]> Shamusworld >> Repos - architektonas/blob - src/base/rs_layerlist.cpp
ac03f6ec435a14b64f663d6715064ffec5457687
[architektonas] / src / base / rs_layerlist.cpp
1 // rs_layerlist.cpp
2 //
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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  06/01/2010  Added this text. :-)
15 //
16
17 #include "rs_layerlist.h"
18
19 #include "rs_layer.h"
20 #include "rs_layerlistlistener.h"
21 #include "rs_entity.h"
22
23 /**
24  * Default constructor.
25  */
26 RS_LayerList::RS_LayerList()
27 {
28 // Good news, we don't have to screw with this shit
29 //      layers.setAutoDelete(false);
30 //      layerListListeners.setAutoDelete(false);
31         activeLayer = NULL;
32         setModified(false);
33 }
34
35 /*virtual*/ RS_LayerList::~RS_LayerList()
36 {
37 }
38
39 /**
40  * Removes all layers in the layerlist.
41  */
42 void RS_LayerList::clear()
43 {
44         layers.clear();
45         setModified(true);
46 }
47
48 /**
49  * @return Number of layers in the list.
50  */
51 uint RS_LayerList::count() const
52 {
53         return layers.count();
54 }
55
56 /**
57  * @return Layer at given position or NULL if i is out of range.
58  */
59 RS_Layer * RS_LayerList::at(uint i)
60 {
61         return layers.at(i);
62 }
63
64 /**
65  * Activates the given layer.
66  *
67  * @param notify Notify listeners.
68  */
69 void RS_LayerList::activate(const QString & name, bool notify)
70 {
71         RS_DEBUG->print("RS_LayerList::activate: %s, notify: %d begin", name.toLatin1().data(), notify);
72
73         activate(find(name), notify);
74         /*
75         if (activeLayer==NULL) {
76                 RS_DEBUG->print("activeLayer is NULL");
77 } else {
78                 RS_DEBUG->print("activeLayer is %s", activeLayer->getName().latin1());
79 }
80         */
81
82         RS_DEBUG->print("RS_LayerList::activate: %s end", name.toLatin1().data());
83 }
84
85 /**
86  * Activates the given layer.
87  *
88  * @param notify Notify listeners.
89  */
90 void RS_LayerList::activate(RS_Layer * layer, bool notify)
91 {
92         RS_DEBUG->print("RS_LayerList::activate notify: %d begin", notify);
93
94         /*if (layer!=NULL) {
95                 RS_DEBUG->print("RS_LayerList::activate: %s",
96                                                 layer->getName().latin1());
97 } else {
98                 RS_DEBUG->print("RS_LayerList::activate: NULL");
99 }*/
100
101         activeLayer = layer;
102
103         if (notify)
104         {
105                 for(int i=0; i<layerListListeners.count(); ++i)
106                 {
107                         RS_LayerListListener * l = layerListListeners.at(i);
108                         l->layerActivated(activeLayer);
109                         RS_DEBUG->print("RS_LayerList::activate listener notified");
110                 }
111         }
112
113         RS_DEBUG->print("RS_LayerList::activate end");
114 }
115
116 //! @return The active layer of NULL if no layer is activated.
117 RS_Layer * RS_LayerList::getActive()
118 {
119         return activeLayer;
120 }
121
122 /**
123  * Adds a layer to the layer list.
124  * If there is already a layer with the same name, no layer is
125  * added. In that case the layer passed to the methode will be deleted!
126  * If no layer was active so far, the new layer becomes the active one.
127  *
128  * Listeners are notified.
129  */
130 void RS_LayerList::add(RS_Layer * layer)
131 {
132         RS_DEBUG->print("RS_LayerList::addLayer()");
133
134         if (layer == NULL)
135                 return;
136
137         // check if layer already exists:
138         RS_Layer * l = find(layer->getName());
139
140         if (l == NULL)
141         {
142                 layers.append(layer);
143
144                 // notify listeners
145                 for(int i=0; i<layerListListeners.count(); ++i)
146                 {
147                         RS_LayerListListener * l = layerListListeners.at(i);
148                         l->layerAdded(layer);
149                 }
150
151                 setModified(true);
152
153                 // if there was no active layer so far, activate this one.
154                 if (activeLayer ==NULL)
155                         activate(layer);
156         }
157         else
158         {
159                 // if there was no active layer so far, activate this one.
160                 if (activeLayer == NULL)
161                         activate(l);
162
163                 l->setPen(layer->getPen());
164
165                 delete layer;
166                 layer = NULL;
167         }
168 }
169
170 /**
171  * Removes a layer from the list.
172  * Listeners are notified after the layer was removed from
173  * the list but before it gets deleted.
174  */
175 void RS_LayerList::remove(RS_Layer * layer)
176 {
177         RS_DEBUG->print("RS_LayerList::removeLayer()");
178
179         if (layer == NULL)
180                 return;
181
182         // here the layer is removed from the list but not deleted
183 //      layers.remove(layer);
184         int idx = layers.indexOf(layer);
185
186         if (idx != -1)
187                 layers.takeAt(idx);
188
189         for(int i=0; i<layerListListeners.count(); ++i)
190         {
191                 RS_LayerListListener * l = layerListListeners.at(i);
192                 l->layerRemoved(layer);
193         }
194
195         setModified(true);
196
197         // activate an other layer if necessary:
198         if (activeLayer == layer)
199                 activate(layers.first());
200
201         // now it's save to delete the layer
202         delete layer;
203 }
204
205 /**
206  * Changes a layer's attributes. The attributes of layer 'layer'
207  * are copied from layer 'source'.
208  * Listeners are notified.
209  */
210 void RS_LayerList::edit(RS_Layer * layer, const RS_Layer & source)
211 {
212         if (layer == NULL)
213                 return;
214
215         *layer = source;
216
217         for(int i=0; i<layerListListeners.count(); ++i)
218         {
219                 RS_LayerListListener * l = layerListListeners.at(i);
220                 l->layerEdited(layer);
221         }
222
223         setModified(true);
224 }
225
226 /**
227  * @return Pointer to the layer with the given name or
228  * \p NULL if no such layer was found.
229  */
230 RS_Layer * RS_LayerList::find(const QString & name)
231 {
232         //RS_DEBUG->print("RS_LayerList::find begin");
233
234         RS_Layer * ret = NULL;
235
236 //      for(RS_Layer * l=layers.first(); l!=NULL; l=layers.next())
237         for(int i=0; i<layers.size(); i++)
238         {
239                 RS_Layer * l = layers[i];
240
241                 if (l->getName() == name)
242                         ret = l;
243         }
244
245         //RS_DEBUG->print("RS_LayerList::find end");
246
247         return ret;
248 }
249
250 /**
251  * @return Index of the given layer in the layer list or -1 if the layer
252  * was not found.
253  */
254 int RS_LayerList::getIndex(const QString & name)
255 {
256 #if 0
257         //RS_DEBUG->print("RS_LayerList::find begin");
258
259         int ret = -1;
260         int i = 0;
261
262         for(RS_Layer * l=layers.first(); l!=NULL; l=layers.next())
263         {
264                 if (l->getName() == name)
265                 {
266                         ret = i;
267                         break;
268                 }
269
270                 i++;
271         }
272
273         //RS_DEBUG->print("RS_LayerList::find end");
274
275         return ret;
276 #else
277         for(int i=0; i<layers.size(); i++)
278         {
279                 RS_Layer * l = layers[i];
280
281                 if (l->getName() == name)
282                         return i;
283         }
284
285         return -1;
286 #endif
287 }
288
289 /**
290  * @return Index of the given layer in the layer list or -1 if the layer
291  * was not found.
292  */
293 int RS_LayerList::getIndex(RS_Layer * layer)
294 {
295 #if 0
296         //RS_DEBUG->print("RS_LayerList::find begin");
297
298         int ret = -1;
299         int i = 0;
300
301         for(RS_Layer* l=layers.first(); l!=NULL; l=layers.next())
302         {
303                 if (l == layer)
304                 {
305                         ret = i;
306                         break;
307                 }
308
309                 i++;
310         }
311
312         //RS_DEBUG->print("RS_LayerList::find end");
313
314         return ret;
315 #else
316         return layers.indexOf(layer);
317 #endif
318 }
319
320 /**
321  * Switches on / off the given layer.
322  * Listeners are notified.
323  */
324 void RS_LayerList::toggle(const QString & name)
325 {
326         toggle(find(name));
327 }
328
329 /**
330  * Switches on / off the given layer.
331  * Listeners are notified.
332  */
333 void RS_LayerList::toggle(RS_Layer * layer)
334 {
335         if (layer == NULL)
336                 return;
337
338         layer->toggle();
339
340         // Notify listeners:
341         for(int i=0; i < layerListListeners.count(); ++i)
342         {
343                 RS_LayerListListener * l = layerListListeners.at(i);
344                 l->layerToggled(layer);
345         }
346 }
347
348 /**
349  * Locks or unlocks the given layer.
350  * Listeners are notified.
351  */
352 void RS_LayerList::toggleLock(RS_Layer * layer)
353 {
354         if (layer == NULL)
355                 return;
356
357         layer->toggleLock();
358
359         // Notify listeners:
360         for(int i=0; i<layerListListeners.count(); ++i)
361         {
362                 RS_LayerListListener * l = layerListListeners.at(i);
363                 l->layerToggled(layer);
364         }
365 }
366
367 /**
368  * Freezes or defreezes all layers.
369  *
370  * @param freeze true: freeze, false: defreeze
371  */
372 void RS_LayerList::freezeAll(bool freeze)
373 {
374         for(uint l=0; l<count(); l++)
375                 at(l)->freeze(freeze);
376
377         for(int i=0; i<layerListListeners.count(); ++i)
378         {
379                 RS_LayerListListener * l = layerListListeners.at(i);
380                 l->layerToggled(NULL);
381         }
382 }
383
384 /**
385  * adds a LayerListListener to the list of listeners. Listeners
386  * are notified when the layer list changes.
387  *
388  * Typical listeners are: layer list widgets, pen toolbar, graphic view
389  */
390 void RS_LayerList::addListener(RS_LayerListListener * listener)
391 {
392         layerListListeners.append(listener);
393 }
394
395 /**
396  * removes a LayerListListener from the list of listeners.
397  */
398 void RS_LayerList::removeListener(RS_LayerListListener * listener)
399 {
400 //      layerListListeners.remove(listener);
401
402         int i = layerListListeners.indexOf(listener);
403
404         if (i != -1)
405                 layerListListeners.takeAt(i);
406 }
407
408 /**
409  * Sets the layer lists modified status to 'm'.
410  */
411 void RS_LayerList::setModified(bool m)
412 {
413         modified = m;
414 }
415
416 /**
417  * @retval true The layer list has been modified.
418  * @retval false The layer list has not been modified.
419  */
420 /*virtual*/ bool RS_LayerList::isModified() const
421 {
422         return modified;
423 }
424
425 /**
426  * Dumps the layers to stdout.
427  */
428 std::ostream & operator<<(std::ostream & os, RS_LayerList & l)
429 {
430         os << "Layerlist: \n";
431
432         for(uint i=0; i<l.count(); i++)
433                 os << *(l.at(i)) << "\n";
434
435         return os;
436 }