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 
28 #ifndef RS_ENTITYCONTAINER_H
29 #define RS_ENTITYCONTAINER_H
30 
31 #include <vector>
32 #include "rs_entity.h"
33 
34 /**
35  * Class representing a tree of entities.
36  * Typical entity containers are graphics, polylines, groups, texts, ...)
37  *
38  * @author Andrew Mustun
39  */
40 class RS_EntityContainer : public RS_Entity {
41 	typedef RS_Entity * value_type;
42 
43 public:
44 
45 	RS_EntityContainer(RS_EntityContainer* parent=nullptr, bool owner=true);
46     //RS_EntityContainer(const RS_EntityContainer& ec);
47 	~RS_EntityContainer() override;
48 
49 	RS_Entity* clone() const override;
50 	virtual void detach();
51 
52     /** @return RS2::EntityContainer */
rtti()53 	RS2::EntityType rtti() const override{
54         return RS2::EntityContainer;
55     }
56 
57 	void reparent(RS_EntityContainer* parent) override;
58 
59     /**
60      * @return true: because entities made from this class
61 	 *         and subclasses are containers for other entities.
62      */
isContainer()63 	bool isContainer() const override{
64         return true;
65     }
66 
67     /**
68      * @return false: because entities made from this class
69      *         and subclasses are containers for other entities.
70      */
isAtomic()71 	bool isAtomic() const override{
72                 return false;
73         }
74 
75 	double getLength() const override;
76 
77 	void setVisible(bool v) override;
78 
79 	bool setSelected(bool select=true) override;
80 	bool toggleSelected() override;
81 
82 	virtual void selectWindow(RS_Vector v1, RS_Vector v2,
83 				bool select=true, bool cross=false);
84 
85     virtual void addEntity(RS_Entity* entity);
86     virtual void appendEntity(RS_Entity* entity);
87     virtual void prependEntity(RS_Entity* entity);
88 	virtual void moveEntity(int index, QList<RS_Entity *>& entList);
89     virtual void insertEntity(int index, RS_Entity* entity);
90     virtual bool removeEntity(RS_Entity* entity);
91 
92 	//!
93 	//! \brief addRectangle add four lines to form a rectangle by
94 	//! the diagonal vertices v0,v1
95 	//! \param v0,v1 diagonal vertices of the rectangle
96 	//!
97 	void addRectangle(RS_Vector const& v0, RS_Vector const& v1);
98 
99     virtual RS_Entity* firstEntity(RS2::ResolveLevel level=RS2::ResolveNone);
100     virtual RS_Entity* lastEntity(RS2::ResolveLevel level=RS2::ResolveNone);
101     virtual RS_Entity* nextEntity(RS2::ResolveLevel level=RS2::ResolveNone);
102     virtual RS_Entity* prevEntity(RS2::ResolveLevel level=RS2::ResolveNone);
103     virtual RS_Entity* entityAt(int index);
104 	virtual void setEntityAt(int index,RS_Entity* en);
105 //RLZ unused	virtual int entityAt();
106 		virtual int findEntity(RS_Entity const* const entity);
107     virtual void clear();
108 
109     //virtual unsigned long int count() {
110         //	return count(false);
111         //}
isEmpty()112 	virtual bool isEmpty() const{
113         return count()==0;
114 	}
115 	unsigned count() const override;
116 	unsigned countDeep() const override;
117 	//virtual unsigned long int countLayerEntities(RS_Layer* layer);
118 	/** \brief countSelected number of selected
119 	* @param deep count sub-containers, if true
120 	* @param types if is not empty, only counts by types listed
121 	*/
122 	virtual unsigned countSelected(bool deep=true, std::initializer_list<RS2::EntityType> const& types = {});
123     virtual double totalSelectedLength();
124 
125     /**
126      * Enables / disables automatic update of borders on entity removals
127      * and additions. By default this is turned on.
128      */
setAutoUpdateBorders(bool enable)129     virtual void setAutoUpdateBorders(bool enable) {
130         autoUpdateBorders = enable;
131     }
132     virtual void adjustBorders(RS_Entity* entity);
133 	void calculateBorders() override;
134 	void forcedCalculateBorders();
135 	void updateDimensions( bool autoText=true);
136     virtual void updateInserts();
137     virtual void updateSplines();
138 	void update() override;
139 	virtual void renameInserts(const QString& oldName,
140 							   const QString& newName);
141 
142 	RS_Vector getNearestEndpoint(const RS_Vector& coord,
143 										 double* dist = nullptr)const override;
144 	RS_Vector getNearestEndpoint(const RS_Vector& coord,
145 										 double* dist, RS_Entity** pEntity ) const;
146 
147     RS_Entity* getNearestEntity(const RS_Vector& point,
148 								double* dist = nullptr,
149 								RS2::ResolveLevel level=RS2::ResolveAll) const;
150 
151 	RS_Vector getNearestPointOnEntity(const RS_Vector& coord,
152             bool onEntity = true,
153 						double* dist = nullptr,
154 			RS_Entity** entity=nullptr)const override;
155 
156 	RS_Vector getNearestCenter(const RS_Vector& coord,
157 									   double* dist = nullptr)const override;
158 	RS_Vector getNearestMiddle(const RS_Vector& coord,
159 									   double* dist = nullptr,
160                                        int middlePoints = 1
161 									   )const override;
162 	RS_Vector getNearestDist(double distance,
163                                      const RS_Vector& coord,
164 									 double* dist = nullptr) const override;
165 	RS_Vector getNearestIntersection(const RS_Vector& coord,
166 			double* dist = nullptr);
167     RS_Vector getNearestVirtualIntersection(const RS_Vector& coord,
168                                             const double& angle,
169                                             double* dist);
170 	RS_Vector getNearestRef(const RS_Vector& coord,
171 									 double* dist = nullptr) const override;
172 	RS_Vector getNearestSelectedRef(const RS_Vector& coord,
173 									 double* dist = nullptr) const override;
174 
175 	double getDistanceToPoint(const RS_Vector& coord,
176                                       RS_Entity** entity,
177                                       RS2::ResolveLevel level=RS2::ResolveNone,
178 									  double solidDist = RS_MAXDOUBLE) const override;
179 
180     virtual bool optimizeContours();
181 
182 	bool hasEndpointsWithinWindow(const RS_Vector& v1, const RS_Vector& v2) override;
183 
184 	void move(const RS_Vector& offset) override;
185 	void rotate(const RS_Vector& center, const double& angle) override;
186 	void rotate(const RS_Vector& center, const RS_Vector& angleVector) override;
187 	void scale(const RS_Vector& center, const RS_Vector& factor) override;
188 	void mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2a) override;
189 
190 	void stretch(const RS_Vector& firstCorner,
191                          const RS_Vector& secondCorner,
192 						 const RS_Vector& offset) override;
193 	void moveRef(const RS_Vector& ref, const RS_Vector& offset) override;
194 	void moveSelectedRef(const RS_Vector& ref, const RS_Vector& offset) override;
195 	void revertDirection() override;
196 
197 
198 	void draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) override;
199 
200     friend std::ostream& operator << (std::ostream& os, RS_EntityContainer& ec);
201 
isOwner()202 	bool isOwner() const {return autoDelete;}
setOwner(bool owner)203     void setOwner(bool owner) {autoDelete=owner;}
204     /**
205      * @brief areaLineIntegral, line integral for contour area calculation by Green's Theorem
206      * Contour Area =\oint x dy
207      * @return line integral \oint x dy along the entity
208      * returns absolute value
209      */
210     virtual double areaLineIntegral() const override;
211     /**
212 	 * @brief ignoreForModification ignore this entity for entity catch for certain actions
213      * like catching circles to create tangent circles
214      * @return, true, indicate this entity container should be ignored
215      */
216     bool ignoredOnModification() const;
217 
218 	/**
219 	 * @brief begin/end to support range based loop
220 	 * @return iterator
221 	 */
222 	QList<RS_Entity *>::const_iterator begin() const;
223 	QList<RS_Entity *>::const_iterator end() const;
224 	QList<RS_Entity *>::iterator begin() ;
225 	QList<RS_Entity *>::iterator end() ;
226 	//! \{
227 	//! first and last without resolving into children, assume the container is
228 	//! not empty
229 	RS_Entity* last() const;
230 	RS_Entity* first() const;
231 	//! \}
232 
233     const QList<RS_Entity*>& getEntityList();
234 
235 protected:
236 
237     /** entities in the container */
238     QList<RS_Entity *> entities;
239 
240     /** sub container used only temporarily for iteration. */
241     RS_EntityContainer* subContainer;
242 
243     /**
244      * Automatically update the borders of the container when entities
245      * are added or removed.
246      */
247     static bool autoUpdateBorders;
248 
249 private:
250 	/**
251 	 * @brief ignoredSnap whether snapping is ignored
252 	 * @return true when entity of this container won't be considered for snapping points
253 	 */
254 	bool ignoredSnap() const;
255     int entIdx;
256     bool autoDelete;
257 };
258 
259 #endif
260