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 #warning "!!! need to rename graphic to drawing !!!"
45 graphic = container->GetDrawing();
46 document = container->getDocument();
56 * Creates a point entity.
60 * creation.createPoint(Vector(10.0, 15.0));
65 /*void Creation::createPoint(const Vector& p) {
66 entityContainer->addEntity(new Point(entityContainer, p));
70 * Creates a line with two points given.
74 * creation.createLine2P(Vector(10.0, 10.0), Vector(100.0, 200.0));
77 * @param p1 start point
80 /*void Creation::createLine2P(const Vector& p1, const Vector& p2) {
81 entityContainer->addEntity(new Line(entityContainer,
86 * Creates a rectangle with two edge points given.
90 * creation.createRectangle(Vector(5.0, 2.0), Vector(7.5, 3.0));
96 /*void Creation::createRectangle(const Vector& e1, const Vector& e2) {
97 Vector e21(e2.x, e1.y);
98 Vector e12(e1.x, e2.y);
99 entityContainer->addEntity(new Line(entityContainer,
101 entityContainer->addEntity(new Line(entityContainer,
103 entityContainer->addEntity(new Line(entityContainer,
105 entityContainer->addEntity(new Line(entityContainer,
110 * Creates a polyline from the given array of entities.
111 * No checking if the entities actually fit together.
112 * Currently this is like a group.
116 * Polyline *pl = creation.createPolyline(Vector(25.0, 55.0));<br>
117 * pl->addVertex(Vector(50.0, 75.0));<br>
120 * @param entities array of entities
121 * @param startPoint Start point of the polyline
123 /*Polyline* Creation::createPolyline(const Vector& startPoint) {
124 Polyline* pl = new Polyline(entityContainer,
125 PolylineData(startPoint, Vector(0.0,0.0), 0));
126 entityContainer->addEntity(pl);
131 * Creates an entity parallel to the given entity e through the given
134 * @param coord Coordinate to define the distance / side (typically a
136 * @param number Number of parallels.
137 * @param e Original entity.
139 * @return Pointer to the first created parallel or NULL if no
140 * parallel has been created.
142 Entity * Creation::createParallelThrough(const Vector & coord, int number, Entity * e)
149 if (e->rtti() == RS2::EntityLine)
151 Line * l = (Line *)e;
152 ConstructionLine cl(NULL, ConstructionLineData(l->getStartpoint(),
154 dist = cl.getDistanceToPoint(coord);
158 dist = e->getDistanceToPoint(coord);
161 if (dist < RS_MAXDOUBLE)
162 return createParallel(coord, dist, number, e);
168 * Creates an entity parallel to the given entity e.
169 * Out of the 2 possible parallels, the one closest to
170 * the given coordinate is returned.
171 * Lines, Arcs and Circles can have parallels.
173 * @param coord Coordinate to define which parallel we want (typically a
175 * @param distance Distance of the parallel.
176 * @param number Number of parallels.
177 * @param e Original entity.
179 * @return Pointer to the first created parallel or NULL if no
180 * parallel has been created.
182 Entity* Creation::createParallel(const Vector& coord,
183 double distance, int number,
190 case RS2::EntityLine:
191 return createParallelLine(coord, distance, number, (Line*)e);
195 return createParallelArc(coord, distance, number, (Arc*)e);
198 case RS2::EntityCircle:
199 return createParallelCircle(coord, distance, number, (Circle*)e);
212 * Creates a line parallel to the given line e.
213 * Out of the 2 possible parallels, the one closest to
214 * the given coordinate is returned.
216 * @param coord Coordinate to define which parallel we want (typically a
218 * @param distance Distance of the parallel.
219 * @param number Number of parallels.
220 * @param e Original entity.
222 * @return Pointer to the first created parallel or NULL if no
223 * parallel has been created.
225 Line* Creation::createParallelLine(const Vector& coord,
226 double distance, int number,
233 double ang = e->getAngle1() + M_PI/2.0;
235 LineData parallelData;
238 if (document!=NULL && handleUndo) {
239 document->startUndoCycle();
242 for (int num=1; num<=number; ++num) {
244 // calculate 1st parallel:
245 p1.setPolar(distance*num, ang);
246 p1 += e->getStartpoint();
247 p2.setPolar(distance*num, ang);
248 p2 += e->getEndpoint();
249 Line parallel1(NULL, LineData(p1, p2));
251 // calculate 2nd parallel:
252 p1.setPolar(distance*num, ang+M_PI);
253 p1 += e->getStartpoint();
254 p2.setPolar(distance*num, ang+M_PI);
255 p2 += e->getEndpoint();
256 Line parallel2(NULL, LineData(p1, p2));
258 double dist1 = parallel1.getDistanceToPoint(coord);
259 double dist2 = parallel2.getDistanceToPoint(coord);
260 double minDist = std::min(dist1, dist2);
262 if (minDist<RS_MAXDOUBLE) {
264 parallelData = parallel1.getData();
266 parallelData = parallel2.getData();
270 Line* newLine = new Line(container, parallelData);
271 newLine->setLayerToActive();
272 newLine->setPenToActive();
276 if (container!=NULL) {
277 container->addEntity(newLine);
279 if (document!=NULL && handleUndo) {
280 document->addUndoable(newLine);
281 //document->endUndoCycle();
283 if (graphicView!=NULL) {
284 graphicView->drawEntity(newLine);
289 if (document!=NULL && handleUndo) {
290 document->endUndoCycle();
299 * Creates a arc parallel to the given arc e.
300 * Out of the 2 possible parallels, the one closest to
301 * the given coordinate is returned.
303 * @param coord Coordinate to define which parallel we want (typically a
305 * @param distance Distance of the parallel.
306 * @param number Number of parallels.
307 * @param e Original entity.
309 * @return Pointer to the first created parallel or NULL if no
310 * parallel has been created.
312 Arc* Creation::createParallelArc(const Vector& coord,
313 double distance, int number,
320 ArcData parallelData;
323 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
329 for (int num=1; num<=number; ++num) {
331 // calculate parallel:
333 Arc parallel1(NULL, e->getData());
334 parallel1.setRadius(e->getRadius() + distance*num);
335 if (parallel1.getRadius()<0.0) {
336 parallel1.setRadius(RS_MAXDOUBLE);
340 // calculate 2nd parallel:
341 //Arc parallel2(NULL, e->getData());
342 //parallel2.setRadius(e->getRadius()+distance*num);
344 //double dist1 = parallel1.getDistanceToPoint(coord);
345 //double dist2 = parallel2.getDistanceToPoint(coord);
346 //double minDist = min(dist1, dist2);
348 //if (minDist<RS_MAXDOUBLE) {
351 parallelData = parallel1.getData();
353 // parallelData = parallel2.getData();
356 if (document!=NULL && handleUndo) {
357 document->startUndoCycle();
360 Arc* newArc = new Arc(container, parallelData);
361 newArc->setLayerToActive();
362 newArc->setPenToActive();
366 if (container!=NULL) {
367 container->addEntity(newArc);
369 if (document!=NULL && handleUndo) {
370 document->addUndoable(newArc);
371 document->endUndoCycle();
373 if (graphicView!=NULL) {
374 graphicView->drawEntity(newArc);
385 * Creates a circle parallel to the given circle e.
386 * Out of the 2 possible parallels, the one closest to
387 * the given coordinate is returned.
389 * @param coord Coordinate to define which parallel we want (typically a
391 * @param distance Distance of the parallel.
392 * @param number Number of parallels.
393 * @param e Original entity.
395 * @return Pointer to the first created parallel or NULL if no
396 * parallel has been created.
398 Circle* Creation::createParallelCircle(const Vector& coord,
399 double distance, int number,
406 CircleData parallelData;
409 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
415 for (int num=1; num<=number; ++num) {
417 // calculate parallel:
419 Circle parallel1(NULL, e->getData());
420 parallel1.setRadius(e->getRadius() + distance*num);
421 if (parallel1.getRadius()<0.0) {
422 parallel1.setRadius(RS_MAXDOUBLE);
426 // calculate 2nd parallel:
427 //Circle parallel2(NULL, e->getData());
428 //parallel2.setRadius(e->getRadius()+distance*num);
430 //double dist1 = parallel1.getDistanceToPoint(coord);
431 //double dist2 = parallel2.getDistanceToPoint(coord);
432 //double minDist = min(dist1, dist2);
434 //if (minDist<RS_MAXDOUBLE) {
437 parallelData = parallel1.getData();
439 // parallelData = parallel2.getData();
442 if (document!=NULL && handleUndo) {
443 document->startUndoCycle();
446 Circle* newCircle = new Circle(container, parallelData);
447 newCircle->setLayerToActive();
448 newCircle->setPenToActive();
452 if (container!=NULL) {
453 container->addEntity(newCircle);
455 if (document!=NULL && handleUndo) {
456 document->addUndoable(newCircle);
457 document->endUndoCycle();
459 if (graphicView!=NULL) {
460 graphicView->drawEntity(newCircle);
470 * Creates a bisecting line of the angle between the entities
471 * e1 and e2. Out of the 4 possible bisectors, the one closest to
472 * the given coordinate is returned.
474 * @param coord Coordinate to define which bisector we want (typically a
476 * @param length Length of the bisecting line.
477 * @param num Number of bisectors
478 * @param l1 First line.
479 * @param l2 Second line.
481 * @return Pointer to the first bisector created or NULL if no bisectors
484 Line * Creation::createBisector(const Vector & coord1, const Vector & coord2,
485 double length, int num, Line * l1, Line * l2)
487 // check given entities:
488 if (!l1 || !l2 || l1->rtti() != RS2::EntityLine || l2->rtti() != RS2::EntityLine)
491 // intersection between entities:
492 VectorSolutions sol = Information::getIntersection(l1, l2, false);
493 Vector inters = sol.get(0);
498 double angle1 = inters.angleTo(l1->getNearestPointOnEntity(coord1));
499 double angle2 = inters.angleTo(l2->getNearestPointOnEntity(coord2));
500 double angleDiff = Math::getAngleDifference(angle1, angle2);
502 if (angleDiff > M_PI)
503 angleDiff = angleDiff - 2 * M_PI;
507 if (document && handleUndo)
508 document->startUndoCycle();
510 for(int n=1; n<=num; n++)
512 double angle = angle1 + (angleDiff / (num + 1) * n);
514 v.setPolar(length, angle);
515 LineData d = LineData(inters, inters + v);
516 Line * newLine = new Line(container, d);
520 newLine->setLayerToActive();
521 newLine->setPenToActive();
522 container->addEntity(newLine);
525 if (document && handleUndo)
526 document->addUndoable(newLine);
529 graphicView->drawEntity(newLine);
535 if (document && handleUndo)
536 document->endUndoCycle();
544 * Creates a tangent between a given point and a circle or arc.
545 * Out of the 2 possible tangents, the one closest to
546 * the given coordinate is returned.
548 * @param coord Coordinate to define which tangent we want (typically a
550 * @param point Point.
551 * @param circle Circle, arc or ellipse entity.
553 Line* Creation::createTangent1(const Vector& coord,
559 // check given entities:
560 if (circle==NULL || !point.valid ||
561 (circle->rtti()!=RS2::EntityArc && circle->rtti()!=RS2::EntityCircle
562 && circle->rtti()!=RS2::EntityEllipse)) {
567 if (circle->rtti()==RS2::EntityCircle) {
568 circleCenter = ((Circle*)circle)->getCenter();
569 } else if (circle->rtti()==RS2::EntityArc) {
570 circleCenter = ((Arc*)circle)->getCenter();
571 } else if (circle->rtti()==RS2::EntityEllipse) {
572 circleCenter = ((Ellipse*)circle)->getCenter();
575 // the two tangent points:
578 // calculate tangent points for arcs / circles:
579 if (circle->rtti()!=RS2::EntityEllipse) {
580 // create temp. thales circle:
581 Vector tCenter = (point + circleCenter)/2.0;
582 double tRadius = point.distanceTo(tCenter);
584 Circle tmp(NULL, CircleData(tCenter, tRadius));
586 // get the two intersection points which are the tangent points:
587 sol = Information::getIntersection(&tmp, circle, false);
590 // calculate tangent points for ellipses:
592 Ellipse* el = (Ellipse*)circle;
594 //sol.set(0, circleCenter);
595 //sol.set(1, circleCenter);
598 double a = el->getMajorRadius(); // the length of the major axis / 2
599 double b = el->getMinorRadius(); // the length of the minor axis / 2
601 // rotate and move point:
602 Vector point2 = point;
603 point2.move(-el->getCenter());
604 point2.rotate(-el->getAngle());
606 double xp = point2.x; // coordinates of the given point
607 double yp = point2.y;
609 double xt1; // Tangent point 1
611 double xt2; // Tangent point 2
616 double d = a2 / b2 * yp / xp;
618 double af = b2 * d * d + a2;
619 double bf = -b2 * d * e * 2.0;
620 double cf = b2 * e * e - a2 * b2;
621 double t = sqrt(bf * bf - af * cf * 4.0);
622 yt1 = (t - bf) / (af * 2.0);
624 yt2 = (-t - bf) / (af * 2.0);
627 Vector s1 = Vector(xt1, yt1);
628 Vector s2 = Vector(xt2, yt2);
630 s1.rotate(el->getAngle());
631 s1.move(el->getCenter());
633 s2.rotate(el->getAngle());
634 s2.move(el->getCenter());
642 if (!sol.get(0).valid || !sol.get(1).valid) {
646 // create all possible tangents:
651 d = LineData(sol.get(0), point);
652 poss[0] = new Line(NULL, d);
653 d = LineData(sol.get(1), point);
654 poss[1] = new Line(NULL, d);
656 // find closest tangent:
657 double minDist = RS_MAXDOUBLE;
660 for (int i=0; i<2; ++i) {
661 dist = poss[i]->getDistanceToPoint(coord);
668 // create the closest tangent:
670 LineData d = poss[idx]->getData();
672 for (int i=0; i<2; ++i) {
676 if (document!=NULL && handleUndo) {
677 document->startUndoCycle();
680 ret = new Line(container, d);
681 ret->setLayerToActive();
682 ret->setPenToActive();
683 if (container!=NULL) {
684 container->addEntity(ret);
686 if (document!=NULL && handleUndo) {
687 document->addUndoable(ret);
688 document->endUndoCycle();
690 if (graphicView!=NULL) {
691 graphicView->drawEntity(ret);
703 * Creates a tangent between two circles or arcs.
704 * Out of the 4 possible tangents, the one closest to
705 * the given coordinate is returned.
707 * @param coord Coordinate to define which tangent we want (typically a
709 * @param circle1 1st circle or arc entity.
710 * @param circle2 2nd circle or arc entity.
712 Line* Creation::createTangent2(const Vector& coord,
716 Vector circleCenter1;
717 Vector circleCenter2;
718 double circleRadius1 = 0.0;
719 double circleRadius2 = 0.0;
721 // check given entities:
722 if (circle1==NULL || circle2==NULL ||
723 (circle1->rtti()!=RS2::EntityArc &&
724 circle1->rtti()!=RS2::EntityCircle) ||
725 (circle2->rtti()!=RS2::EntityArc &&
726 circle2->rtti()!=RS2::EntityCircle) ) {
731 if (circle1->rtti()==RS2::EntityCircle) {
732 circleCenter1 = ((Circle*)circle1)->getCenter();
733 circleRadius1 = ((Circle*)circle1)->getRadius();
734 } else if (circle1->rtti()==RS2::EntityArc) {
735 circleCenter1 = ((Arc*)circle1)->getCenter();
736 circleRadius1 = ((Arc*)circle1)->getRadius();
739 if (circle2->rtti()==RS2::EntityCircle) {
740 circleCenter2 = ((Circle*)circle2)->getCenter();
741 circleRadius2 = ((Circle*)circle2)->getRadius();
742 } else if (circle2->rtti()==RS2::EntityArc) {
743 circleCenter2 = ((Arc*)circle2)->getCenter();
744 circleRadius2 = ((Arc*)circle2)->getRadius();
747 // create all possible tangents:
749 for (int i=0; i<4; ++i) {
755 double angle1 = circleCenter1.angleTo(circleCenter2);
756 double dist1 = circleCenter1.distanceTo(circleCenter2);
760 double dist2 = circleRadius2 - circleRadius1;
762 double angle2 = asin(dist2/dist1);
763 double angt1 = angle1 + angle2 + M_PI/2.0;
764 double angt2 = angle1 - angle2 - M_PI/2.0;
768 offs1.setPolar(circleRadius1, angt1);
769 offs2.setPolar(circleRadius2, angt1);
771 d = LineData(circleCenter1 + offs1,
772 circleCenter2 + offs2);
773 poss[0] = new Line(NULL, d);
776 offs1.setPolar(circleRadius1, angt2);
777 offs2.setPolar(circleRadius2, angt2);
779 d = LineData(circleCenter1 + offs1,
780 circleCenter2 + offs2);
781 poss[1] = new Line(NULL, d);
785 double dist3 = circleRadius2 + circleRadius1;
787 double angle3 = asin(dist3/dist1);
788 double angt3 = angle1 + angle3 + M_PI/2.0;
789 double angt4 = angle1 - angle3 - M_PI/2.0;
793 offs1.setPolar(circleRadius1, angt3);
794 offs2.setPolar(circleRadius2, angt3);
796 d = LineData(circleCenter1 - offs1,
797 circleCenter2 + offs2);
798 poss[2] = new Line(NULL, d);
801 offs1.setPolar(circleRadius1, angt4);
802 offs2.setPolar(circleRadius2, angt4);
804 d = LineData(circleCenter1 - offs1,
805 circleCenter2 + offs2);
806 poss[3] = new Line(NULL, d);
811 // find closest tangent:
812 double minDist = RS_MAXDOUBLE;
815 for (int i=0; i<4; ++i) {
817 dist = poss[i]->getDistanceToPoint(coord);
826 LineData d = poss[idx]->getData();
827 for (int i=0; i<4; ++i) {
833 if (document!=NULL && handleUndo) {
834 document->startUndoCycle();
837 ret = new Line(container, d);
838 ret->setLayerToActive();
839 ret->setPenToActive();
840 if (container!=NULL) {
841 container->addEntity(ret);
843 if (document!=NULL && handleUndo) {
844 document->addUndoable(ret);
845 document->endUndoCycle();
847 if (graphicView!=NULL) {
848 graphicView->drawEntity(ret);
859 * Creates a line with a relative angle to the given entity.
861 * @param coord Coordinate to define the point where the line should end.
862 * (typically a mouse coordinate).
863 * @param entity Pointer to basis entity. The angle is relative to the
864 * angle of this entity.
865 * @param angle Angle of the line relative to the angle of the basis entity.
866 * @param length Length of the line we're creating.
868 Line* Creation::createLineRelAngle(const Vector& coord,
873 // check given entity / coord:
874 if (entity==NULL || !coord.valid ||
875 (entity->rtti()!=RS2::EntityArc && entity->rtti()!=RS2::EntityCircle
876 && entity->rtti()!=RS2::EntityLine)) {
883 switch (entity->rtti()) {
884 case RS2::EntityLine:
885 a1 = ((Line*)entity)->getAngle1();
888 a1 = ((Arc*)entity)->getCenter().angleTo(coord) + M_PI/2.0;
890 case RS2::EntityCircle:
891 a1 = ((Circle*)entity)->getCenter().angleTo(coord);
901 v1.setPolar(length, a1);
902 //ConstructionLineData(coord-v1, coord+v1);
903 LineData d(coord-v1, coord+v1);
906 if (document!=NULL && handleUndo) {
907 document->startUndoCycle();
910 ret = new Line(container, d);
911 ret->setLayerToActive();
912 ret->setPenToActive();
913 if (container!=NULL) {
914 container->addEntity(ret);
916 if (document!=NULL && handleUndo) {
917 document->addUndoable(ret);
918 document->endUndoCycle();
920 if (graphicView!=NULL) {
921 graphicView->drawEntity(ret);
929 * Creates a polygon with 'number' edges.
931 * @param center Center of the polygon.
932 * @param corner The first corner of the polygon
933 * @param number Number of edges / corners.
935 Line* Creation::createPolygon(const Vector& center,
936 const Vector& corner,
939 // check given coords / number:
940 if (!center.valid || !corner.valid || number<3) {
946 if (document!=NULL && handleUndo) {
947 document->startUndoCycle();
954 for (int n=1; n<=number; ++n) {
956 c2 = c2.rotate(center, (M_PI*2)/number);
958 line = new Line(container, LineData(c1, c2));
959 line->setLayerToActive();
960 line->setPenToActive();
966 if (container!=NULL) {
967 container->addEntity(line);
969 if (document!=NULL && handleUndo) {
970 document->addUndoable(line);
972 if (graphicView!=NULL) {
973 graphicView->drawEntity(line);
977 if (document!=NULL && handleUndo) {
978 document->endUndoCycle();
987 * Creates a polygon with 'number' edges.
989 * @param corner1 The first corner of the polygon.
990 * @param corner2 The second corner of the polygon.
991 * @param number Number of edges / corners.
993 Line* Creation::createPolygon2(const Vector& corner1,
994 const Vector& corner2,
997 // check given coords / number:
998 if (!corner1.valid || !corner2.valid || number<3) {
1004 if (document!=NULL && handleUndo) {
1005 document->startUndoCycle();
1008 double len = corner1.distanceTo(corner2);
1009 double ang1 = corner1.angleTo(corner2);
1013 Vector c2 = corner1;
1017 for (int n=1; n<=number; ++n) {
1019 edge.setPolar(len, ang);
1022 line = new Line(container, LineData(c1, c2));
1023 line->setLayerToActive();
1024 line->setPenToActive();
1030 if (container!=NULL) {
1031 container->addEntity(line);
1033 if (document!=NULL && handleUndo) {
1034 document->addUndoable(line);
1036 if (graphicView!=NULL) {
1037 graphicView->drawEntity(line);
1040 // more accurate than incrementing the angle:
1041 ang = ang1 + (2*M_PI)/number*n;
1044 if (document!=NULL && handleUndo) {
1045 document->endUndoCycle();
1052 * Creates an insert with the given data.
1054 * @param data Insert data (position, block name, ..)
1056 Insert* Creation::createInsert(InsertData & data)
1058 DEBUG->print("Creation::createInsert");
1060 if (document != NULL && handleUndo)
1061 document->startUndoCycle();
1063 Insert * ins = new Insert(container, data);
1064 // inserts are also on layers
1065 ins->setLayerToActive();
1066 ins->setPenToActive();
1068 if (container != NULL)
1069 container->addEntity(ins);
1071 if (document != NULL && handleUndo)
1073 document->addUndoable(ins);
1074 document->endUndoCycle();
1077 if (graphicView != NULL)
1078 graphicView->drawEntity(ins);
1080 DEBUG->print("Creation::createInsert: OK");
1086 * Creates an image with the given data.
1088 Image* Creation::createImage(ImageData& data) {
1090 if (document!=NULL && handleUndo) {
1091 document->startUndoCycle();
1094 Image* img = new Image(container, data);
1095 img->setLayerToActive();
1096 img->setPenToActive();
1099 if (container!=NULL) {
1100 container->addEntity(img);
1102 if (document!=NULL && handleUndo) {
1103 document->addUndoable(img);
1104 document->endUndoCycle();
1106 if (graphicView!=NULL) {
1107 graphicView->drawEntity(img);
1114 * Creates a new block from the currently selected entitiies.
1116 * @param referencePoint Reference point for the block.
1117 * @param name Block name
1118 * @param remove true: remove existing entities, false: don't touch entities
1120 Block * Creation::createBlock(const BlockData & data,
1121 const Vector & referencePoint, const bool remove)
1123 // start undo cycle for the container if we're deleting the existing entities
1124 if (remove && document!=NULL) {
1125 document->startUndoCycle();
1129 new Block(container,
1130 BlockData(data.name, data.basePoint, data.frozen));
1132 // copy entities into a block
1133 for(Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
1135 //for (uint i=0; i<container->count(); ++i) {
1136 //Entity* e = container->entityAt(i);
1138 if (e && e->isSelected())
1140 // delete / redraw entity in graphic view:
1143 #warning "!!! Old rendering path needs upgrading !!!"
1146 graphicView->deleteEntity(e);
1149 e->setSelected(false);
1153 #warning "!!! Old rendering path needs upgrading !!!"
1156 graphicView->deleteEntity(e);
1158 e->setSelected(false);
1160 #warning "!!! Old rendering path needs upgrading !!!"
1163 graphicView->drawEntity(e);
1167 // add entity to block:
1168 Entity * c = e->clone();
1169 c->move(-referencePoint);
1170 block->addEntity(c);
1174 //container->removeEntity(e);
1176 e->changeUndoState();
1179 document->addUndoable(e);
1184 if (remove && document != NULL)
1185 document->endUndoCycle();
1187 if (graphic != NULL)
1188 graphic->addBlock(block);
1194 * Inserts a library item from the given path into the drawing.
1196 Insert * Creation::createLibraryInsert(LibraryInsertData & data)
1198 DEBUG->print("Creation::createLibraryInsert");
1201 if (!g.open(data.file, RS2::FormatUnknown))
1203 DEBUG->print(Debug::D_WARNING, "Creation::createLibraryInsert: Cannot open file: %s");
1208 if (graphic != NULL)
1210 double uf = Units::convert(1.0, g.getUnit(), graphic->getUnit());
1211 g.scale(Vector(0.0, 0.0), Vector(uf, uf));
1214 //g.scale(Vector(data.factor, data.factor));
1215 //g.rotate(data.angle);
1217 // QString s = QFileInfo(data.file).baseName(true);
1218 QString s = QFileInfo(data.file).completeBaseName();
1220 Modification m(*container, graphicView);
1221 m.paste(PasteData(data.insertionPoint, data.factor, data.angle, true, s), &g);
1223 DEBUG->print("Creation::createLibraryInsert: OK");