1 /* This file is part of StepCore library.
2    Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
3    Copyright (C) 2014 Inge Wallin        <inge@lysator.liu.se>
4 
5    StepCore library is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    StepCore library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with StepCore; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 #include "itemgroup.h"
21 #include "world.h"  // FIXME: This is ugly
22 
23 
24 namespace StepCore
25 {
26 
27 
28 STEPCORE_META_OBJECT(ItemGroup, QT_TRANSLATE_NOOP("ObjectClass", "ItemGroup"), QT_TRANSLATE_NOOP("ObjectDescription", "ItemGroup"),
29 		     0, STEPCORE_SUPER_CLASS(Item),)
30 
31 
ItemGroup(const ItemGroup & group)32 ItemGroup::ItemGroup(const ItemGroup& group)
33     : Item()
34 {
35     *this = group;
36 }
37 
setWorld(World * world)38 void ItemGroup::setWorld(World* world)
39 {
40     ItemList::const_iterator end = _items.end();
41     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
42         (*it)->setWorld(world);
43     Item::setWorld(world);
44 }
45 
worldItemRemoved(Item * item)46 void ItemGroup::worldItemRemoved(Item* item)
47 {
48     ItemList::const_iterator end = _items.end();
49     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
50         (*it)->worldItemRemoved(item);
51 }
52 
addItem(Item * item)53 void ItemGroup::addItem(Item* item)
54 {
55     _items.push_back(item);
56 
57     if(world()) world()->worldItemAdded(item);
58 
59     item->setGroup(this);
60     item->setWorld(this->world());
61 }
62 
removeItem(Item * item)63 void ItemGroup::removeItem(Item* item)
64 {
65     item->setWorld(NULL);
66     item->setGroup(NULL);
67 
68     if(world()) world()->worldItemRemoved(item);
69 
70     ItemList::iterator i = std::find(_items.begin(), _items.end(), item);
71     STEPCORE_ASSERT_NOABORT(i != _items.end());
72     _items.erase(i);
73 }
74 
clear()75 void ItemGroup::clear()
76 {
77     ItemList::const_iterator end = _items.end();
78     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
79         (*it)->setWorld(NULL);
80         (*it)->setGroup(NULL);
81         if(world()) world()->worldItemRemoved(*it);
82     }
83 
84     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
85         delete *it;
86     }
87 
88     _items.clear();
89 }
90 
~ItemGroup()91 ItemGroup::~ItemGroup()
92 {
93     clear();
94 }
95 
operator =(const ItemGroup & group)96 ItemGroup& ItemGroup::operator=(const ItemGroup& group)
97 {
98 
99     /*
100     item->setGroup(this);
101     item->setWorld(this->world());
102     _items.push_back(item);
103 
104     if(world()) {
105         //world()->worldItemAdded(item);
106         ItemGroup* gr = dynamic_cast<ItemGroup*>(item);
107         if(gr) gr->groupItemsAdded();
108     }
109     */
110 
111     if(this == &group) return *this;
112 
113     clear();
114 
115     _items.reserve(group._items.size());
116 
117     const ItemList::const_iterator gr_end = group._items.end();
118     for(ItemList::const_iterator it = group._items.begin(); it != gr_end; ++it) {
119         StepCore::Item* item = static_cast<Item*>( (*it)->metaObject()->cloneObject(*(*it)) );
120         _items.push_back(item);
121     }
122 
123     const ItemList::const_iterator end = _items.end();
124     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
125         (*it)->setGroup(this);
126     }
127 
128     Item::operator=(group);
129 
130     // NOTE: We don't change world() here
131 
132     return *this;
133 }
134 
childItemIndex(const Item * item) const135 int ItemGroup::childItemIndex(const Item* item) const
136 {
137     ItemList::const_iterator o = std::find(_items.begin(), _items.end(), item);
138     STEPCORE_ASSERT_NOABORT(o != _items.end());
139     return std::distance(_items.begin(), o);
140 }
141 
childItem(const QString & name) const142 Item* ItemGroup::childItem(const QString& name) const
143 {
144     ItemList::const_iterator end = _items.end();
145     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
146         if((*it)->name() == name) return *it;
147     return NULL;
148 }
149 
item(const QString & name) const150 Item* ItemGroup::item(const QString& name) const
151 {
152     if(name.isEmpty()) return NULL;
153     ItemList::const_iterator end = _items.end();
154     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
155         if((*it)->name() == name) return *it;
156         if((*it)->metaObject()->inherits<ItemGroup>()) {
157             Item* ret = static_cast<ItemGroup*>(*it)->item(name);
158             if(ret) return ret;
159         }
160     }
161     return NULL;
162 }
163 
allItems(ItemList * items) const164 void ItemGroup::allItems(ItemList* items) const
165 {
166     items->reserve(_items.size());
167     ItemList::const_iterator end = _items.end();
168     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
169         items->push_back(*it);
170         if((*it)->metaObject()->inherits<ItemGroup>())
171             static_cast<ItemGroup*>(*it)->allItems(items);
172     }
173 }
174 
175 
176 } // namespace StepCore
177