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