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. :-)
17 #include "rs_creation.h"
19 #include "rs_constructionline.h"
21 #include "graphicview.h"
23 #include "rs_information.h"
24 #include "rs_insert.h"
25 #include "rs_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 RS_Creation::RS_Creation(RS_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 RS_Creation::createPoint(const Vector& p) {
65 entityContainer->addEntity(new RS_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 RS_Creation::createLine2P(const Vector& p1, const Vector& p2) {
80 entityContainer->addEntity(new RS_Line(entityContainer,
81 RS_LineData(p1, p2)));
85 * Creates a rectangle with two edge points given.
89 * creation.createRectangle(Vector(5.0, 2.0), Vector(7.5, 3.0));
95 /*void RS_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 RS_Line(entityContainer,
99 RS_LineData(e1, e12)));
100 entityContainer->addEntity(new RS_Line(entityContainer,
101 RS_LineData(e12, e2)));
102 entityContainer->addEntity(new RS_Line(entityContainer,
103 RS_LineData(e2, e21)));
104 entityContainer->addEntity(new RS_Line(entityContainer,
105 RS_LineData(e21, e1)));
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 * RS_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 /*RS_Polyline* RS_Creation::createPolyline(const Vector& startPoint) {
123 RS_Polyline* pl = new RS_Polyline(entityContainer,
124 RS_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 RS_Entity * RS_Creation::createParallelThrough(const Vector & coord, int number, RS_Entity * e)
148 if (e->rtti() == RS2::EntityLine)
150 RS_Line * l = (RS_Line *)e;
151 RS_ConstructionLine cl(NULL, RS_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 RS_Entity* RS_Creation::createParallel(const Vector& coord,
182 double distance, int number,
189 case RS2::EntityLine:
190 return createParallelLine(coord, distance, number, (RS_Line*)e);
194 return createParallelArc(coord, distance, number, (RS_Arc*)e);
197 case RS2::EntityCircle:
198 return createParallelCircle(coord, distance, number, (RS_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 RS_Line* RS_Creation::createParallelLine(const Vector& coord,
225 double distance, int number,
232 double ang = e->getAngle1() + M_PI/2.0;
234 RS_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 RS_Line parallel1(NULL, RS_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 RS_Line parallel2(NULL, RS_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 RS_Line* newLine = new RS_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 RS_Arc* RS_Creation::createParallelArc(const Vector& coord,
312 double distance, int number,
319 RS_ArcData parallelData;
322 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
328 for (int num=1; num<=number; ++num) {
330 // calculate parallel:
332 RS_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 //RS_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 RS_Arc* newArc = new RS_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 RS_Circle* RS_Creation::createParallelCircle(const Vector& coord,
398 double distance, int number,
405 RS_CircleData parallelData;
406 RS_Circle* ret = NULL;
408 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
414 for (int num=1; num<=number; ++num) {
416 // calculate parallel:
418 RS_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 //RS_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 RS_Circle* newCircle = new RS_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 RS_Line* RS_Creation::createBisector(const Vector& coord1,
484 const Vector& coord2,
492 // check given entities:
493 if (l1==NULL || l2==NULL ||
494 l1->rtti()!=RS2::EntityLine || l2->rtti()!=RS2::EntityLine) {
498 // intersection between entities:
499 sol = RS_Information::getIntersection(l1, l2, false);
500 Vector inters = sol.get(0);
501 if (inters.valid==false) {
505 double angle1 = inters.angleTo(l1->getNearestPointOnEntity(coord1));
506 double angle2 = inters.angleTo(l2->getNearestPointOnEntity(coord2));
507 double angleDiff = RS_Math::getAngleDifference(angle1, angle2);
508 if (angleDiff>M_PI) {
509 angleDiff = angleDiff - 2*M_PI;
513 if (document!=NULL && handleUndo) {
514 document->startUndoCycle();
517 for (int n=1; n<=num; ++n) {
519 double angle = angle1 +
520 (angleDiff / (num+1) * n);
526 v.setPolar(length, angle);
527 d = RS_LineData(inters, inters + v);
529 RS_Line* newLine = new RS_Line(container, d);
530 if (container!=NULL) {
531 newLine->setLayerToActive();
532 newLine->setPenToActive();
533 container->addEntity(newLine);
535 if (document!=NULL && handleUndo) {
536 document->addUndoable(newLine);
538 if (graphicView!=NULL) {
539 graphicView->drawEntity(newLine);
545 if (document!=NULL && handleUndo) {
546 document->endUndoCycle();
555 * Creates a tangent between a given point and a circle or arc.
556 * Out of the 2 possible tangents, the one closest to
557 * the given coordinate is returned.
559 * @param coord Coordinate to define which tangent we want (typically a
561 * @param point Point.
562 * @param circle Circle, arc or ellipse entity.
564 RS_Line* RS_Creation::createTangent1(const Vector& coord,
570 // check given entities:
571 if (circle==NULL || !point.valid ||
572 (circle->rtti()!=RS2::EntityArc && circle->rtti()!=RS2::EntityCircle
573 && circle->rtti()!=RS2::EntityEllipse)) {
578 if (circle->rtti()==RS2::EntityCircle) {
579 circleCenter = ((RS_Circle*)circle)->getCenter();
580 } else if (circle->rtti()==RS2::EntityArc) {
581 circleCenter = ((RS_Arc*)circle)->getCenter();
582 } else if (circle->rtti()==RS2::EntityEllipse) {
583 circleCenter = ((RS_Ellipse*)circle)->getCenter();
586 // the two tangent points:
589 // calculate tangent points for arcs / circles:
590 if (circle->rtti()!=RS2::EntityEllipse) {
591 // create temp. thales circle:
592 Vector tCenter = (point + circleCenter)/2.0;
593 double tRadius = point.distanceTo(tCenter);
595 RS_Circle tmp(NULL, RS_CircleData(tCenter, tRadius));
597 // get the two intersection points which are the tangent points:
598 sol = RS_Information::getIntersection(&tmp, circle, false);
601 // calculate tangent points for ellipses:
603 RS_Ellipse* el = (RS_Ellipse*)circle;
605 //sol.set(0, circleCenter);
606 //sol.set(1, circleCenter);
609 double a = el->getMajorRadius(); // the length of the major axis / 2
610 double b = el->getMinorRadius(); // the length of the minor axis / 2
612 // rotate and move point:
613 Vector point2 = point;
614 point2.move(-el->getCenter());
615 point2.rotate(-el->getAngle());
617 double xp = point2.x; // coordinates of the given point
618 double yp = point2.y;
620 double xt1; // Tangent point 1
622 double xt2; // Tangent point 2
627 double d = a2 / b2 * yp / xp;
629 double af = b2 * d * d + a2;
630 double bf = -b2 * d * e * 2.0;
631 double cf = b2 * e * e - a2 * b2;
632 double t = sqrt(bf * bf - af * cf * 4.0);
633 yt1 = (t - bf) / (af * 2.0);
635 yt2 = (-t - bf) / (af * 2.0);
638 Vector s1 = Vector(xt1, yt1);
639 Vector s2 = Vector(xt2, yt2);
641 s1.rotate(el->getAngle());
642 s1.move(el->getCenter());
644 s2.rotate(el->getAngle());
645 s2.move(el->getCenter());
653 if (!sol.get(0).valid || !sol.get(1).valid) {
657 // create all possible tangents:
662 d = RS_LineData(sol.get(0), point);
663 poss[0] = new RS_Line(NULL, d);
664 d = RS_LineData(sol.get(1), point);
665 poss[1] = new RS_Line(NULL, d);
667 // find closest tangent:
668 double minDist = RS_MAXDOUBLE;
671 for (int i=0; i<2; ++i) {
672 dist = poss[i]->getDistanceToPoint(coord);
679 // create the closest tangent:
681 RS_LineData d = poss[idx]->getData();
683 for (int i=0; i<2; ++i) {
687 if (document!=NULL && handleUndo) {
688 document->startUndoCycle();
691 ret = new RS_Line(container, d);
692 ret->setLayerToActive();
693 ret->setPenToActive();
694 if (container!=NULL) {
695 container->addEntity(ret);
697 if (document!=NULL && handleUndo) {
698 document->addUndoable(ret);
699 document->endUndoCycle();
701 if (graphicView!=NULL) {
702 graphicView->drawEntity(ret);
714 * Creates a tangent between two circles or arcs.
715 * Out of the 4 possible tangents, the one closest to
716 * the given coordinate is returned.
718 * @param coord Coordinate to define which tangent we want (typically a
720 * @param circle1 1st circle or arc entity.
721 * @param circle2 2nd circle or arc entity.
723 RS_Line* RS_Creation::createTangent2(const Vector& coord,
725 RS_Entity* circle2) {
727 Vector circleCenter1;
728 Vector circleCenter2;
729 double circleRadius1 = 0.0;
730 double circleRadius2 = 0.0;
732 // check given entities:
733 if (circle1==NULL || circle2==NULL ||
734 (circle1->rtti()!=RS2::EntityArc &&
735 circle1->rtti()!=RS2::EntityCircle) ||
736 (circle2->rtti()!=RS2::EntityArc &&
737 circle2->rtti()!=RS2::EntityCircle) ) {
742 if (circle1->rtti()==RS2::EntityCircle) {
743 circleCenter1 = ((RS_Circle*)circle1)->getCenter();
744 circleRadius1 = ((RS_Circle*)circle1)->getRadius();
745 } else if (circle1->rtti()==RS2::EntityArc) {
746 circleCenter1 = ((RS_Arc*)circle1)->getCenter();
747 circleRadius1 = ((RS_Arc*)circle1)->getRadius();
750 if (circle2->rtti()==RS2::EntityCircle) {
751 circleCenter2 = ((RS_Circle*)circle2)->getCenter();
752 circleRadius2 = ((RS_Circle*)circle2)->getRadius();
753 } else if (circle2->rtti()==RS2::EntityArc) {
754 circleCenter2 = ((RS_Arc*)circle2)->getCenter();
755 circleRadius2 = ((RS_Arc*)circle2)->getRadius();
758 // create all possible tangents:
760 for (int i=0; i<4; ++i) {
766 double angle1 = circleCenter1.angleTo(circleCenter2);
767 double dist1 = circleCenter1.distanceTo(circleCenter2);
771 double dist2 = circleRadius2 - circleRadius1;
773 double angle2 = asin(dist2/dist1);
774 double angt1 = angle1 + angle2 + M_PI/2.0;
775 double angt2 = angle1 - angle2 - M_PI/2.0;
779 offs1.setPolar(circleRadius1, angt1);
780 offs2.setPolar(circleRadius2, angt1);
782 d = RS_LineData(circleCenter1 + offs1,
783 circleCenter2 + offs2);
784 poss[0] = new RS_Line(NULL, d);
787 offs1.setPolar(circleRadius1, angt2);
788 offs2.setPolar(circleRadius2, angt2);
790 d = RS_LineData(circleCenter1 + offs1,
791 circleCenter2 + offs2);
792 poss[1] = new RS_Line(NULL, d);
796 double dist3 = circleRadius2 + circleRadius1;
798 double angle3 = asin(dist3/dist1);
799 double angt3 = angle1 + angle3 + M_PI/2.0;
800 double angt4 = angle1 - angle3 - M_PI/2.0;
804 offs1.setPolar(circleRadius1, angt3);
805 offs2.setPolar(circleRadius2, angt3);
807 d = RS_LineData(circleCenter1 - offs1,
808 circleCenter2 + offs2);
809 poss[2] = new RS_Line(NULL, d);
812 offs1.setPolar(circleRadius1, angt4);
813 offs2.setPolar(circleRadius2, angt4);
815 d = RS_LineData(circleCenter1 - offs1,
816 circleCenter2 + offs2);
817 poss[3] = new RS_Line(NULL, d);
822 // find closest tangent:
823 double minDist = RS_MAXDOUBLE;
826 for (int i=0; i<4; ++i) {
828 dist = poss[i]->getDistanceToPoint(coord);
837 RS_LineData d = poss[idx]->getData();
838 for (int i=0; i<4; ++i) {
844 if (document!=NULL && handleUndo) {
845 document->startUndoCycle();
848 ret = new RS_Line(container, d);
849 ret->setLayerToActive();
850 ret->setPenToActive();
851 if (container!=NULL) {
852 container->addEntity(ret);
854 if (document!=NULL && handleUndo) {
855 document->addUndoable(ret);
856 document->endUndoCycle();
858 if (graphicView!=NULL) {
859 graphicView->drawEntity(ret);
870 * Creates a line with a relative angle to the given entity.
872 * @param coord Coordinate to define the point where the line should end.
873 * (typically a mouse coordinate).
874 * @param entity Pointer to basis entity. The angle is relative to the
875 * angle of this entity.
876 * @param angle Angle of the line relative to the angle of the basis entity.
877 * @param length Length of the line we're creating.
879 RS_Line* RS_Creation::createLineRelAngle(const Vector& coord,
884 // check given entity / coord:
885 if (entity==NULL || !coord.valid ||
886 (entity->rtti()!=RS2::EntityArc && entity->rtti()!=RS2::EntityCircle
887 && entity->rtti()!=RS2::EntityLine)) {
894 switch (entity->rtti()) {
895 case RS2::EntityLine:
896 a1 = ((RS_Line*)entity)->getAngle1();
899 a1 = ((RS_Arc*)entity)->getCenter().angleTo(coord) + M_PI/2.0;
901 case RS2::EntityCircle:
902 a1 = ((RS_Circle*)entity)->getCenter().angleTo(coord);
912 v1.setPolar(length, a1);
913 //RS_ConstructionLineData(coord-v1, coord+v1);
914 RS_LineData d(coord-v1, coord+v1);
917 if (document!=NULL && handleUndo) {
918 document->startUndoCycle();
921 ret = new RS_Line(container, d);
922 ret->setLayerToActive();
923 ret->setPenToActive();
924 if (container!=NULL) {
925 container->addEntity(ret);
927 if (document!=NULL && handleUndo) {
928 document->addUndoable(ret);
929 document->endUndoCycle();
931 if (graphicView!=NULL) {
932 graphicView->drawEntity(ret);
940 * Creates a polygon with 'number' edges.
942 * @param center Center of the polygon.
943 * @param corner The first corner of the polygon
944 * @param number Number of edges / corners.
946 RS_Line* RS_Creation::createPolygon(const Vector& center,
947 const Vector& corner,
950 // check given coords / number:
951 if (!center.valid || !corner.valid || number<3) {
957 if (document!=NULL && handleUndo) {
958 document->startUndoCycle();
965 for (int n=1; n<=number; ++n) {
967 c2 = c2.rotate(center, (M_PI*2)/number);
969 line = new RS_Line(container, RS_LineData(c1, c2));
970 line->setLayerToActive();
971 line->setPenToActive();
977 if (container!=NULL) {
978 container->addEntity(line);
980 if (document!=NULL && handleUndo) {
981 document->addUndoable(line);
983 if (graphicView!=NULL) {
984 graphicView->drawEntity(line);
988 if (document!=NULL && handleUndo) {
989 document->endUndoCycle();
998 * Creates a polygon with 'number' edges.
1000 * @param corner1 The first corner of the polygon.
1001 * @param corner2 The second corner of the polygon.
1002 * @param number Number of edges / corners.
1004 RS_Line* RS_Creation::createPolygon2(const Vector& corner1,
1005 const Vector& corner2,
1008 // check given coords / number:
1009 if (!corner1.valid || !corner2.valid || number<3) {
1013 RS_Line* ret = NULL;
1015 if (document!=NULL && handleUndo) {
1016 document->startUndoCycle();
1019 double len = corner1.distanceTo(corner2);
1020 double ang1 = corner1.angleTo(corner2);
1024 Vector c2 = corner1;
1028 for (int n=1; n<=number; ++n) {
1030 edge.setPolar(len, ang);
1033 line = new RS_Line(container, RS_LineData(c1, c2));
1034 line->setLayerToActive();
1035 line->setPenToActive();
1041 if (container!=NULL) {
1042 container->addEntity(line);
1044 if (document!=NULL && handleUndo) {
1045 document->addUndoable(line);
1047 if (graphicView!=NULL) {
1048 graphicView->drawEntity(line);
1051 // more accurate than incrementing the angle:
1052 ang = ang1 + (2*M_PI)/number*n;
1055 if (document!=NULL && handleUndo) {
1056 document->endUndoCycle();
1063 * Creates an insert with the given data.
1065 * @param data Insert data (position, block name, ..)
1067 RS_Insert* RS_Creation::createInsert(RS_InsertData & data)
1069 RS_DEBUG->print("RS_Creation::createInsert");
1071 if (document != NULL && handleUndo)
1072 document->startUndoCycle();
1074 RS_Insert * ins = new RS_Insert(container, data);
1075 // inserts are also on layers
1076 ins->setLayerToActive();
1077 ins->setPenToActive();
1079 if (container != NULL)
1080 container->addEntity(ins);
1082 if (document != NULL && handleUndo)
1084 document->addUndoable(ins);
1085 document->endUndoCycle();
1088 if (graphicView != NULL)
1089 graphicView->drawEntity(ins);
1091 RS_DEBUG->print("RS_Creation::createInsert: OK");
1097 * Creates an image with the given data.
1099 RS_Image* RS_Creation::createImage(RS_ImageData& data) {
1101 if (document!=NULL && handleUndo) {
1102 document->startUndoCycle();
1105 RS_Image* img = new RS_Image(container, data);
1106 img->setLayerToActive();
1107 img->setPenToActive();
1110 if (container!=NULL) {
1111 container->addEntity(img);
1113 if (document!=NULL && handleUndo) {
1114 document->addUndoable(img);
1115 document->endUndoCycle();
1117 if (graphicView!=NULL) {
1118 graphicView->drawEntity(img);
1125 * Creates a new block from the currently selected entitiies.
1127 * @param referencePoint Reference point for the block.
1128 * @param name Block name
1129 * @param remove true: remove existing entities, false: don't touch entities
1131 RS_Block * RS_Creation::createBlock(const RS_BlockData & data,
1132 const Vector & referencePoint, const bool remove)
1134 // start undo cycle for the container if we're deleting the existing entities
1135 if (remove && document!=NULL) {
1136 document->startUndoCycle();
1140 new RS_Block(container,
1141 RS_BlockData(data.name, data.basePoint, data.frozen));
1143 // copy entities into a block
1144 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
1146 //for (uint i=0; i<container->count(); ++i) {
1147 //RS_Entity* e = container->entityAt(i);
1149 if (e != NULL && e->isSelected())
1151 // delete / redraw entity in graphic view:
1154 if (graphicView != NULL)
1155 graphicView->deleteEntity(e);
1157 e->setSelected(false);
1161 if (graphicView != NULL)
1162 graphicView->deleteEntity(e);
1164 e->setSelected(false);
1166 if (graphicView != NULL)
1167 graphicView->drawEntity(e);
1170 // add entity to block:
1171 RS_Entity * c = e->clone();
1172 c->move(-referencePoint);
1173 block->addEntity(c);
1177 //container->removeEntity(e);
1179 e->changeUndoState();
1181 if (document != NULL)
1182 document->addUndoable(e);
1187 if (remove && document != NULL)
1188 document->endUndoCycle();
1190 if (graphic != NULL)
1191 graphic->addBlock(block);
1197 * Inserts a library item from the given path into the drawing.
1199 RS_Insert * RS_Creation::createLibraryInsert(RS_LibraryInsertData & data)
1201 RS_DEBUG->print("RS_Creation::createLibraryInsert");
1204 if (!g.open(data.file, RS2::FormatUnknown))
1206 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Creation::createLibraryInsert: Cannot open file: %s");
1211 if (graphic != NULL)
1213 double uf = RS_Units::convert(1.0, g.getUnit(), graphic->getUnit());
1214 g.scale(Vector(0.0, 0.0), Vector(uf, uf));
1217 //g.scale(Vector(data.factor, data.factor));
1218 //g.rotate(data.angle);
1220 // QString s = QFileInfo(data.file).baseName(true);
1221 QString s = QFileInfo(data.file).completeBaseName();
1223 RS_Modification m(*container, graphicView);
1224 m.paste(RS_PasteData(data.insertionPoint, data.factor, data.angle, true, s), &g);
1226 RS_DEBUG->print("RS_Creation::createLibraryInsert: OK");