1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 
27 #ifndef RS_MODIFICATION_H
28 #define RS_MODIFICATION_H
29 
30 #include "rs_vector.h"
31 #include "rs_pen.h"
32 #include <QHash>
33 
34 class RS_AtomicEntity;
35 class RS_Entity;
36 class RS_EntityContainer;
37 class RS_MText;
38 class RS_Text;
39 class RS_Polyline;
40 class RS_Document;
41 class RS_Graphic;
42 class RS_GraphicView;
43 
44 /**
45  * Holds the data needed for move modifications.
46  */
47 class RS_MoveData {
48 public:
49     int number;
50     bool useCurrentAttributes;
51     bool useCurrentLayer;
52     RS_Vector offset;
53 };
54 
55 
56 /**
57  * Holds the data needed for offset modifications.
58  */
59 class RS_OffsetData {
60 public:
61     int number;
62     bool useCurrentAttributes;
63     bool useCurrentLayer;
64     RS_Vector coord;
65     double distance;
66 };
67 
68 /**
69  * Holds the data needed for rotation modifications.
70  */
71 class RS_RotateData {
72 public:
73     int number;
74     bool useCurrentAttributes;
75     bool useCurrentLayer;
76     RS_Vector center;
77     double angle;
78 };
79 
80 
81 
82 /**
83  * Holds the data needed for scale modifications.
84  */
85 class RS_ScaleData {
86 public:
87     int number;
88     bool useCurrentAttributes;
89     bool useCurrentLayer;
90     RS_Vector referencePoint;
91     RS_Vector factor;
92 };
93 
94 
95 /**
96  * Holds the data needed for mirror modifications.
97  */
98 class RS_MirrorData {
99 public:
100     bool copy;
101     bool useCurrentAttributes;
102     bool useCurrentLayer;
103     RS_Vector axisPoint1;
104     RS_Vector axisPoint2;
105 };
106 
107 
108 /**
109  * Holds the data needed for move/rotate modifications.
110  */
111 class RS_MoveRotateData {
112 public:
113     int number;
114     bool useCurrentAttributes;
115     bool useCurrentLayer;
116     RS_Vector referencePoint;
117         RS_Vector offset;
118         double angle;
119 };
120 
121 
122 
123 /**
124  * Holds the data needed for rotation around two centers modifications.
125  */
126 class RS_Rotate2Data {
127 public:
128     int number;
129     bool useCurrentAttributes;
130     bool useCurrentLayer;
131     RS_Vector center1;
132     RS_Vector center2;
133     double angle1;
134     double angle2;
135 };
136 
137 
138 
139 /**
140  * Holds the data needed for beveling modifications.
141  */
142 class RS_BevelData {
143 public:
144         double length1;
145         double length2;
146         bool trim;
147 };
148 
149 
150 
151 
152 /**
153  * Holds the data needed for rounding modifications.
154  */
155 class RS_RoundData {
156 public:
157         double radius;
158         bool trim;
159 };
160 
161 
162 /**
163  * Holds the data needed for moving reference points.
164  */
165 class RS_MoveRefData {
166 public:
167         RS_Vector ref;
168     RS_Vector offset;
169 };
170 
171 
172 
173 /**
174  * Holds the data needed for changing attributes.
175  */
176 class RS_AttributesData {
177 public:
178         QString layer;
179         RS_Pen pen;
180         bool changeLayer;
181         bool changeColor;
182         bool changeLineType;
183         bool changeWidth;
184         bool applyBlockDeep;
185 };
186 
187 
188 /**
189  * Holds the data needed for pasting.
190  */
191 class RS_PasteData {
192 public:
193         RS_PasteData(RS_Vector insertionPoint,
194                 double factor,
195                 double angle,
196                 bool asInsert,
197 				const QString& blockName);
198 
199         //! Insertion point.
200         RS_Vector insertionPoint;
201         //! Scale factor.
202         double factor;
203         //! Rotation angle.
204         double angle;
205         //! Paste as an insert rather than individual entities.
206         bool asInsert;
207         //! Name of the block to create or an empty string to assign a new auto name.
208         QString blockName;
209 };
210 
211 
212 /**
213  * API Class for manipulating entities.
214  * There's no interaction handled in this class.
215  *
216  * All modifications can be undone / redone if the container
217  * is a RS_Graphic.
218  *
219  * This class is connected to an entity container and
220  * can be connected to a graphic view.
221  *
222  * @author Andrew Mustun
223  */
224 class RS_Modification {
225 public:
226 	RS_Modification()=delete;
227     RS_Modification(RS_EntityContainer& entityContainer,
228                     RS_GraphicView* graphicView=NULL,
229                                         bool handleUndo=true);
230 
231 	void remove();
232 	void revertDirection();
233 	bool changeAttributes(RS_AttributesData& data);
234     bool changeAttributes(RS_AttributesData& data, RS_EntityContainer* container);
235 
236         void copy(const RS_Vector& ref, const bool cut);
237 private:
238         void copyEntity(RS_Entity* e, const RS_Vector& ref, const bool cut);
239         void copyLayers(RS_Entity* e);
240         void copyBlocks(RS_Entity* e);
241         bool pasteLayers(RS_Graphic* source);
242         bool pasteContainer(RS_Entity* entity, RS_EntityContainer* container, QHash<QString, QString>blocksDict, RS_Vector insertionPoint);
243         bool pasteEntity(RS_Entity* entity, RS_EntityContainer* container);
244 public:
245         void paste(const RS_PasteData& data, RS_Graphic* source=NULL);
246 
247     bool move(RS_MoveData& data);
248     bool rotate(RS_RotateData& data);
249     bool scale(RS_ScaleData& data);
250     bool mirror(RS_MirrorData& data);
251     bool moveRotate(RS_MoveRotateData& data);
252     bool rotate2(RS_Rotate2Data& data);
253 
254     bool trim(const RS_Vector& trimCoord, RS_AtomicEntity* trimEntity,
255               const RS_Vector& limitCoord, RS_Entity* limitEntity,
256               bool both);
257     bool trimAmount(const RS_Vector& trimCoord, RS_AtomicEntity* trimEntity,
258                     double dist);
259     bool offset(const RS_OffsetData& data);
260     bool cut(const RS_Vector& cutCoord, RS_AtomicEntity* cutEntity);
261     bool stretch(const RS_Vector& firstCorner,
262                                 const RS_Vector& secondCorner,
263                                 const RS_Vector& offset);
264 
265     bool bevel(const RS_Vector& coord1, RS_AtomicEntity* entity1,
266               const RS_Vector& coord2, RS_AtomicEntity* entity2,
267                           RS_BevelData& data);
268     bool round(const RS_Vector& coord,
269                const RS_Vector& coord1,
270                    RS_AtomicEntity* entity1,
271                const RS_Vector& coord2,
272                RS_AtomicEntity* entity2,
273                            RS_RoundData& data);
274 
275         bool explode(const bool remove = true);
276 		bool explodeTextIntoLetters();
277         bool moveRef(RS_MoveRefData& data);
278 
279     bool splitPolyline(RS_Polyline& polyline,
280                        RS_Entity& e1, RS_Vector v1,
281                        RS_Entity& e2, RS_Vector v2,
282                        RS_Polyline** polyline1,
283                        RS_Polyline** polyline2) const;
284         RS_Polyline* addPolylineNode(RS_Polyline& polyline,
285                      const RS_AtomicEntity& segment,
286                                  const RS_Vector& node);
287         RS_Polyline* deletePolylineNode(RS_Polyline& polyline,
288                                 const RS_Vector& node);
289         RS_Polyline* deletePolylineNodesBetween(RS_Polyline& polyline, RS_AtomicEntity& segment,
290                                 const RS_Vector& node1, const RS_Vector& node2);
291         RS_Polyline* polylineTrim(RS_Polyline& polyline,
292                                 RS_AtomicEntity& segment1,
293                                 RS_AtomicEntity& segment2);
294 
295 private:
296     void deselectOriginals(bool remove);
297 	void addNewEntities(std::vector<RS_Entity*>& addList);
298 	bool explodeTextIntoLetters(RS_MText* text, std::vector<RS_Entity*>& addList);
299 	bool explodeTextIntoLetters(RS_Text* text, std::vector<RS_Entity*>& addList);
300 
301 protected:
302     RS_EntityContainer* container;
303     RS_Graphic* graphic;
304     RS_Document* document;
305     RS_GraphicView* graphicView;
306         bool handleUndo;
307 };
308 
309 #endif
310