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
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
15 #include "rs_creation.h"
17 #include "rs_constructionline.h"
19 #include "rs_graphicview.h"
21 #include "rs_information.h"
22 #include "rs_insert.h"
23 #include "rs_modification.h"
27 * Default constructor.
29 * @param container The container to which we will add
30 * entities. Usually that's an Drawing entity but
31 * it can also be a polyline, text, ...
33 RS_Creation::RS_Creation(RS_EntityContainer * container, RS_GraphicView * graphicView,
36 this->container = container;
37 this->graphicView = graphicView;
38 this->handleUndo = handleUndo;
40 if (container != NULL)
42 graphic = container->getGraphic();
43 document = container->getDocument();
53 * Creates a point entity.
57 * creation.createPoint(Vector(10.0, 15.0));
62 /*void RS_Creation::createPoint(const Vector& p) {
63 entityContainer->addEntity(new RS_Point(entityContainer, p));
67 * Creates a line with two points given.
71 * creation.createLine2P(Vector(10.0, 10.0), Vector(100.0, 200.0));
74 * @param p1 start point
77 /*void RS_Creation::createLine2P(const Vector& p1, const Vector& p2) {
78 entityContainer->addEntity(new RS_Line(entityContainer,
79 RS_LineData(p1, p2)));
83 * Creates a rectangle with two edge points given.
87 * creation.createRectangle(Vector(5.0, 2.0), Vector(7.5, 3.0));
93 /*void RS_Creation::createRectangle(const Vector& e1, const Vector& e2) {
94 Vector e21(e2.x, e1.y);
95 Vector e12(e1.x, e2.y);
96 entityContainer->addEntity(new RS_Line(entityContainer,
97 RS_LineData(e1, e12)));
98 entityContainer->addEntity(new RS_Line(entityContainer,
99 RS_LineData(e12, e2)));
100 entityContainer->addEntity(new RS_Line(entityContainer,
101 RS_LineData(e2, e21)));
102 entityContainer->addEntity(new RS_Line(entityContainer,
103 RS_LineData(e21, e1)));
107 * Creates a polyline from the given array of entities.
108 * No checking if the entities actually fit together.
109 * Currently this is like a group.
113 * RS_Polyline *pl = creation.createPolyline(Vector(25.0, 55.0));<br>
114 * pl->addVertex(Vector(50.0, 75.0));<br>
117 * @param entities array of entities
118 * @param startPoint Start point of the polyline
120 /*RS_Polyline* RS_Creation::createPolyline(const Vector& startPoint) {
121 RS_Polyline* pl = new RS_Polyline(entityContainer,
122 RS_PolylineData(startPoint, Vector(0.0,0.0), 0));
123 entityContainer->addEntity(pl);
128 * Creates an entity parallel to the given entity e through the given
131 * @param coord Coordinate to define the distance / side (typically a
133 * @param number Number of parallels.
134 * @param e Original entity.
136 * @return Pointer to the first created parallel or NULL if no
137 * parallel has been created.
139 RS_Entity * RS_Creation::createParallelThrough(const Vector & coord, int number, RS_Entity * e)
146 if (e->rtti() == RS2::EntityLine)
148 RS_Line * l = (RS_Line *)e;
149 RS_ConstructionLine cl(NULL, RS_ConstructionLineData(l->getStartpoint(),
151 dist = cl.getDistanceToPoint(coord);
155 dist = e->getDistanceToPoint(coord);
158 if (dist < RS_MAXDOUBLE)
159 return createParallel(coord, dist, number, e);
165 * Creates an entity parallel to the given entity e.
166 * Out of the 2 possible parallels, the one closest to
167 * the given coordinate is returned.
168 * Lines, Arcs and Circles can have parallels.
170 * @param coord Coordinate to define which parallel we want (typically a
172 * @param distance Distance of the parallel.
173 * @param number Number of parallels.
174 * @param e Original entity.
176 * @return Pointer to the first created parallel or NULL if no
177 * parallel has been created.
179 RS_Entity* RS_Creation::createParallel(const Vector& coord,
180 double distance, int number,
187 case RS2::EntityLine:
188 return createParallelLine(coord, distance, number, (RS_Line*)e);
192 return createParallelArc(coord, distance, number, (RS_Arc*)e);
195 case RS2::EntityCircle:
196 return createParallelCircle(coord, distance, number, (RS_Circle*)e);
209 * Creates a line parallel to the given line e.
210 * Out of the 2 possible parallels, the one closest to
211 * the given coordinate is returned.
213 * @param coord Coordinate to define which parallel we want (typically a
215 * @param distance Distance of the parallel.
216 * @param number Number of parallels.
217 * @param e Original entity.
219 * @return Pointer to the first created parallel or NULL if no
220 * parallel has been created.
222 RS_Line* RS_Creation::createParallelLine(const Vector& coord,
223 double distance, int number,
230 double ang = e->getAngle1() + M_PI/2.0;
232 RS_LineData parallelData;
235 if (document!=NULL && handleUndo) {
236 document->startUndoCycle();
239 for (int num=1; num<=number; ++num) {
241 // calculate 1st parallel:
242 p1.setPolar(distance*num, ang);
243 p1 += e->getStartpoint();
244 p2.setPolar(distance*num, ang);
245 p2 += e->getEndpoint();
246 RS_Line parallel1(NULL, RS_LineData(p1, p2));
248 // calculate 2nd parallel:
249 p1.setPolar(distance*num, ang+M_PI);
250 p1 += e->getStartpoint();
251 p2.setPolar(distance*num, ang+M_PI);
252 p2 += e->getEndpoint();
253 RS_Line parallel2(NULL, RS_LineData(p1, p2));
255 double dist1 = parallel1.getDistanceToPoint(coord);
256 double dist2 = parallel2.getDistanceToPoint(coord);
257 double minDist = std::min(dist1, dist2);
259 if (minDist<RS_MAXDOUBLE) {
261 parallelData = parallel1.getData();
263 parallelData = parallel2.getData();
267 RS_Line* newLine = new RS_Line(container, parallelData);
268 newLine->setLayerToActive();
269 newLine->setPenToActive();
273 if (container!=NULL) {
274 container->addEntity(newLine);
276 if (document!=NULL && handleUndo) {
277 document->addUndoable(newLine);
278 //document->endUndoCycle();
280 if (graphicView!=NULL) {
281 graphicView->drawEntity(newLine);
286 if (document!=NULL && handleUndo) {
287 document->endUndoCycle();
296 * Creates a arc parallel to the given arc e.
297 * Out of the 2 possible parallels, the one closest to
298 * the given coordinate is returned.
300 * @param coord Coordinate to define which parallel we want (typically a
302 * @param distance Distance of the parallel.
303 * @param number Number of parallels.
304 * @param e Original entity.
306 * @return Pointer to the first created parallel or NULL if no
307 * parallel has been created.
309 RS_Arc* RS_Creation::createParallelArc(const Vector& coord,
310 double distance, int number,
317 RS_ArcData parallelData;
320 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
326 for (int num=1; num<=number; ++num) {
328 // calculate parallel:
330 RS_Arc parallel1(NULL, e->getData());
331 parallel1.setRadius(e->getRadius() + distance*num);
332 if (parallel1.getRadius()<0.0) {
333 parallel1.setRadius(RS_MAXDOUBLE);
337 // calculate 2nd parallel:
338 //RS_Arc parallel2(NULL, e->getData());
339 //parallel2.setRadius(e->getRadius()+distance*num);
341 //double dist1 = parallel1.getDistanceToPoint(coord);
342 //double dist2 = parallel2.getDistanceToPoint(coord);
343 //double minDist = min(dist1, dist2);
345 //if (minDist<RS_MAXDOUBLE) {
348 parallelData = parallel1.getData();
350 // parallelData = parallel2.getData();
353 if (document!=NULL && handleUndo) {
354 document->startUndoCycle();
357 RS_Arc* newArc = new RS_Arc(container, parallelData);
358 newArc->setLayerToActive();
359 newArc->setPenToActive();
363 if (container!=NULL) {
364 container->addEntity(newArc);
366 if (document!=NULL && handleUndo) {
367 document->addUndoable(newArc);
368 document->endUndoCycle();
370 if (graphicView!=NULL) {
371 graphicView->drawEntity(newArc);
382 * Creates a circle parallel to the given circle e.
383 * Out of the 2 possible parallels, the one closest to
384 * the given coordinate is returned.
386 * @param coord Coordinate to define which parallel we want (typically a
388 * @param distance Distance of the parallel.
389 * @param number Number of parallels.
390 * @param e Original entity.
392 * @return Pointer to the first created parallel or NULL if no
393 * parallel has been created.
395 RS_Circle* RS_Creation::createParallelCircle(const Vector& coord,
396 double distance, int number,
403 RS_CircleData parallelData;
404 RS_Circle* ret = NULL;
406 bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
412 for (int num=1; num<=number; ++num) {
414 // calculate parallel:
416 RS_Circle parallel1(NULL, e->getData());
417 parallel1.setRadius(e->getRadius() + distance*num);
418 if (parallel1.getRadius()<0.0) {
419 parallel1.setRadius(RS_MAXDOUBLE);
423 // calculate 2nd parallel:
424 //RS_Circle parallel2(NULL, e->getData());
425 //parallel2.setRadius(e->getRadius()+distance*num);
427 //double dist1 = parallel1.getDistanceToPoint(coord);
428 //double dist2 = parallel2.getDistanceToPoint(coord);
429 //double minDist = min(dist1, dist2);
431 //if (minDist<RS_MAXDOUBLE) {
434 parallelData = parallel1.getData();
436 // parallelData = parallel2.getData();
439 if (document!=NULL && handleUndo) {
440 document->startUndoCycle();
443 RS_Circle* newCircle = new RS_Circle(container, parallelData);
444 newCircle->setLayerToActive();
445 newCircle->setPenToActive();
449 if (container!=NULL) {
450 container->addEntity(newCircle);
452 if (document!=NULL && handleUndo) {
453 document->addUndoable(newCircle);
454 document->endUndoCycle();
456 if (graphicView!=NULL) {
457 graphicView->drawEntity(newCircle);
467 * Creates a bisecting line of the angle between the entities
468 * e1 and e2. Out of the 4 possible bisectors, the one closest to
469 * the given coordinate is returned.
471 * @param coord Coordinate to define which bisector we want (typically a
473 * @param length Length of the bisecting line.
474 * @param num Number of bisectors
475 * @param l1 First line.
476 * @param l2 Second line.
478 * @return Pointer to the first bisector created or NULL if no bisectors
481 RS_Line* RS_Creation::createBisector(const Vector& coord1,
482 const Vector& coord2,
490 // check given entities:
491 if (l1==NULL || l2==NULL ||
492 l1->rtti()!=RS2::EntityLine || l2->rtti()!=RS2::EntityLine) {
496 // intersection between entities:
497 sol = RS_Information::getIntersection(l1, l2, false);
498 Vector inters = sol.get(0);
499 if (inters.valid==false) {
503 double angle1 = inters.angleTo(l1->getNearestPointOnEntity(coord1));
504 double angle2 = inters.angleTo(l2->getNearestPointOnEntity(coord2));
505 double angleDiff = RS_Math::getAngleDifference(angle1, angle2);
506 if (angleDiff>M_PI) {
507 angleDiff = angleDiff - 2*M_PI;
511 if (document!=NULL && handleUndo) {
512 document->startUndoCycle();
515 for (int n=1; n<=num; ++n) {
517 double angle = angle1 +
518 (angleDiff / (num+1) * n);
524 v.setPolar(length, angle);
525 d = RS_LineData(inters, inters + v);
527 RS_Line* newLine = new RS_Line(container, d);
528 if (container!=NULL) {
529 newLine->setLayerToActive();
530 newLine->setPenToActive();
531 container->addEntity(newLine);
533 if (document!=NULL && handleUndo) {
534 document->addUndoable(newLine);
536 if (graphicView!=NULL) {
537 graphicView->drawEntity(newLine);
543 if (document!=NULL && handleUndo) {
544 document->endUndoCycle();
553 * Creates a tangent between a given point and a circle or arc.
554 * Out of the 2 possible tangents, the one closest to
555 * the given coordinate is returned.
557 * @param coord Coordinate to define which tangent we want (typically a
559 * @param point Point.
560 * @param circle Circle, arc or ellipse entity.
562 RS_Line* RS_Creation::createTangent1(const Vector& coord,
568 // check given entities:
569 if (circle==NULL || !point.valid ||
570 (circle->rtti()!=RS2::EntityArc && circle->rtti()!=RS2::EntityCircle
571 && circle->rtti()!=RS2::EntityEllipse)) {
576 if (circle->rtti()==RS2::EntityCircle) {
577 circleCenter = ((RS_Circle*)circle)->getCenter();
578 } else if (circle->rtti()==RS2::EntityArc) {
579 circleCenter = ((RS_Arc*)circle)->getCenter();
580 } else if (circle->rtti()==RS2::EntityEllipse) {
581 circleCenter = ((RS_Ellipse*)circle)->getCenter();
584 // the two tangent points:
587 // calculate tangent points for arcs / circles:
588 if (circle->rtti()!=RS2::EntityEllipse) {
589 // create temp. thales circle:
590 Vector tCenter = (point + circleCenter)/2.0;
591 double tRadius = point.distanceTo(tCenter);
593 RS_Circle tmp(NULL, RS_CircleData(tCenter, tRadius));
595 // get the two intersection points which are the tangent points:
596 sol = RS_Information::getIntersection(&tmp, circle, false);
599 // calculate tangent points for ellipses:
601 RS_Ellipse* el = (RS_Ellipse*)circle;
603 //sol.set(0, circleCenter);
604 //sol.set(1, circleCenter);
607 double a = el->getMajorRadius(); // the length of the major axis / 2
608 double b = el->getMinorRadius(); // the length of the minor axis / 2
610 // rotate and move point:
611 Vector point2 = point;
612 point2.move(-el->getCenter());
613 point2.rotate(-el->getAngle());
615 double xp = point2.x; // coordinates of the given point
616 double yp = point2.y;
618 double xt1; // Tangent point 1
620 double xt2; // Tangent point 2
625 double d = a2 / b2 * yp / xp;
627 double af = b2 * d * d + a2;
628 double bf = -b2 * d * e * 2.0;
629 double cf = b2 * e * e - a2 * b2;
630 double t = sqrt(bf * bf - af * cf * 4.0);
631 yt1 = (t - bf) / (af * 2.0);
633 yt2 = (-t - bf) / (af * 2.0);
636 Vector s1 = Vector(xt1, yt1);
637 Vector s2 = Vector(xt2, yt2);
639 s1.rotate(el->getAngle());
640 s1.move(el->getCenter());
642 s2.rotate(el->getAngle());
643 s2.move(el->getCenter());
651 if (!sol.get(0).valid || !sol.get(1).valid) {
655 // create all possible tangents:
660 d = RS_LineData(sol.get(0), point);
661 poss[0] = new RS_Line(NULL, d);
662 d = RS_LineData(sol.get(1), point);
663 poss[1] = new RS_Line(NULL, d);
665 // find closest tangent:
666 double minDist = RS_MAXDOUBLE;
669 for (int i=0; i<2; ++i) {
670 dist = poss[i]->getDistanceToPoint(coord);
677 // create the closest tangent:
679 RS_LineData d = poss[idx]->getData();
681 for (int i=0; i<2; ++i) {
685 if (document!=NULL && handleUndo) {
686 document->startUndoCycle();
689 ret = new RS_Line(container, d);
690 ret->setLayerToActive();
691 ret->setPenToActive();
692 if (container!=NULL) {
693 container->addEntity(ret);
695 if (document!=NULL && handleUndo) {
696 document->addUndoable(ret);
697 document->endUndoCycle();
699 if (graphicView!=NULL) {
700 graphicView->drawEntity(ret);
712 * Creates a tangent between two circles or arcs.
713 * Out of the 4 possible tangents, the one closest to
714 * the given coordinate is returned.
716 * @param coord Coordinate to define which tangent we want (typically a
718 * @param circle1 1st circle or arc entity.
719 * @param circle2 2nd circle or arc entity.
721 RS_Line* RS_Creation::createTangent2(const Vector& coord,
723 RS_Entity* circle2) {
725 Vector circleCenter1;
726 Vector circleCenter2;
727 double circleRadius1 = 0.0;
728 double circleRadius2 = 0.0;
730 // check given entities:
731 if (circle1==NULL || circle2==NULL ||
732 (circle1->rtti()!=RS2::EntityArc &&
733 circle1->rtti()!=RS2::EntityCircle) ||
734 (circle2->rtti()!=RS2::EntityArc &&
735 circle2->rtti()!=RS2::EntityCircle) ) {
740 if (circle1->rtti()==RS2::EntityCircle) {
741 circleCenter1 = ((RS_Circle*)circle1)->getCenter();
742 circleRadius1 = ((RS_Circle*)circle1)->getRadius();
743 } else if (circle1->rtti()==RS2::EntityArc) {
744 circleCenter1 = ((RS_Arc*)circle1)->getCenter();
745 circleRadius1 = ((RS_Arc*)circle1)->getRadius();
748 if (circle2->rtti()==RS2::EntityCircle) {
749 circleCenter2 = ((RS_Circle*)circle2)->getCenter();
750 circleRadius2 = ((RS_Circle*)circle2)->getRadius();
751 } else if (circle2->rtti()==RS2::EntityArc) {
752 circleCenter2 = ((RS_Arc*)circle2)->getCenter();
753 circleRadius2 = ((RS_Arc*)circle2)->getRadius();
756 // create all possible tangents:
758 for (int i=0; i<4; ++i) {
764 double angle1 = circleCenter1.angleTo(circleCenter2);
765 double dist1 = circleCenter1.distanceTo(circleCenter2);
769 double dist2 = circleRadius2 - circleRadius1;
771 double angle2 = asin(dist2/dist1);
772 double angt1 = angle1 + angle2 + M_PI/2.0;
773 double angt2 = angle1 - angle2 - M_PI/2.0;
777 offs1.setPolar(circleRadius1, angt1);
778 offs2.setPolar(circleRadius2, angt1);
780 d = RS_LineData(circleCenter1 + offs1,
781 circleCenter2 + offs2);
782 poss[0] = new RS_Line(NULL, d);
785 offs1.setPolar(circleRadius1, angt2);
786 offs2.setPolar(circleRadius2, angt2);
788 d = RS_LineData(circleCenter1 + offs1,
789 circleCenter2 + offs2);
790 poss[1] = new RS_Line(NULL, d);
794 double dist3 = circleRadius2 + circleRadius1;
796 double angle3 = asin(dist3/dist1);
797 double angt3 = angle1 + angle3 + M_PI/2.0;
798 double angt4 = angle1 - angle3 - M_PI/2.0;
802 offs1.setPolar(circleRadius1, angt3);
803 offs2.setPolar(circleRadius2, angt3);
805 d = RS_LineData(circleCenter1 - offs1,
806 circleCenter2 + offs2);
807 poss[2] = new RS_Line(NULL, d);
810 offs1.setPolar(circleRadius1, angt4);
811 offs2.setPolar(circleRadius2, angt4);
813 d = RS_LineData(circleCenter1 - offs1,
814 circleCenter2 + offs2);
815 poss[3] = new RS_Line(NULL, d);
820 // find closest tangent:
821 double minDist = RS_MAXDOUBLE;
824 for (int i=0; i<4; ++i) {
826 dist = poss[i]->getDistanceToPoint(coord);
835 RS_LineData d = poss[idx]->getData();
836 for (int i=0; i<4; ++i) {
842 if (document!=NULL && handleUndo) {
843 document->startUndoCycle();
846 ret = new RS_Line(container, d);
847 ret->setLayerToActive();
848 ret->setPenToActive();
849 if (container!=NULL) {
850 container->addEntity(ret);
852 if (document!=NULL && handleUndo) {
853 document->addUndoable(ret);
854 document->endUndoCycle();
856 if (graphicView!=NULL) {
857 graphicView->drawEntity(ret);
868 * Creates a line with a relative angle to the given entity.
870 * @param coord Coordinate to define the point where the line should end.
871 * (typically a mouse coordinate).
872 * @param entity Pointer to basis entity. The angle is relative to the
873 * angle of this entity.
874 * @param angle Angle of the line relative to the angle of the basis entity.
875 * @param length Length of the line we're creating.
877 RS_Line* RS_Creation::createLineRelAngle(const Vector& coord,
882 // check given entity / coord:
883 if (entity==NULL || !coord.valid ||
884 (entity->rtti()!=RS2::EntityArc && entity->rtti()!=RS2::EntityCircle
885 && entity->rtti()!=RS2::EntityLine)) {
892 switch (entity->rtti()) {
893 case RS2::EntityLine:
894 a1 = ((RS_Line*)entity)->getAngle1();
897 a1 = ((RS_Arc*)entity)->getCenter().angleTo(coord) + M_PI/2.0;
899 case RS2::EntityCircle:
900 a1 = ((RS_Circle*)entity)->getCenter().angleTo(coord);
910 v1.setPolar(length, a1);
911 //RS_ConstructionLineData(coord-v1, coord+v1);
912 RS_LineData d(coord-v1, coord+v1);
915 if (document!=NULL && handleUndo) {
916 document->startUndoCycle();
919 ret = new RS_Line(container, d);
920 ret->setLayerToActive();
921 ret->setPenToActive();
922 if (container!=NULL) {
923 container->addEntity(ret);
925 if (document!=NULL && handleUndo) {
926 document->addUndoable(ret);
927 document->endUndoCycle();
929 if (graphicView!=NULL) {
930 graphicView->drawEntity(ret);
938 * Creates a polygon with 'number' edges.
940 * @param center Center of the polygon.
941 * @param corner The first corner of the polygon
942 * @param number Number of edges / corners.
944 RS_Line* RS_Creation::createPolygon(const Vector& center,
945 const Vector& corner,
948 // check given coords / number:
949 if (!center.valid || !corner.valid || number<3) {
955 if (document!=NULL && handleUndo) {
956 document->startUndoCycle();
963 for (int n=1; n<=number; ++n) {
965 c2 = c2.rotate(center, (M_PI*2)/number);
967 line = new RS_Line(container, RS_LineData(c1, c2));
968 line->setLayerToActive();
969 line->setPenToActive();
975 if (container!=NULL) {
976 container->addEntity(line);
978 if (document!=NULL && handleUndo) {
979 document->addUndoable(line);
981 if (graphicView!=NULL) {
982 graphicView->drawEntity(line);
986 if (document!=NULL && handleUndo) {
987 document->endUndoCycle();
996 * Creates a polygon with 'number' edges.
998 * @param corner1 The first corner of the polygon.
999 * @param corner2 The second corner of the polygon.
1000 * @param number Number of edges / corners.
1002 RS_Line* RS_Creation::createPolygon2(const Vector& corner1,
1003 const Vector& corner2,
1006 // check given coords / number:
1007 if (!corner1.valid || !corner2.valid || number<3) {
1011 RS_Line* ret = NULL;
1013 if (document!=NULL && handleUndo) {
1014 document->startUndoCycle();
1017 double len = corner1.distanceTo(corner2);
1018 double ang1 = corner1.angleTo(corner2);
1022 Vector c2 = corner1;
1026 for (int n=1; n<=number; ++n) {
1028 edge.setPolar(len, ang);
1031 line = new RS_Line(container, RS_LineData(c1, c2));
1032 line->setLayerToActive();
1033 line->setPenToActive();
1039 if (container!=NULL) {
1040 container->addEntity(line);
1042 if (document!=NULL && handleUndo) {
1043 document->addUndoable(line);
1045 if (graphicView!=NULL) {
1046 graphicView->drawEntity(line);
1049 // more accurate than incrementing the angle:
1050 ang = ang1 + (2*M_PI)/number*n;
1053 if (document!=NULL && handleUndo) {
1054 document->endUndoCycle();
1061 * Creates an insert with the given data.
1063 * @param data Insert data (position, block name, ..)
1065 RS_Insert* RS_Creation::createInsert(RS_InsertData & data)
1067 RS_DEBUG->print("RS_Creation::createInsert");
1069 if (document != NULL && handleUndo)
1070 document->startUndoCycle();
1072 RS_Insert * ins = new RS_Insert(container, data);
1073 // inserts are also on layers
1074 ins->setLayerToActive();
1075 ins->setPenToActive();
1077 if (container != NULL)
1078 container->addEntity(ins);
1080 if (document != NULL && handleUndo)
1082 document->addUndoable(ins);
1083 document->endUndoCycle();
1086 if (graphicView != NULL)
1087 graphicView->drawEntity(ins);
1089 RS_DEBUG->print("RS_Creation::createInsert: OK");
1095 * Creates an image with the given data.
1097 RS_Image* RS_Creation::createImage(RS_ImageData& data) {
1099 if (document!=NULL && handleUndo) {
1100 document->startUndoCycle();
1103 RS_Image* img = new RS_Image(container, data);
1104 img->setLayerToActive();
1105 img->setPenToActive();
1108 if (container!=NULL) {
1109 container->addEntity(img);
1111 if (document!=NULL && handleUndo) {
1112 document->addUndoable(img);
1113 document->endUndoCycle();
1115 if (graphicView!=NULL) {
1116 graphicView->drawEntity(img);
1123 * Creates a new block from the currently selected entitiies.
1125 * @param referencePoint Reference point for the block.
1126 * @param name Block name
1127 * @param remove true: remove existing entities, false: don't touch entities
1129 RS_Block * RS_Creation::createBlock(const RS_BlockData & data,
1130 const Vector & referencePoint, const bool remove)
1132 // start undo cycle for the container if we're deleting the existing entities
1133 if (remove && document!=NULL) {
1134 document->startUndoCycle();
1138 new RS_Block(container,
1139 RS_BlockData(data.name, data.basePoint, data.frozen));
1141 // copy entities into a block
1142 for(RS_Entity * e=container->firstEntity(); e!=NULL; e=container->nextEntity())
1144 //for (uint i=0; i<container->count(); ++i) {
1145 //RS_Entity* e = container->entityAt(i);
1147 if (e != NULL && e->isSelected())
1149 // delete / redraw entity in graphic view:
1152 if (graphicView != NULL)
1153 graphicView->deleteEntity(e);
1155 e->setSelected(false);
1159 if (graphicView != NULL)
1160 graphicView->deleteEntity(e);
1162 e->setSelected(false);
1164 if (graphicView != NULL)
1165 graphicView->drawEntity(e);
1168 // add entity to block:
1169 RS_Entity * c = e->clone();
1170 c->move(-referencePoint);
1171 block->addEntity(c);
1175 //container->removeEntity(e);
1177 e->changeUndoState();
1179 if (document != NULL)
1180 document->addUndoable(e);
1185 if (remove && document != NULL)
1186 document->endUndoCycle();
1188 if (graphic != NULL)
1189 graphic->addBlock(block);
1195 * Inserts a library item from the given path into the drawing.
1197 RS_Insert * RS_Creation::createLibraryInsert(RS_LibraryInsertData & data)
1199 RS_DEBUG->print("RS_Creation::createLibraryInsert");
1202 if (!g.open(data.file, RS2::FormatUnknown))
1204 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Creation::createLibraryInsert: Cannot open file: %s");
1209 if (graphic != NULL)
1211 double uf = RS_Units::convert(1.0, g.getUnit(), graphic->getUnit());
1212 g.scale(Vector(0.0, 0.0), Vector(uf, uf));
1215 //g.scale(Vector(data.factor, data.factor));
1216 //g.rotate(data.angle);
1218 // QString s = QFileInfo(data.file).baseName(true);
1219 QString s = QFileInfo(data.file).completeBaseName();
1221 RS_Modification m(*container, graphicView);
1222 m.paste(RS_PasteData(data.insertionPoint, data.factor, data.angle, true, s), &g);
1224 RS_DEBUG->print("RS_Creation::createLibraryInsert: OK");