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