]> Shamusworld >> Repos - architektonas/blob - src/base/entity.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / base / entity.cpp
1 // entity.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/28/2010  Added this text. :-)
15 //
16
17 #include "entity.h"
18
19 #include <iostream>
20 #include "arc.h"
21 #include "circle.h"
22 #include "debug.h"
23 #include "document.h"
24 #include "ellipse.h"
25 #include "drawing.h"
26 #include "graphicview.h"
27 #include "insert.h"
28 #include "layer.h"
29 #include "line.h"
30 #include "point.h"
31 #include "polyline.h"
32 #include "text.h"
33 #include "units.h"
34
35 /**
36  * Default constructor.
37  * @param parent The parent entity of this entity.
38  *               E.g. a line might have a graphic entity or
39  *               a polyline entity as parent.
40  */
41 Entity::Entity(EntityContainer * parent)
42 {
43         this->parent = parent;
44         init();
45 }
46
47 /**
48  * Copy constructor.
49  */
50 /*Entity::Entity(const Entity& e) : Flags(e.getFlags()) {
51         cout << "copy constructor called\n";
52         init();
53         parent = e.parent;
54         layer = e.layer;
55         //setFlag(e.getFlags());
56     minV = e.minV;
57     maxV = e.maxV;
58     pen = e.pen;
59 }*/
60
61 /**
62  * Destructor.
63  */
64 Entity::~Entity()
65 {
66 }
67
68 /*virtual*/ void Entity::reparent(EntityContainer * parent)
69 {
70         this->parent = parent;
71 }
72
73 /**
74  * Initialisation. Called from all constructors.
75  */
76 void Entity::init()
77 {
78         resetBorders();
79
80         setFlag(RS2::FlagVisible);
81         //layer = NULL;
82         //pen = Pen();
83         updateEnabled = true;
84         setLayerToActive();
85         setPenToActive();
86         initId();
87 }
88
89 /**
90  * Gives this entity a new unique id.
91  */
92 void Entity::initId()
93 {
94         static unsigned long int idCounter = 0;
95         id = idCounter++;
96 }
97
98 /**
99  * Resets the borders of this element.
100  */
101 void Entity::resetBorders()
102 {
103         // TODO: Check that. windoze XP crashes with MAXDOUBLE
104         double maxd = RS_MAXDOUBLE;
105         double mind = RS_MINDOUBLE;
106
107         minV.set(maxd, maxd, maxd);
108         maxV.set(mind, mind, mind);
109 }
110
111 /**
112  * Must be overwritten to return the rtti of this entity
113  * (e.g. RS2::EntityArc).
114  */
115 /*virtual*/ RS2::EntityType Entity::rtti() const
116 {
117         return RS2::EntityUnknown;
118 }
119
120 /**
121  * Identify all entities as undoable entities.
122  * @return RS2::UndoableEntity
123  */
124 /*virtual*/ RS2::UndoableType Entity::undoRtti()
125 {
126         return RS2::UndoableEntity;
127 }
128
129 /**
130  * @return Unique Id of this entity.
131  */
132 unsigned long int Entity::getId() const
133 {
134         return id;
135 }
136
137 /**
138  * Must be overwritten to return true if an entity type
139  * is a potential edge entity of a contour. By default
140  * this returns false.
141  */
142 /*virtual*/ bool Entity::isEdge() const
143 {
144         return false;
145 }
146
147 /**
148  * @return true for all document entities (e.g. Graphics or Blocks).
149  * false otherwise.
150  */
151 /*virtual*/ bool Entity::isDocument() const
152 {
153         return false;
154 }
155
156 /**
157  * Selects or deselects this entity.
158  *
159  * @param select True to select, false to deselect.
160  */
161 bool Entity::setSelected(bool select)
162 {
163         // layer is locked:
164         if (select && isLocked())
165                 return false;
166
167         if (select)
168                 setFlag(RS2::FlagSelected);
169         else
170                 delFlag(RS2::FlagSelected);
171
172         return true;
173 }
174
175 /**
176  * Toggles select on this entity.
177  */
178 bool Entity::toggleSelected()
179 {
180         return setSelected(!isSelected());
181         //toggleFlag(RS2::FlagSelected);
182 }
183
184 /**
185  * @return True if the entity is selected. Note that an entity might
186  * not be selected but one of its parents is selected. In that case
187  * this function returns false.
188  */
189 bool Entity::isSelected() const
190 {
191         return getFlag(RS2::FlagSelected);
192 }
193
194 /**
195  * @return true if a parent entity of this entity is selected.
196  */
197 bool Entity::isParentSelected()
198 {
199         Entity * p = this;
200
201         do
202         {
203                 p = p->getParent();
204
205                 if (p && p->isSelected() == true)
206                         return true;
207         }
208         while (p);
209
210         return false;
211 }
212
213 /**
214  * Sets or resets the processed flag of this entity.
215  *
216  * @param on True to set, false to reset.
217  */
218 void Entity::setProcessed(bool on)
219 {
220         if (on)
221                 setFlag(RS2::FlagProcessed);
222         else
223                 delFlag(RS2::FlagProcessed);
224 }
225
226 /**
227  * @return True if the processed flag is set.
228  */
229 bool Entity::isProcessed() const
230 {
231         return getFlag(RS2::FlagProcessed);
232 }
233
234 /**
235  * Called when the undo state changed.
236  *
237  * @param undone true: entity has become invisible.
238  *               false: entity has become visible.
239  */
240 void Entity::undoStateChanged(bool /*undone*/)
241 {
242         setSelected(false);
243         update();
244 }
245
246 /**
247  * @return true if this entity or any parent entities are undone.
248  */
249 bool Entity::isUndone() const
250 {
251         if (parent == NULL)
252                 return Undoable::isUndone();
253
254         return Undoable::isUndone() || parent->isUndone();
255 }
256
257 /**
258  * @return True if the entity is in the given range.
259  */
260 bool Entity::isInWindow(Vector v1, Vector v2)
261 {
262         double right, left, top, bottom;
263
264         right = std::max(v1.x, v2.x);
265         left = std::min(v1.x, v2.x);
266         top = std::max(v1.y, v2.y);
267         bottom = std::min(v1.y, v2.y);
268
269         return (getMin().x >= left && getMax().x <= right
270                 && getMin().y >= bottom && getMax().y <= top);
271 }
272
273 /**
274  * @param tolerance Tolerance.
275  *
276  * @retval true if the given point is on this entity.
277  * @retval false otherwise
278  */
279 bool Entity::isPointOnEntity(const Vector & coord, double tolerance)
280 {
281         double dist = getDistanceToPoint(coord, NULL, RS2::ResolveNone);
282         return (dist <= tolerance);
283 }
284
285 /*virtual*/ bool Entity::hasEndpointsWithinWindow(Vector /*v1*/, Vector /*v2*/)
286 {
287         return false;
288 }
289
290 /**
291  * Is this entity visible?
292  *
293  * @return true Only if the entity and the layer it is on are visible.
294  * The Layer might also be NULL. In that case the layer visiblity
295 * is ignored.
296  */
297 /*virtual*/ bool Entity::isVisible()
298 {
299         if (!getFlag(RS2::FlagVisible))
300                 return false;
301
302         if (isUndone())
303                 return false;
304
305         /*EntityCotnainer* parent = getParent();
306         if (parent!=NULL && parent->isUndone()) {
307                 return false;
308         }*/
309
310         if (getLayer() == NULL)
311                 return true;
312
313         // inserts are usually visible - the entities in them have their own
314         //   layers which might be frozen
315         // upd: i'm not sure if that is the best behaviour
316         //if (rtti()==RS2::EntityInsert) {
317         //      return true;
318         //}
319
320         if (layer != NULL /*&& layer->getName()!="ByBlock"*/)
321         {
322                 if (!layer->isFrozen())
323                         return true;
324                 else
325                         return false;
326         }
327
328         if (layer == NULL /*&& getLayer()->getName()!="ByBlock"*/)
329         {
330                 if (getLayer() == NULL)
331                         return true;
332                 else
333                 {
334                         if (!getLayer()->isFrozen())
335                                 return true;
336                         else
337                                 return false;
338                 }
339         }
340
341         if (getBlockOrInsert() == NULL)
342                 return true;
343
344         if (getBlockOrInsert()->rtti() == RS2::EntityBlock)
345         {
346                 if (getLayer(false) == NULL || !getLayer(false)->isFrozen())
347                         return true;
348                 else
349                         return false;
350         }
351
352
353         if (getBlockOrInsert()->getLayer() == NULL)
354                 return true;
355
356         if (!getBlockOrInsert()->getLayer()->isFrozen())
357                 return true;
358
359         return false;
360 }
361
362 /*virtual*/ void Entity::setVisible(bool v)
363 {
364         if (v)
365                 setFlag(RS2::FlagVisible);
366         else
367                 delFlag(RS2::FlagVisible);
368 }
369
370 /**
371  * Sets the highlight status of the entity. Highlighted entities
372  * usually indicate a feedback to a user action.
373  */
374 void Entity::setHighlighted(bool on)
375 {
376         if (on)
377                 setFlag(RS2::FlagHighlighted);
378         else
379                 delFlag(RS2::FlagHighlighted);
380 }
381
382 /**
383  * @return true if the entity is highlighted.
384  */
385 bool Entity::isHighlighted()
386 {
387         return getFlag(RS2::FlagHighlighted);
388 }
389
390 /**
391  * @return true if the layer this entity is on is locked.
392  */
393 bool Entity::isLocked()
394 {
395         if (getLayer(true) != NULL && getLayer()->isLocked())
396                 return true;
397
398         return false;
399 }
400
401 /**
402  * Implementations must return the total length of the entity
403  * or a negative number if the entity has no length (e.g. a text or hatch).
404  */
405 /*virtual*/ double Entity::getLength()
406 {
407         return -1.0;
408 }
409
410 /**
411  * @return Parent of this entity or NULL if this is a root entity.
412  */
413 EntityContainer * Entity::getParent() const
414 {
415         return parent;
416 }
417
418 /**
419  * Reparents this entity.
420  */
421 void Entity::setParent(EntityContainer * p)
422 {
423         parent = p;
424 }
425
426 /**
427  * @return The parent graphic in which this entity is stored
428  * or the parent's parent graphic or NULL if none of the parents
429  * are stored in a graphic.
430  */
431 Drawing * Entity::getGraphic()
432 {
433         if (rtti() == RS2::EntityGraphic)
434                 return (Drawing *)this;
435         else if (parent == NULL)
436                 return NULL;
437         else
438                 return parent->getGraphic();
439 }
440
441 /**
442  * @return The parent block in which this entity is stored
443  * or the parent's parent block or NULL if none of the parents
444  * are stored in a block.
445  */
446 Block * Entity::getBlock()
447 {
448         if (rtti() == RS2::EntityBlock)
449                 return (Block *)this;
450         else if (parent == NULL)
451                 return NULL;
452         else
453                 return parent->getBlock();
454 }
455
456 /**
457  * @return The parent insert in which this entity is stored
458  * or the parent's parent block or NULL if none of the parents
459  * are stored in a block.
460  */
461 Insert * Entity::getInsert()
462 {
463         if (rtti() == RS2::EntityInsert)
464                 return (Insert *)this;
465         else if (parent == NULL)
466                 return NULL;
467         else
468                 return parent->getInsert();
469 }
470
471 /**
472  * @return The parent block or insert in which this entity is stored
473  * or the parent's parent block or insert or NULL if none of the parents
474  * are stored in a block or insert.
475  */
476 Entity * Entity::getBlockOrInsert()
477 {
478         if (rtti() == RS2::EntityBlock || rtti() == RS2::EntityInsert)
479                 return this;
480         else if (parent == NULL)
481                 return NULL;
482         else
483                 return parent->getBlockOrInsert();
484 }
485
486 /**
487  * @return The parent document in which this entity is stored
488  * or the parent's parent document or NULL if none of the parents
489  * are stored in a document. Note that a document is usually
490  * either a Graphic or a Block.
491  */
492 Document * Entity::getDocument()
493 {
494         if (isDocument() == true)
495                 return (Document *)this;
496         else if (parent == NULL)
497                 return NULL;
498         else
499                 return parent->getDocument();
500 }
501
502 /**
503  * Can be implemented by child classes to update the entities
504  * temporary subentities. update() is called if the entity's
505  * paramters or undo state changed.
506  */
507 /*virtual*/ void Entity::update()
508 {
509 }
510
511 /*virtual*/ void Entity::setUpdateEnabled(bool on)
512 {
513         updateEnabled = on;
514 }
515
516 /**
517  * This method doesn't do any calculations.
518  * @return minimum coordinate of the entity.
519  * @see calculateBorders()
520  */
521 Vector Entity::getMin() const
522 {
523         return minV;
524 }
525
526 /**
527  * This method doesn't do any calculations.
528  * @return minimum coordinate of the entity.
529  * @see calculateBorders()
530  */
531 Vector Entity::getMax() const
532 {
533         return maxV;
534 }
535
536 /**
537  * This method returns the difference of max and min returned
538  * by the above functions.
539  * @return size of the entity.
540  * @see calculateBorders()
541  * @see getMin()
542  * @see getMax()
543  */
544 Vector Entity::getSize() const
545 {
546         return maxV - minV;
547 }
548
549 /**
550  * Sets a variable value for the parent graphic object.
551  *
552  * @param key Variable name (e.g. "$DIMASZ")
553  * @param val Default value
554  */
555 void Entity::addGraphicVariable(const QString & key, double val, int code)
556 {
557         Drawing * graphic = getGraphic();
558
559         if (graphic != NULL)
560                 graphic->addVariable(key, val, code);
561 }
562
563 /**
564  * Sets a variable value for the parent graphic object.
565  *
566  * @param key Variable name (e.g. "$DIMASZ")
567  * @param val Default value
568  */
569 void Entity::addGraphicVariable(const QString & key, int val, int code)
570 {
571         Drawing * graphic = getGraphic();
572
573         if (graphic != NULL)
574                 graphic->addVariable(key, val, code);
575 }
576
577 /**
578  * Sets a variable value for the parent graphic object.
579  *
580  * @param key Variable name (e.g. "$DIMASZ")
581  * @param val Default value
582  */
583 void Entity::addGraphicVariable(const QString & key, const QString & val, int code)
584 {
585         Drawing * graphic = getGraphic();
586
587         if (graphic != NULL)
588                 graphic->addVariable(key, val, code);
589 }
590
591 /**
592  * A safe member function to return the given variable.
593  *
594  * @param key Variable name (e.g. "$DIMASZ")
595  * @param def Default value
596  *
597  * @return value of variable or default value if the given variable
598  *    doesn't exist.
599  */
600 double Entity::getGraphicVariableDouble(const QString & key, double def)
601 {
602         Drawing * graphic = getGraphic();
603         double ret = def;
604
605         if (graphic != NULL)
606                 ret = graphic->getVariableDouble(key, def);
607
608         return ret;
609 }
610
611 /**
612  * A safe member function to return the given variable.
613  *
614  * @param key Variable name (e.g. "$DIMASZ")
615  * @param def Default value
616  *
617  * @return value of variable or default value if the given variable
618  *    doesn't exist.
619  */
620 int Entity::getGraphicVariableInt(const QString & key, int def)
621 {
622         Drawing * graphic = getGraphic();
623         int ret = def;
624
625         if (graphic != NULL)
626                 ret = graphic->getVariableInt(key, def);
627
628         return ret;
629 }
630
631 /**
632  * A safe member function to return the given variable.
633  *
634  * @param key Variable name (e.g. "$DIMASZ")
635  * @param def Default value
636  *
637  * @return value of variable or default value if the given variable
638  *    doesn't exist.
639  */
640 QString Entity::getGraphicVariableString(const QString & key, const QString & def)
641 {
642         Drawing * graphic = getGraphic();
643         QString ret = def;
644
645         if (graphic != NULL)
646                 ret = graphic->getVariableString(key, def);
647
648         return ret;
649 }
650
651 /**
652  * @return The unit the parent graphic works on or None if there's no
653  * parent graphic.
654  */
655 RS2::Unit Entity::getGraphicUnit()
656 {
657         Drawing * graphic = getGraphic();
658         RS2::Unit ret = RS2::None;
659
660         if (graphic != NULL)
661                 ret = graphic->getUnit();
662
663         return ret;
664 }
665
666 /**
667  * Must be overwritten to get all reference points of the entity.
668  */
669 /*virtual*/ VectorSolutions Entity::getRefPoints()
670 {
671         VectorSolutions ret;
672         return ret;
673 }
674
675 /**
676  * Must be overwritten to get the point with a given
677  * distance to the start- or endpoint to the given coordinate for this entity.
678  *
679  * @param distance Distance to endpoint.
680  * @param startp true = measured from Startpoint, false = measured from Endpoint
681  *
682  * @return The point with the given distance to the start- or endpoint.
683  */
684 /*virtual*/ Vector Entity::getNearestDist(double /*distance*/, bool /*startp*/)
685 {
686         return Vector(false);
687 }
688
689 /**
690  * Must be overwritten to get the nearest reference point for this entity.
691  *
692  * @param coord Coordinate (typically a mouse coordinate)
693  * @param dist Pointer to a value which will contain the measured
694  * distance between 'coord' and the closest point. The passed
695  * pointer can also be NULL in which case the distance will be
696  * lost.
697  *
698  * @return The closest point with the given distance to the endpoint.
699  */
700 /*virtual*/ Vector Entity::getNearestRef(const Vector & coord, double * dist/*= NULL*/)
701 {
702         VectorSolutions s = getRefPoints();
703
704         return s.getClosest(coord, dist);
705 }
706
707 /**
708  * Gets the nearest reference point of this entity if it is selected.
709  * Containers re-implement this method to return the nearest reference
710  * point of a selected sub entity.
711  *
712  * @param coord Coordinate (typically a mouse coordinate)
713  * @param dist Pointer to a value which will contain the measured
714  * distance between 'coord' and the closest point. The passed
715  * pointer can also be NULL in which case the distance will be
716  * lost.
717  *
718  * @return The closest point with the given distance to the endpoint.
719  */
720 /*virtual*/ Vector Entity::getNearestSelectedRef(const Vector & coord, double * dist/*= NULL*/)
721 {
722         if (isSelected())
723                 return getNearestRef(coord, dist);
724
725         return Vector(false);
726 }
727
728 /**
729  * Acts like scale(Vector) but with equal factors.
730  * Equal to scale(center, Vector(factor, factor)).
731  */
732 /*virtual*/ void Entity::scale(Vector center, double factor)
733 {
734         scale(center, Vector(factor, factor));
735 }
736
737 /**
738  * Implementations must drag the reference point(s) of all
739  * (sub-)entities that are very close to ref by offset.
740  */
741 /*virtual*/ void Entity::moveRef(const Vector &/*ref*/, const Vector &/*offset*/)
742 {
743         return;
744 }
745
746 /**
747  * Implementations must drag the reference point(s) of selected
748  * (sub-)entities that are very close to ref by offset.
749  */
750 /*virtual*/ void Entity::moveSelectedRef(const Vector &/*ref*/, const Vector &/*offset*/)
751 {
752         return;
753 }
754
755 /**
756  * Returns a pointer to the layer this entity is on or NULL.
757  *
758  * @para resolve true: if the layer is ByBlock, the layer of the
759  *               block this entity is in is returned.
760  *               false: the layer of the entity is returned.
761  *
762  * @return pointer to the layer this entity is on. If the layer
763  * is set to NULL the layer of the next parent that is not on
764  * layer NULL is returned. If all parents are on layer NULL, NULL
765  * is returned.
766  */
767 Layer * Entity::getLayer(bool resolve) const
768 {
769         if (resolve)
770         {
771                 // we have no layer but a parent that might have one.
772                 // return parent's layer instead:
773                 if (layer == NULL /*|| layer->getName()=="ByBlock"*/)
774                 {
775                         if (parent != NULL)
776                                 return parent->getLayer(true);
777                         else
778                                 return NULL;
779                 }
780         }
781
782         // return our layer. might still be NULL:
783         return layer;
784 }
785
786 /**
787  * Sets the layer of this entity to the layer with the given name
788  */
789 void Entity::setLayer(const QString & name)
790 {
791         Drawing * graphic = getGraphic();
792
793         if (graphic != NULL)
794                 layer = graphic->findLayer(name);
795         else
796                 layer = NULL;
797 }
798
799 /**
800  * Sets the layer of this entity to the layer given.
801  */
802 void Entity::setLayer(Layer * l)
803 {
804     layer = l;
805 }
806
807 /**
808  * Sets the layer of this entity to the current layer of
809  * the graphic this entity is in. If this entity (and none
810  * of its parents) are in a graphic the layer is set to NULL.
811  */
812 void Entity::setLayerToActive()
813 {
814         Drawing * graphic = getGraphic();
815
816         if (graphic != NULL)
817                 layer = graphic->getActiveLayer();
818         else
819                 layer = NULL;
820 }
821
822 /**
823  * Gets the pen needed to draw this entity.
824  * The attributes can also come from the layer this entity is on
825  * if the flags are set accordingly.
826  *
827  * @param resolve true: Resolve the pen to a drawable pen (e.g. the pen
828  *         from the layer or parent..)
829  *         false: Don't resolve and return a pen or ByLayer, ByBlock, ...
830  *
831  * @return Pen for this entity.
832  */
833 Pen Entity::getPen(bool resolve) const
834 {
835         if (!resolve)
836                 return pen;
837         else
838         {
839                 Pen p = pen;
840                 Layer * l = getLayer(true);
841
842                 // use parental attributes (e.g. vertex of a polyline, block
843                 // entities when they are drawn in block documents):
844                 if (!p.isValid() || p.getColor().isByBlock())
845                 {
846                         if (parent != NULL)
847                                 p = parent->getPen();
848                 }
849                 // use layer attributes:
850                 else if (l != NULL)
851                 {
852                         // layer is "ByBlock":
853                         /*if (layer->getName()=="ByBlock" && getBlockOrInsert()!=NULL) {
854                                 p = getBlockOrInsert()->getPen();
855                 } else {*/
856
857                         // use layer's color:
858                         if (p.getColor().isByLayer())
859                                 p.setColor(l->getPen().getColor());
860
861                         // use layer's width:
862                         if (p.getWidth() == RS2::WidthByLayer)
863                                 p.setWidth(l->getPen().getWidth());
864
865                         // use layer's linetype:
866                         if (p.getLineType() == RS2::LineByLayer)
867                                 p.setLineType(l->getPen().getLineType());
868                         //}
869                 }
870
871                 return p;
872         }
873 }
874
875 /**
876  * Sets the explicit pen for this entity or a pen with special
877  * attributes such as BY_LAYER, ..
878  */
879 void Entity::setPen(const Pen & pen)
880 {
881         this->pen = pen;
882 }
883
884 /**
885  * Sets the pen of this entity to the current pen of
886  * the graphic this entity is in. If this entity (and none
887  * of its parents) are in a graphic the pen is not changed.
888  */
889 void Entity::setPenToActive()
890 {
891         Document * doc = getDocument();
892
893         if (doc != NULL)
894                 pen = doc->getActivePen();
895         else
896         {
897                 //DEBUG->print(Debug::D_WARNING, "Entity::setPenToActive(): "
898                 //                "No document / active pen linked to this entity.");
899         }
900         //else {
901         //   pen = Pen();
902         //}
903 }
904
905 /**
906  * Implementations must stretch the given range of the entity
907  * by the given offset. This default implementation moves the
908  * whole entity if it is completely inside the given range.
909  */
910 void Entity::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
911 {
912         //e->calculateBorders();
913         if (getMin().isInWindow(firstCorner, secondCorner)
914                 && getMax().isInWindow(firstCorner, secondCorner))
915                 move(offset);
916 }
917
918 /**
919  * @return Factor for scaling the line styles considering the current
920  * paper scaling and the fact that styles are stored in Millimeter.
921  */
922 double Entity::getStyleFactor(GraphicView * view)
923 {
924         double styleFactor = 1.0;
925
926         if (view != NULL)
927         {
928                 if (view->isPrinting() == false && view->isDraftMode())
929                         styleFactor = 1.0 / view->getFactor().x;
930                 else
931                 {
932                         //styleFactor = getStyleFactor();
933                         // the factor caused by the unit:
934                         RS2::Unit unit = RS2::None;
935                         Drawing * g = getGraphic();
936
937                         if (g != NULL)
938                         {
939                                 unit = g->getUnit();
940                                 //double scale = g->getPaperScale();
941                                 styleFactor = Units::convert(1.0, RS2::Millimeter, unit);
942                                 // / scale;
943                         }
944
945                         // the factor caused by the line width:
946                         if (((int)getPen(true).getWidth()) > 0)
947                                 styleFactor *= ((double)getPen(true).getWidth() / 100.0);
948                         else if (((int)getPen(true).getWidth()) == 0)
949                                 styleFactor *= 0.01;
950                 }
951
952                 if (view->isPrinting() || view->isPrintPreview() || view->isDraftMode() == false)
953                 {
954                         Drawing * graphic = getGraphic();
955
956                         if (graphic != NULL && graphic->getPaperScale() > 1.0e-6)
957                                 styleFactor /= graphic->getPaperScale();
958                 }
959         }
960
961         //DEBUG->print("stylefactor: %f", styleFactor);
962         //DEBUG->print("viewfactor: %f", view->getFactor().x);
963
964         if (styleFactor * view->getFactor().x < 0.2)
965                 styleFactor = -1.0;
966
967         return styleFactor;
968 }
969
970 /**
971  * @return User defined variable connected to this entity.
972  */
973 QString * Entity::getUserDefVar(QString key)
974 {
975 //      return (this->varList.find(key));
976         return (this->varList.value(key));
977 }
978
979 /**
980  * Add a user defined variable to this entity.
981  */
982 void Entity::setUserDefVar(QString key, QString val)
983 {
984         varList.insert(key, new QString(val));
985 }
986
987 /**
988  * Deletes the given user defined variable.
989  */
990 void Entity::delUserDefVar(QString key)
991 {
992         varList.remove(key);
993 }
994
995 /**
996  * @return A list of all keys connected to this entity.
997  */
998 QStringList Entity::getAllKeys()
999 {
1000         QStringList keys;
1001 //      Q3DictIterator<QString> it(varList);
1002         QHashIterator<QString, QString *> it(varList);
1003
1004 //      for(; it.current(); ++it)
1005 //              keys.append(it.currentKey());
1006         while (it.hasNext())
1007         {
1008                 it.next();
1009                 keys.append(it.key());
1010         }
1011
1012         return keys;
1013 }
1014
1015 /**
1016  * Dumps the elements data to stdout.
1017  */
1018 std::ostream & operator<<(std::ostream & os, Entity & e)
1019 {
1020         //os << "Warning: Virtual entity!\n";
1021         //return os;
1022
1023         os << " {Entity id: " << e.id;
1024
1025         if (e.parent !=  NULL)
1026                 os << " | parent id: " << e.parent->getId() << "\n";
1027         else
1028                 os << " | no parent\n";
1029
1030         os << " flags: " << (e.getFlag(RS2::FlagVisible) ? "RS2::FlagVisible" : "");
1031         os << (e.getFlag(RS2::FlagUndone) ? " RS2::FlagUndone" : "");
1032         os << (e.getFlag(RS2::FlagSelected) ? " RS2::FlagSelected" : "");
1033         os << "\n";
1034
1035         if (e.layer == NULL)
1036                 os << " layer: NULL ";
1037         else
1038                 os << " layer: " << e.layer->getName().toLatin1().data() << " "
1039                         << " layer address: " << (int)(e.layer) << " ";
1040
1041         os << e.pen << "\n";
1042
1043         os << "variable list:\n";
1044 //      Q3DictIterator<QString> it(e.varList); // See QDictIterator
1045         QHashIterator<QString, QString *> it(e.varList);
1046
1047 #if 0
1048         for( ; it.current(); ++it )
1049         {
1050 #warning "Removed output (Qt3 style iterator)... !!! FIX !!!"
1051 //        os << it.currentKey() << ": " << *it.current() << ", ";
1052         }
1053 #else
1054         while (it.hasNext())
1055         {
1056                 it.next();
1057                 os << (it.key()).toAscii().data() << ": " << (*it.value()).toAscii().data() << ", ";
1058         }
1059 #endif
1060
1061         // There should be a better way than this...
1062         switch (e.rtti())
1063         {
1064         case RS2::EntityPoint:
1065                 os << (Point &)e;
1066                 break;
1067
1068         case RS2::EntityLine:
1069                 os << (Line &)e;
1070                 break;
1071
1072         case RS2::EntityPolyline:
1073                 os << (Polyline &)e;
1074                 break;
1075
1076         case RS2::EntityArc:
1077                 os << (Arc &)e;
1078                 break;
1079
1080         case RS2::EntityCircle:
1081                 os << (Circle &)e;
1082                 break;
1083
1084         case RS2::EntityEllipse:
1085                 os << (Ellipse &)e;
1086                 break;
1087
1088         case RS2::EntityInsert:
1089                 os << (Insert &)e;
1090                 break;
1091
1092         case RS2::EntityText:
1093                 os << (Text &)e;
1094                 break;
1095
1096         default:
1097                 os << "Unknown Entity";
1098                 break;
1099         }
1100
1101         os << "}\n\n";
1102
1103         return os;
1104 }