xref: /haiku/src/apps/icon-o-matic/generic/property/PropertyObject.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "PropertyObject.h"
10 
11 #include <stdio.h>
12 
13 #include <ByteOrder.h>
14 #include <Message.h>
15 #include <OS.h>
16 
17 #include "Int64Property.h"
18 #include "Property.h"
19 
20 #ifndef DEBUG
21 #	define DEBUG 0
22 #endif
23 
24 // constructor
25 PropertyObject::PropertyObject()
26 	: fProperties(16)
27 {
28 }
29 
30 // constructor
31 PropertyObject::PropertyObject(const PropertyObject& other)
32 	: fProperties(16)
33 {
34 	Assign(other);
35 }
36 
37 // destructor
38 PropertyObject::~PropertyObject()
39 {
40 	DeleteProperties();
41 }
42 
43 // #pragma mark -
44 
45 // Archive
46 status_t
47 PropertyObject::Archive(BMessage* into) const
48 {
49 	if (!into)
50 		return B_BAD_VALUE;
51 
52 	status_t ret = B_OK;
53 
54 	int32 count = CountProperties();
55 	for (int32 i = 0; i < count; i++) {
56 		Property* p = PropertyAtFast(i);
57 
58 		unsigned id = B_HOST_TO_BENDIAN_INT32(p->Identifier());
59 		char idString[5];
60 		sprintf(idString, "%.4s", (const char*)&id);
61 		idString[4] = 0;
62 
63 		BString value;
64 		p->GetValue(value);
65 		ret = into->AddString(idString, value.String());
66 		if (ret < B_OK)
67 			return ret;
68 	}
69 	return ret;
70 }
71 
72 // Unarchive
73 status_t
74 PropertyObject::Unarchive(const BMessage* archive)
75 {
76 	if (!archive)
77 		return B_BAD_VALUE;
78 
79 	SuspendNotifications(true);
80 
81 	int32 count = CountProperties();
82 	for (int32 i = 0; i < count; i++) {
83 		Property* p = PropertyAtFast(i);
84 
85 		unsigned id = B_HOST_TO_BENDIAN_INT32(p->Identifier());
86 		char idString[5];
87 		sprintf(idString, "%.4s", (const char*)&id);
88 		idString[4] = 0;
89 
90 		const char* value;
91 		if (archive->FindString(idString, &value) == B_OK)
92 			if (p->SetValue(value))
93 				Notify();
94 	}
95 
96 	SuspendNotifications(false);
97 
98 	return B_OK;
99 }
100 
101 // #pragma mark -
102 
103 // AddProperty
104 bool
105 PropertyObject::AddProperty(Property* property)
106 {
107 	if (!property)
108 		return false;
109 
110 #if DEBUG
111 	if (FindProperty(property->Identifier())) {
112 		debugger("PropertyObject::AddProperty() -"
113 				 "property with same ID already here!\n");
114 		return false;
115 	}
116 
117 	// debugging
118 	if (fProperties.HasItem((void*)property)) {
119 		debugger("PropertyObject::AddProperty() - property id "
120 				 "changed unexpectedly\n");
121 		return false;
122 	}
123 #endif
124 
125 	if (fProperties.AddItem((void*)property)) {
126 		Notify();
127 		return true;
128 	}
129 
130 	return false;
131 }
132 
133 // PropertyAt
134 Property*
135 PropertyObject::PropertyAt(int32 index) const
136 {
137 	return (Property*)fProperties.ItemAt(index);
138 }
139 
140 // PropertyAtFast
141 Property*
142 PropertyObject::PropertyAtFast(int32 index) const
143 {
144 	return (Property*)fProperties.ItemAtFast(index);
145 }
146 
147 // CountProperties
148 int32
149 PropertyObject::CountProperties() const
150 {
151 	return fProperties.CountItems();
152 }
153 
154 // #pragma mark -
155 
156 // FindProperty
157 Property*
158 PropertyObject::FindProperty(uint32 propertyID) const
159 {
160 	int32 count = fProperties.CountItems();
161 	for (int32 i = 0; i < count; i++) {
162 		Property* p = (Property*)fProperties.ItemAtFast(i);
163 		if (p->Identifier() == propertyID)
164 			return p;
165 	}
166 	return NULL;
167 }
168 
169 //HasProperty
170 bool
171 PropertyObject::HasProperty(Property* property) const
172 {
173 	return fProperties.HasItem((void*)property);
174 }
175 
176 // ContainsSameProperties
177 bool
178 PropertyObject::ContainsSameProperties(const PropertyObject& other) const
179 {
180 	bool equal = false;
181 	int32 count = CountProperties();
182 	if (count == other.CountProperties()) {
183 		equal = true;
184 		for (int32 i = 0; i < count; i++) {
185 			Property* ownProperty = PropertyAtFast(i);
186 			Property* otherProperty = other.PropertyAtFast(i);
187 			if (ownProperty->Identifier() != otherProperty->Identifier()) {
188 				equal = false;
189 				break;
190 			}
191 		}
192 	}
193 	return equal;
194 }
195 
196 // Assign
197 status_t
198 PropertyObject::Assign(const PropertyObject& other)
199 {
200 	DeleteProperties();
201 
202 	int32 count = other.fProperties.CountItems();
203 	for (int32 i = 0; i < count; i++) {
204 		Property* p = (Property*)other.fProperties.ItemAtFast(i);
205 		Property* clone = p->Clone();
206 		if (!AddProperty(clone)) {
207 			delete clone;
208 			fprintf(stderr, "PropertyObject::Assign() - no memory for "
209 							"cloning properties!\n");
210 			return B_NO_MEMORY;
211 		}
212 	}
213 
214 	return B_OK;
215 }
216 
217 // DeleteProperties
218 void
219 PropertyObject::DeleteProperties()
220 {
221 	int32 count = fProperties.CountItems();
222 	for (int32 i = 0; i < count; i++)
223 		delete (Property*)fProperties.ItemAtFast(i);
224 	fProperties.MakeEmpty();
225 	Notify();
226 }
227 
228 // DeleteProperty
229 bool
230 PropertyObject::DeleteProperty(uint32 propertyID)
231 {
232 	int32 count = fProperties.CountItems();
233 	for (int32 i = 0; i < count; i++) {
234 		Property* p = (Property*)fProperties.ItemAtFast(i);
235 		if (p->Identifier() == propertyID) {
236 			if (fProperties.RemoveItem(i)) {
237 				Notify();
238 				delete p;
239 				return true;
240 			}
241 			break;
242 		}
243 	}
244 	return false;
245 }
246 
247 // ValueChanged
248 void
249 PropertyObject::ValueChanged(uint32 propertyID)
250 {
251 	Notify();
252 }
253 
254 // #pragma mark -
255 
256 // SetValue
257 bool
258 PropertyObject::SetValue(uint32 propertyID, const char* value)
259 {
260 	if (Property* p = FindProperty(propertyID)) {
261 		if (p->SetValue(value)) {
262 			ValueChanged(propertyID);
263 			return true;
264 		}
265 	}
266 	return false;
267 }
268 
269 // GetValue
270 bool
271 PropertyObject::GetValue(uint32 propertyID, BString& value) const
272 {
273 	if (Property* p = FindProperty(propertyID)) {
274 		p->GetValue(value);
275 		return true;
276 	}
277 	return false;
278 }
279 
280 // #pragma mark - int32
281 
282 // SetValue
283 bool
284 PropertyObject::SetValue(uint32 propertyID, int32 value)
285 {
286 	IntProperty* p = dynamic_cast<IntProperty*>(FindProperty(propertyID));
287 	if (p && p->SetValue(value)) {
288 		ValueChanged(propertyID);
289 		return true;
290 	}
291 	return false;
292 }
293 
294 // Value
295 int32
296 PropertyObject::Value(uint32 propertyID, int32 defaultValue) const
297 {
298 	if (IntProperty* p = dynamic_cast<IntProperty*>(FindProperty(propertyID)))
299 		return p->Value();
300 	return defaultValue;
301 }
302 
303 // #pragma mark - int64
304 
305 // SetValue
306 bool
307 PropertyObject::SetValue(uint32 propertyID, int64 value)
308 {
309 	Int64Property* p = dynamic_cast<Int64Property*>(FindProperty(propertyID));
310 	if (p && p->SetValue(value)) {
311 		ValueChanged(propertyID);
312 		return true;
313 	}
314 	return false;
315 }
316 
317 // Value
318 int64
319 PropertyObject::Value(uint32 propertyID, int64 defaultValue) const
320 {
321 	if (Int64Property* p = dynamic_cast<Int64Property*>(FindProperty(propertyID)))
322 		return p->Value();
323 	return defaultValue;
324 }
325 
326 // #pragma mark - float
327 
328 // SetValue
329 bool
330 PropertyObject::SetValue(uint32 propertyID, float value)
331 {
332 	FloatProperty* p = dynamic_cast<FloatProperty*>(FindProperty(propertyID));
333 	if (p && p->SetValue(value)) {
334 		ValueChanged(propertyID);
335 		return true;
336 	}
337 	return false;
338 }
339 
340 // Value
341 float
342 PropertyObject::Value(uint32 propertyID, float defaultValue) const
343 {
344 	if (FloatProperty* p = dynamic_cast<FloatProperty*>(FindProperty(propertyID)))
345 		return p->Value();
346 	return defaultValue;
347 }
348 
349 // #pragma mark - bool
350 
351 // SetValue
352 bool
353 PropertyObject::SetValue(uint32 propertyID, bool value)
354 {
355 	BoolProperty* p = dynamic_cast<BoolProperty*>(FindProperty(propertyID));
356 	if (p && p->SetValue(value)) {
357 		ValueChanged(propertyID);
358 		return true;
359 	}
360 	return false;
361 }
362 
363 // Value
364 bool
365 PropertyObject::Value(uint32 propertyID, bool defaultValue) const
366 {
367 	if (BoolProperty* p = dynamic_cast<BoolProperty*>(FindProperty(propertyID)))
368 		return p->Value();
369 	return defaultValue;
370 }
371 
372 
373