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
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
19 #include "constructionline.h"
21 #include "graphicview.h"
23 #include "information.h"
25 #include "modification.h"
29 * Default constructor.
31 * @param container The container to which we will add
32 * entities. Usually that's an Drawing entity but
33 * it can also be a polyline, text, ...
35 Creation::Creation(EntityContainer * container, GraphicView * graphicView,
38 this->container = container;
39 this->graphicView = graphicView;
40 this->handleUndo = handleUndo;
42 if (container != NULL)
44 graphic = container->getGraphic();
45 document = container->getDocument();
55 * Creates a point entity.
59 * creation.createPoint(Vector(10.0, 15.0));
64 /*void Creation::createPoint(const Vector& p) {
65 entityContainer->addEntity(new Point(entityContainer, p));
69 * Creates a line with two points given.
73 * creation.createLine2P(Vector(10.0, 10.0), Vector(100.0, 200.0));
76 * @param p1 start point
79 /*void Creation::createLine2P(const Vector& p1, const Vector& p2) {
80 entityContainer->addEntity(new Line(entityContainer,
85 * Creates a rectangle with two edge points given.
89 * creation.createRectangle(Vector(5.0, 2.0), Vector(7.5, 3.0));
95 /*void Creation::createRectangle(const Vector& e1, const Vector& e2) {
96 Vector e21(e2.x, e1.y);
97 Vector e12(e1.x, e2.y);
98 entityContainer->addEntity(new Line(entityContainer,
100 entityContainer->addEntity(new Line(entityContainer,
102 entityContainer->addEntity(new Line(entityContainer,
104 entityContainer->addEntity(new Line(entityContainer,
109 * Creates a polyline from the given array of entities.
110 * No checking if the entities actually fit together.
111 * Currently this is like a group.
115 * Polyline *pl = creation.createPolyline(Vector(25.0, 55.0));<br>
116 * pl->addVertex(Vector(50.0, 75.0));<br>
119 * @param entities array of entities
120 * @param startPoint Start point of the polyline
122 /*Polyline* Creation::createPolyline(const Vector& startPoint) {
123 Polyline* pl = new Polyline(entityContainer,
124 PolylineData(startPoint, Vector(0.0,0.0), 0));
125 entityContainer->addEntity(pl);
130 * Creates an entity parallel to the given entity e through the given
133 * @param coord Coordinate to define the distance / side (typically a
135 * @param number Number of parallels.
136 * @param e Original entity.
138 * @return Pointer to the first created parallel or NULL if no
139 * parallel has been created.
141 Entity * Creation::createParallelThrough(const Vector & coord, int number, Entity * e)
148 if (e->rtti() == RS2::EntityLine)
150 Line * l = (Line *)e;
151 ConstructionLine cl(NULL, ConstructionLineData(l->getStartpoint(),
153 dist = cl.getDistanceToPoint(coord);
157 dist = e->getDistanceToPoint(coord);
160 if (dist < RS_MAXDOUBLE)
161 return createParallel(coord, dist, number, e);
167 * Creates an entity parallel to the given entity e.
168 * Out of the 2 possible parallels, the one closest to
169 * the given coordinate is returned.
170 * Lines, Arcs and Circles can have parallels.
172 * @param coord Coordinate to define which parallel we want (typically a
174 * @param distance Distance of the parallel.
175 * @param number Number of parallels.
176 * @param e Original entity.
178 * @return Pointer to the first created parallel or NULL if no
179 * parallel has been created.
181 Entity* Creation::createParallel(const Vector& coord,
182 double distance, int number,
189 case RS2::EntityLine:
190 return createParallelLine(coord, distance, number, (Line*)e);
194 return createParallelArc(coord, distance, number, (Arc*)e);
197 case RS2::EntityCircle:
198 return createParallelCircle(coord, distance, number, (Circle*)e);
211 * Creates a line parallel to the given line e.
212 * Out of the 2 possible parallels, the one closest to
213 * the given coordinate is returned.
215 * @param coord Coordinate to define which parallel we want (typically a
217 * @param distance Distance of the parallel.
218 * @param number Number of parallels.
219 * @param e Original entity.
221 * @return Pointer to the first created parallel or NULL if no
222 * parallel has been created.
224 Line* Creation::createParallelLine(const Vector& coord,
225 double distance, int number,
232 double ang = e->getAngle1() + M_PI/2.0;
234 LineData parallelData;
237 if (document!=NULL && handleUndo) {
238 document->startUndoCycle();
241 for (int num=1; num<=number; ++num) {
243 // calculate 1st parallel:
244 p1.setPolar(distance*num, ang);
245 p1 += e->getStartpoint();
246 p2.setPolar(distance*num, ang);
247 p2 += e->getEndpoint();
248 Line parallel1(NULL, LineData(p1, p2));
250 // calculate 2nd parallel:
251 p1.setPolar(distance*num, ang+M_PI);
252 p1 += e->getStartpoint();
253 p2.setPolar(distance*num, ang+M_PI);
254 p2 += e->getEndpoint();
255 Line parallel2(NULL, LineData(p1, p2));
257 double dist1 = parallel1.getDistanceToPoint(coord);
258 double dist2 = parallel2.getDistanceToPoint(coord);
259 double minDist = std::min(dist1, dist2);
261 if (minDist<RS_MAXDOUBLE) {
263 parallelData = parallel1.getData();
265 parallelData = parallel2.getData();
269 Line* newLine = new Line(container, parallelData);
270 newLine->setLayerToActive();
271 newLine->setPenToActive();
275 if (container!=NULL) {
276 container->addEntity(newLine);
278 if (document!=NULL && handleUndo) {
279 document->addUndoable(newLine);
280 //document->endUndoCycle();
282 if (graphicView!=NULL) {
283 graphicView->drawEntity(newLine);
288 if (document!=NULL && handleUndo) {
289 document->endUndoCycle();
298 * Creates a arc parallel to the given arc e.
299 * Out of the 2 possible parallels, the one closest to
300 * the given coordinate is returned.
302 * @param coord Coordinate to define which parallel we want (typically a
304 * @param distance Distance of the parallel.
305 * @param number Number of parallels.
306 * @param e Original entity.
308 * @return Pointer to the first created parallel or NULL if no
309 * parallel has been created.
311 Arc* Creation::createParallelArc(const Vector& coord,
312 double distance, int number,
319 ArcData parallelData;
322 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
328 for (int num=1; num<=number; ++num) {
330 // calculate parallel:
332 Arc parallel1(NULL, e->getData());
333 parallel1.setRadius(e->getRadius() + distance*num);
334 if (parallel1.getRadius()<0.0) {
335 parallel1.setRadius(RS_MAXDOUBLE);
339 // calculate 2nd parallel:
340 //Arc parallel2(NULL, e->getData());
341 //parallel2.setRadius(e->getRadius()+distance*num);
343 //double dist1 = parallel1.getDistanceToPoint(coord);
344 //double dist2 = parallel2.getDistanceToPoint(coord);
345 //double minDist = min(dist1, dist2);
347 //if (minDist<RS_MAXDOUBLE) {
350 parallelData = parallel1.getData();
352 // parallelData = parallel2.getData();
355 if (document!=NULL && handleUndo) {
356 document->startUndoCycle();
359 Arc* newArc = new Arc(container, parallelData);
360 newArc->setLayerToActive();
361 newArc->setPenToActive();
365 if (container!=NULL) {
366 container->addEntity(newArc);
368 if (document!=NULL && handleUndo) {
369 document->addUndoable(newArc);
370 document->endUndoCycle();
372 if (graphicView!=NULL) {
373 graphicView->drawEntity(newArc);
384 * Creates a circle parallel to the given circle e.
385 * Out of the 2 possible parallels, the one closest to
386 * the given coordinate is returned.
388 * @param coord Coordinate to define which parallel we want (typically a
390 * @param distance Distance of the parallel.
391 * @param number Number of parallels.
392 * @param e Original entity.
394 * @return Pointer to the first created parallel or NULL if no
395 * parallel has been created.
397 Circle* Creation::createParallelCircle(const Vector& coord,
398 double distance, int number,
405 CircleData parallelData;
408 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
414 for (int num=1; num<=number; ++num) {
416 // calculate parallel:
418 Circle parallel1(NULL, e->getData());
419 parallel1.setRadius(e->getRadius() + distance*num);
420 if (parallel1.getRadius()<0.0) {
421 parallel1.setRadius(RS_MAXDOUBLE);
425 // calculate 2nd parallel:
426 //Circle parallel2(NULL, e->getData());
427 //parallel2.setRadius(e->getRadius()+distance*num);
429 //double dist1 = parallel1.getDistanceToPoint(coord);
430 //double dist2 = parallel2.getDistanceToPoint(coord);
431 //double minDist = min(dist1, dist2);
433 //if (minDist<RS_MAXDOUBLE) {
436 parallelData = parallel1.getData();
438 // parallelData = parallel2.getData();
441 if (document!=NULL && handleUndo) {
442 document->startUndoCycle();
445 Circle* newCircle = new Circle(container, parallelData);
446 newCircle->setLayerToActive();
447 newCircle->setPenToActive();
451 if (container!=NULL) {
452 container->addEntity(newCircle);
454 if (document!=NULL && handleUndo) {
455 document->addUndoable(newCircle);
456 document->endUndoCycle();
458 if (graphicView!=NULL) {
459 graphicView->drawEntity(newCircle);
469 * Creates a bisecting line of the angle between the entities
470 * e1 and e2. Out of the 4 possible bisectors, the one closest to
471 * the given coordinate is returned.
473 * @param coord Coordinate to define which bisector we want (typically a
475 * @param length Length of the bisecting line.
476 * @param num Number of bisectors
477 * @param l1 First line.
478 * @param l2 Second line.
480 * @return Pointer to the first bisector created or NULL if no bisectors
483 Line * Creation::createBisector(const Vector & coord1, const Vector & coord2,
484 double length, int num, Line * l1, Line * l2)
486 // check given entities:
487 if (!l1 || !l2 || l1->rtti() != RS2::EntityLine || l2->rtti() != RS2::EntityLine)
490 // intersection between entities:
491 VectorSolutions sol = Information::getIntersection(l1, l2, false);
492 Vector inters = sol.get(0);
497 double angle1 = inters.angleTo(l1->getNearestPointOnEntity(coord1));
498 double angle2 = inters.angleTo(l2->getNearestPointOnEntity(coord2));
499 double angleDiff = Math::getAngleDifference(angle1, angle2);
501 if (angleDiff > M_PI)
502 angleDiff = angleDiff - 2 * M_PI;
506 if (document && handleUndo)
507 document->startUndoCycle();
509 for(int n=1; n<=num; n++)
511 double angle = angle1 + (angleDiff / (num + 1) * n);
513 v.setPolar(length, angle);
514 LineData d = LineData(inters, inters + v);
515 Line * newLine = new Line(container, d);
519 newLine->setLayerToActive();
520 newLine->setPenToActive();
521 container->addEntity(newLine);
524 if (document && handleUndo)
525 document->addUndoable(newLine);
528 graphicView->drawEntity(newLine);
534 if (document && handleUndo)
535 document->endUndoCycle();
543 * Creates a tangent between a given point and a circle or arc.
544 * Out of the 2 possible tangents, the one closest to
545 * the given coordinate is returned.
547 * @param coord Coordinate to define which tangent we want (typically a
549 * @param point Point.
550 * @param circle Circle, arc or ellipse entity.
552 Line* Creation::createTangent1(const Vector& coord,
558 // check given entities:
559 if (circle==NULL || !point.valid ||
560 (circle->rtti()!=RS2::EntityArc && circle->rtti()!=RS2::EntityCircle
561 && circle->rtti()!=RS2::EntityEllipse)) {
566 if (circle->rtti()==RS2::EntityCircle) {
567 circleCenter = ((Circle*)circle)->getCenter();
568 } else if (circle->rtti()==RS2::EntityArc) {
569 circleCenter = ((Arc*)circle)->getCenter();
570 } else if (circle->rtti()==RS2::EntityEllipse) {
571 circleCenter = ((Ellipse*)circle)->getCenter();
574 // the two tangent points:
577 // calculate tangent points for arcs / circles:
578 if (circle->rtti()!=RS2::EntityEllipse) {
579 // create temp. thales circle:
580 Vector tCenter = (point + circleCenter)/2.0;
581 double tRadius = point.distanceTo(tCenter);
583 Circle tmp(NULL, CircleData(tCenter, tRadius));
585 // get the two intersection points which are the tangent points:
586 sol = Information::getIntersection(&tmp, circle, false);
589 // calculate tangent points for ellipses:
591 Ellipse* el = (Ellipse*)circle;
593 //sol.set(0, circleCenter);
594 //sol.set(1, circleCenter);
597 double a = el->getMajorRadius(); // the length of the major axis / 2
598 double b = el->getMinorRadius(); // the length of the minor axis / 2
600 // rotate and move point:
601 Vector point2 = point;
602 point2.move(-el->getCenter());
603 point2.rotate(-el->getAngle());
605 double xp = point2.x; // coordinates of the given point
606 double yp = point2.y;
608 double xt1; // Tangent point 1
610 double xt2; // Tangent point 2
615 double d = a2 / b2 * yp / xp;
617 double af = b2 * d * d + a2;
618 double bf = -b2 * d * e * 2.0;
619 double cf = b2 * e * e - a2 * b2;
620 double t = sqrt(bf * bf - af * cf * 4.0);
621 yt1 = (t - bf) / (af * 2.0);
623 yt2 = (-t - bf) / (af * 2.0);
626 Vector s1 = Vector(xt1, yt1);
627 Vector s2 = Vector(xt2, yt2);
629 s1.rotate(el->getAngle());
630 s1.move(el->getCenter());
632 s2.rotate(el->getAngle());
633 s2.move(el->getCenter());
641 if (!sol.get(0).valid || !sol.get(1).valid) {
645 // create all possible tangents:
650 d = LineData(sol.get(0), point);
651 poss[0] = new Line(NULL, d);
652 d = LineData(sol.get(1), point);
653 poss[1] = new Line(NULL, d);
655 // find closest tangent:
656 double minDist = RS_MAXDOUBLE;
659 for (int i=0; i<2; ++i) {
660 dist = poss[i]->getDistanceToPoint(coord);
667 // create the closest tangent:
669 LineData d = poss[idx]->getData();
671 for (int i=0; i<2; ++i) {
675 if (document!=NULL && handleUndo) {
676 document->startUndoCycle();
679 ret = new Line(container, d);
680 ret->setLayerToActive();
681 ret->setPenToActive();
682 if (container!=NULL) {
683 container->addEntity(ret);
685 if (document!=NULL && handleUndo) {
686 document->addUndoable(ret);
687 document->endUndoCycle();
689 if (graphicView!=NULL) {
690 graphicView->drawEntity(ret);
702 * Creates a tangent between two circles or arcs.
703 * Out of the 4 possible tangents, the one closest to
704 * the given coordinate is returned.
706 * @param coord Coordinate to define which tangent we want (typically a
708 * @param circle1 1st circle or arc entity.
709 * @param circle2 2nd circle or arc entity.
711 Line* Creation::createTangent2(const Vector& coord,
715 Vector circleCenter1;
716 Vector circleCenter2;
717 double circleRadius1 = 0.0;
718 double circleRadius2 = 0.0;
720 // check given entities:
721 if (circle1==NULL || circle2==NULL ||
722 (circle1->rtti()!=RS2::EntityArc &&
723 circle1->rtti()!=RS2::EntityCircle) ||
724 (circle2->rtti()!=RS2::EntityArc &&
725 circle2->rtti()!=RS2::EntityCircle) ) {
730 if (circle1->rtti()==RS2::EntityCircle) {
731 circleCenter1 = ((Circle*)circle1)->getCenter();
732 circleRadius1 = ((Circle*)circle1)->getRadius();
733 } else if (circle1->rtti()==RS2::EntityArc) {
734 circleCenter1 = ((Arc*)circle1)->getCenter();
735 circleRadius1 = ((Arc*)circle1)->getRadius();
738 if (circle2->rtti()==RS2::EntityCircle) {
739 circleCenter2 = ((Circle*)circle2)->getCenter();
740 circleRadius2 = ((Circle*)circle2)->getRadius();
741 } else if (circle2->rtti()==RS2::EntityArc) {
742 circleCenter2 = ((Arc*)circle2)->getCenter();
743 circleRadius2 = ((Arc*)circle2)->getRadius();
746 // create all possible tangents:
748 for (int i=0; i<4; ++i) {
754 double angle1 = circleCenter1.angleTo(circleCenter2);
755 double dist1 = circleCenter1.distanceTo(circleCenter2);
759 double dist2 = circleRadius2 - circleRadius1;
761 double angle2 = asin(dist2/dist1);
762 double angt1 = angle1 + angle2 + M_PI/2.0;
763 double angt2 = angle1 - angle2 - M_PI/2.0;
767 offs1.setPolar(circleRadius1, angt1);
768 offs2.setPolar(circleRadius2, angt1);
770 d = LineData(circleCenter1 + offs1,
771 circleCenter2 + offs2);
772 poss[0] = new Line(NULL, d);
775 offs1.setPolar(circleRadius1, angt2);
776 offs2.setPolar(circleRadius2, angt2);
778 d = LineData(circleCenter1 + offs1,
779 circleCenter2 + offs2);
780 poss[1] = new Line(NULL, d);
784 double dist3 = circleRadius2 + circleRadius1;
786 double angle3 = asin(dist3/dist1);
787 double angt3 = angle1 + angle3 + M_PI/2.0;
788 double angt4 = angle1 - angle3 - M_PI/2.0;
792 offs1.setPolar(circleRadius1, angt3);
793 offs2.setPolar(circleRadius2, angt3);
795 d = LineData(circleCenter1 - offs1,
796 circleCenter2 + offs2);
797 poss[2] = new Line(NULL, d);
800 offs1.setPolar(circleRadius1, angt4);
801 offs2.setPolar(circleRadius2, angt4);
803 d = LineData(circleCenter1 - offs1,
804 circleCenter2 + offs2);
805 poss[3] = new Line(NULL, d);
810 // find closest tangent:
811 double minDist = RS_MAXDOUBLE;
814 for (int i=0; i<4; ++i) {
816 dist = poss[i]->getDistanceToPoint(coord);
825 LineData d = poss[idx]->getData();
826 for (int i=0; i<4; ++i) {
832 if (document!=NULL && handleUndo) {
833 document->startUndoCycle();
836 ret = new Line(container, d);
837 ret->setLayerToActive();
838 ret->setPenToActive();
839 if (container!=NULL) {
840 container->addEntity(ret);
842 if (document!=NULL && handleUndo) {
843 document->addUndoable(ret);
844 document->endUndoCycle();
846 if (graphicView!=NULL) {
847 graphicView->drawEntity(ret);
858 * Creates a line with a relative angle to the given entity.
860 * @param coord Coordinate to define the point where the line should end.
861 * (typically a mouse coordinate).
862 * @param entity Pointer to basis entity. The angle is relative to the
863 * angle of this entity.
864 * @param angle Angle of the line relative to the angle of the basis entity.
865 * @param length Length of the line we're creating.
867 Line* Creation::createLineRelAngle(const Vector& coord,
872 // check given entity / coord:
873 if (entity==NULL || !coord.valid ||
874 (entity->rtti()!=RS2::EntityArc && entity->rtti()!=RS2::EntityCircle
875 && entity->rtti()!=RS2::EntityLine)) {
882 switch (entity->rtti()) {
883 case RS2::EntityLine:
884 a1 = ((Line*)entity)->getAngle1();
887 a1 = ((Arc*)entity)->getCenter().angleTo(coord) + M_PI/2.0;
889 case RS2::EntityCircle:
890 a1 = ((Circle*)entity)->getCenter().angleTo(coord);
900 v1.setPolar(length, a1);
901 //ConstructionLineData(coord-v1, coord+v1);
902 LineData d(coord-v1, coord+v1);
905 if (document!=NULL && handleUndo) {
906 document->startUndoCycle();
909 ret = new Line(container, d);
910 ret->setLayerToActive();
911 ret->setPenToActive();
912 if (container!=NULL) {
913 container->addEntity(ret);
915 if (document!=NULL && handleUndo) {
916 document->addUndoable(ret);
917 document->endUndoCycle();
919 if (graphicView!=NULL) {
920 graphicView->drawEntity(ret);
928 * Creates a polygon with 'number' edges.
930 * @param center Center of the polygon.
931 * @param corner The first corner of the polygon
932 * @param number Number of edges / corners.
934 Line* Creation::createPolygon(const Vector& center,
935 const Vector& corner,
938 // check given coords / number:
939 if (!center.valid || !corner.valid || number<3) {
945 if (document!=NULL && handleUndo) {
946 document->startUndoCycle();
953 for (int n=1; n<=number; ++n) {
955 c2 = c2.rotate(center, (M_PI*2)/number);
957 line = new Line(container, LineData(c1, c2));
958 line->setLayerToActive();
959 line->setPenToActive();
965 if (container!=NULL) {
966 container->addEntity(line);
968 if (document!=NULL && handleUndo) {
969 document->addUndoable(line);
971 if (graphicView!=NULL) {
972 graphicView->drawEntity(line);
976 if (document!=NULL && handleUndo) {
977 document->endUndoCycle();
986 * Creates a polygon with 'number' edges.
988 * @param corner1 The first corner of the polygon.
989 * @param corner2 The second corner of the polygon.
990 * @param number Number of edges / corners.
992 Line* Creation::createPolygon2(const Vector& corner1,
993 const Vector& corner2,
996 // check given coords / number:
997 if (!corner1.valid || !corner2.valid || number<3) {
1003 if (document!=NULL && handleUndo) {
1004 document->startUndoCycle();
1007 double len = corner1.distanceTo(corner2);
1008 double ang1 = corner1.angleTo(corner2);
1012 Vector c2 = corner1;
1016 for (int n=1; n<=number; ++n) {
1018 edge.setPolar(len, ang);
1021 line = new Line(container, LineData(c1, c2));
1022 line->setLayerToActive();
1023 line->setPenToActive();
1029 if (container!=NULL) {
1030 container->addEntity(line);
1032 if (document!=NULL && handleUndo) {
1033 document->addUndoable(line);
1035 if (graphicView!=NULL) {
1036 graphicView->drawEntity(line);
1039 // more accurate than incrementing the angle:
1040 ang = ang1 + (2*M_PI)/number*n;
1043 if (document!=NULL && handleUndo) {
1044 document->endUndoCycle();
1051 * Creates an insert with the given data.
1053 * @param data Insert data (position, block name, ..)
1055 Insert* Creation::createInsert(InsertData & data)
1057 DEBUG->print("Creation::createInsert");
1059 if (document != NULL && handleUndo)
1060 document->startUndoCycle();
1062 Insert * ins = new Insert(container, data);
1063 // inserts are also on layers
1064 ins->setLayerToActive();
1065 ins->setPenToActive();
1067 if (container != NULL)
1068 container->addEntity(ins);
1070 if (document != NULL && handleUndo)
1072 document->addUndoable(ins);
1073 document->endUndoCycle();
1076 if (graphicView != NULL)
1077 graphicView->drawEntity(ins);
1079 DEBUG->print("Creation::createInsert: OK");
1085 * Creates an image with the given data.
1087 Image* Creation::createImage(ImageData& data) {
1089 if (document!=NULL && handleUndo) {
1090 document->startUndoCycle();
1093 Image* img = new Image(container, data);
1094 img->setLayerToActive();
1095 img->setPenToActive();
1098 if (container!=NULL) {
1099 container->addEntity(img);
1101 if (document!=NULL && handleUndo) {
1102 document->addUndoable(img);
1103 document->endUndoCycle();
1105 if (graphicView!=NULL) {
1106 graphicView->drawEntity(img);
1113 * Creates a new block from the currently selected entitiies.
1115 * @param referencePoint Reference point for the block.
1116 * @param name Block name
1117 * @param remove true: remove existing entities, false: don't touch entities
1119 Block * Creation::createBlock(const BlockData & data,
1120 const Vector & referencePoint, const bool remove)
1122 // start undo cycle for the container if we're deleting the existing entities
1123 if (remove && document!=NULL) {
1124 document->startUndoCycle();
1128 new Block(container,
1129 BlockData(data.name, data.basePoint, data.frozen));
1131 // copy entities into a block
1132 for(Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
1134 //for (uint i=0; i<container->count(); ++i) {
1135 //Entity* e = container->entityAt(i);
1137 if (e && e->isSelected())
1139 // delete / redraw entity in graphic view:
1142 #warning "!!! Old rendering path needs upgrading !!!"
1145 graphicView->deleteEntity(e);
1148 e->setSelected(false);
1152 #warning "!!! Old rendering path needs upgrading !!!"
1155 graphicView->deleteEntity(e);
1157 e->setSelected(false);
1159 #warning "!!! Old rendering path needs upgrading !!!"
1162 graphicView->drawEntity(e);
1166 // add entity to block:
1167 Entity * c = e->clone();
1168 c->move(-referencePoint);
1169 block->addEntity(c);
1173 //container->removeEntity(e);
1175 e->changeUndoState();
1178 document->addUndoable(e);
1183 if (remove && document != NULL)
1184 document->endUndoCycle();
1186 if (graphic != NULL)
1187 graphic->addBlock(block);
1193 * Inserts a library item from the given path into the drawing.
1195 Insert * Creation::createLibraryInsert(LibraryInsertData & data)
1197 DEBUG->print("Creation::createLibraryInsert");
1200 if (!g.open(data.file, RS2::FormatUnknown))
1202 DEBUG->print(Debug::D_WARNING, "Creation::createLibraryInsert: Cannot open file: %s");
1207 if (graphic != NULL)
1209 double uf = Units::convert(1.0, g.getUnit(), graphic->getUnit());
1210 g.scale(Vector(0.0, 0.0), Vector(uf, uf));
1213 //g.scale(Vector(data.factor, data.factor));
1214 //g.rotate(data.angle);
1216 // QString s = QFileInfo(data.file).baseName(true);
1217 QString s = QFileInfo(data.file).completeBaseName();
1219 Modification m(*container, graphicView);
1220 m.paste(PasteData(data.insertionPoint, data.factor, data.angle, true, s), &g);
1222 DEBUG->print("Creation::createLibraryInsert: OK");