84 |
85 |
85 Model(class DocumentManager* manager); |
86 Model(class DocumentManager* manager); |
86 Model(const Model& other) = delete; |
87 Model(const Model& other) = delete; |
87 ~Model(); |
88 ~Model(); |
88 |
89 |
89 void addObject(LDObject* object); |
90 void insertCopy(int position, LDObject* object); |
90 virtual void insertObject(int position, LDObject* object); |
91 void insertFromArchive(int row, Serializer::Archive& archive); |
91 virtual bool swapObjects(LDObject* one, LDObject* other); |
92 bool swapObjects(LDObject* one, LDObject* other); |
92 virtual bool setObjectAt(int idx, LDObject* obj); |
93 bool setObjectAt(int idx, Serializer::Archive& archive); |
93 template<typename T, typename... Args> T* emplace(Args&& ...args); |
94 template<typename T, typename... Args> T* emplace(Args&& ...args); |
94 template<typename T, typename... Args> T* emplaceAt(int position, Args&& ...args); |
95 template<typename T, typename... Args> T* emplaceAt(int position, Args&& ...args); |
95 template<typename T, typename... Args> T* emplaceReplacement(LDObject* object, Args&& ...args); |
|
96 template<typename T, typename... Args> T* emplaceReplacementAt(int position, Args&& ...args); |
|
97 void removeAt(int position); |
96 void removeAt(int position); |
98 void removeAt(const QModelIndex& index); |
97 void removeAt(const QModelIndex& index); |
99 void remove(LDObject* object); |
98 void remove(LDObject* object); |
100 void replace(LDObject *object, Model& model); |
99 void replace(LDObject *object, Model& model); |
101 void clear(); |
100 void clear(); |
117 LDObject* lookup(const QModelIndex& index) const; |
116 LDObject* lookup(const QModelIndex& index) const; |
118 QModelIndex indexFromId(qint32 id) const; |
117 QModelIndex indexFromId(qint32 id) const; |
119 |
118 |
120 int rowCount(const QModelIndex& parent) const override; |
119 int rowCount(const QModelIndex& parent) const override; |
121 QVariant data(const QModelIndex& index, int role) const override; |
120 QVariant data(const QModelIndex& index, int role) const override; |
122 // bool removeRows(int row, int count, const QModelIndex& ) override; |
|
123 |
121 |
124 signals: |
122 signals: |
125 void objectAdded(LDObject* object); |
123 void objectAdded(const QModelIndex& object); |
126 void aboutToRemoveObject(LDObject* object); |
124 void aboutToRemoveObject(const QModelIndex& index); |
127 void objectModified(LDObject* object); |
125 void objectModified(LDObject* object); |
|
126 void objectsSwapped(const QModelIndex& index_1, const QModelIndex& index_2); |
128 |
127 |
129 protected: |
128 protected: |
130 template<typename T, typename... Args> T* constructObject(Args&& ...args); |
129 template<typename T, typename... Args> T* constructObject(Args&& ...args); |
131 void withdraw(LDObject* object); |
|
132 virtual LDObject* withdrawAt(int position); |
|
133 |
130 |
134 QVector<LDObject*> _objects; |
131 QVector<LDObject*> _objects; |
135 class DocumentManager* _manager; |
132 class DocumentManager* _manager; |
136 mutable int _triangleCount = 0; |
133 mutable int _triangleCount = 0; |
137 mutable bool _needsTriangleRecount; |
134 mutable bool _needsTriangleRecount; |
|
135 |
|
136 private: |
|
137 void installObject(int row, LDObject* object); |
138 }; |
138 }; |
139 |
139 |
140 int countof(Model& model); |
140 int countof(Model& model); |
141 |
141 |
142 /* |
142 /* |
144 * and inserts it into this model. The variadic parameters and this model pointer are passed to the constructor. The constructed object |
144 * and inserts it into this model. The variadic parameters and this model pointer are passed to the constructor. The constructed object |
145 * is added to the end of the model. |
145 * is added to the end of the model. |
146 * |
146 * |
147 * For instance, the LDLine contains a constructor as such: |
147 * For instance, the LDLine contains a constructor as such: |
148 * |
148 * |
149 * LDLine(Vertex v1, Vertex v2, Model* model); |
149 * LDLine(Vertex v1, Vertex v2); |
150 * |
150 * |
151 * This constructor can be invoked as such: |
151 * This constructor can be invoked as such: |
152 * |
152 * |
153 * model->emplace<LDLine>(v1, v2); |
153 * model->emplace<LDLine>(v1, v2); |
154 */ |
154 */ |
155 template<typename T, typename... Args> |
155 template<typename T, typename... Args> |
156 T* Model::emplace(Args&& ...args) |
156 T* Model::emplace(Args&& ...args) |
157 { |
157 { |
158 T* object = constructObject<T>(args...); |
158 return emplaceAt<T>(size(), args...); |
159 addObject(object); |
|
160 return object; |
|
161 } |
159 } |
162 |
160 |
163 /* |
161 /* |
164 * Like emplace<>() but also takes a position as the first argument and emplaces the object at the given position instead of the |
162 * Like emplace<>() but also takes a position as the first argument and emplaces the object at the given position instead of the |
165 * end of the model. |
163 * end of the model. |
166 */ |
164 */ |
167 template<typename T, typename... Args> |
165 template<typename T, typename... Args> |
168 T* Model::emplaceAt(int position, Args&& ...args) |
166 T* Model::emplaceAt(int position, Args&& ...args) |
169 { |
167 { |
170 T* object = constructObject<T>(args...); |
168 T* object = constructObject<T>(args...); |
171 insertObject(position, object); |
169 installObject(position, object); |
172 return object; |
170 return object; |
173 } |
|
174 |
|
175 /* |
|
176 * Like emplace<>() but instead of inserting the constructed object, the new object replaces the object given in the first parameter. |
|
177 * If the old object cannot be replaced, the new object will not be constructed at all. |
|
178 */ |
|
179 template<typename T, typename... Args> |
|
180 T* Model::emplaceReplacement(LDObject* object, Args&& ...args) |
|
181 { |
|
182 QModelIndex position = this->indexOf(object); |
|
183 |
|
184 if (position.isValid()) |
|
185 { |
|
186 T* replacement = constructObject<T>(args...); |
|
187 setObjectAt(position.row(), replacement); |
|
188 return replacement; |
|
189 } |
|
190 else |
|
191 { |
|
192 return nullptr; |
|
193 } |
|
194 } |
|
195 |
|
196 /* |
|
197 * Like emplaceAt<>() but instead of inserting the constructed object, it replaces the document at the given spot instead. |
|
198 * The replaced object is deleted in the process. |
|
199 */ |
|
200 template<typename T, typename... Args> |
|
201 T* Model::emplaceReplacementAt(int position, Args&& ...args) |
|
202 { |
|
203 T* replacement = constructObject<T>(args...); |
|
204 setObjectAt(position, replacement); |
|
205 return replacement; |
|
206 } |
171 } |
207 |
172 |
208 /* |
173 /* |
209 * Constructs an LDObject such that it gets this model as its model pointer. |
174 * Constructs an LDObject such that it gets this model as its model pointer. |
210 */ |
175 */ |
211 template<typename T, typename... Args> |
176 template<typename T, typename... Args> |
212 T* Model::constructObject(Args&& ...args) |
177 T* Model::constructObject(Args&& ...args) |
213 { |
178 { |
214 static_assert (std::is_base_of<LDObject, T>::value, "Can only use this function with LDObject-derivatives"); |
179 static_assert (std::is_base_of<LDObject, T>::value, "Can only use this function with LDObject-derivatives"); |
215 T* object = new T {args..., this}; |
180 T* object = new T {args...}; |
216 |
181 |
217 // Set default color. Relying on virtual functions, this cannot be done in the c-tor. |
182 // Set default color. Relying on virtual functions, this cannot be done in the c-tor. |
218 // TODO: store -1 as the default color |
183 // TODO: store -1 as the default color |
219 if (object->isColored()) |
184 if (object->isColored()) |
220 object->setColor(object->defaultColor()); |
185 object->setColor(object->defaultColor()); |