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