4 * Copyright 2007 Novell, Inc. (http://www.novell.com)
6 * See the LICENSE file included with the distribution for details.
14 #include "resources.h"
15 #include "namescope.h"
19 free_value (Value
*value
)
24 ResourceDictionary::ResourceDictionary ()
26 SetObjectType (Type::RESOURCE_DICTIONARY
);
27 hash
= g_hash_table_new_full (g_str_hash
,
29 (GDestroyNotify
)g_free
,
30 (GDestroyNotify
)free_value
);
31 from_resource_dictionary_api
= false;
34 ResourceDictionary::~ResourceDictionary ()
36 g_hash_table_destroy (hash
);
40 ResourceDictionary::CanAdd (Value
*value
)
46 ResourceDictionary::Add (const char* key
, Value
*value
)
49 return AddWithError (key
, value
, &err
);
53 ResourceDictionary::AddWithError (const char* key
, Value
*value
, MoonError
*error
)
56 MoonError::FillIn (error
, MoonError::ARGUMENT_NULL
, "key was null");
60 if (ContainsKey (key
)) {
61 MoonError::FillIn (error
, MoonError::ARGUMENT
, "An item with the same key has already been added");
65 Value
*v
= new Value (*value
);
67 from_resource_dictionary_api
= true;
68 bool result
= Collection::AddWithError (v
, error
) != -1;
69 from_resource_dictionary_api
= false;
71 g_hash_table_insert (hash
, g_strdup (key
), v
);
76 ResourceDictionary::Clear ()
78 #if GLIB_CHECK_VERSION(2,12,0)
79 if (glib_check_version (2,12,0))
80 g_hash_table_remove_all (hash
);
83 g_hash_table_foreach_remove (hash
, (GHRFunc
) gtk_true
, NULL
);
85 from_resource_dictionary_api
= true;
86 bool rv
= Collection::Clear ();
87 from_resource_dictionary_api
= false;
93 ResourceDictionary::ContainsKey (const char *key
)
101 return g_hash_table_lookup_extended (hash
, key
,
102 &orig_key
, &orig_value
);
106 ResourceDictionary::Remove (const char *key
)
111 /* check if the item exists first */
115 if (!g_hash_table_lookup_extended (hash
, key
,
116 &orig_key
, (gpointer
*)&orig_value
))
119 from_resource_dictionary_api
= true;
120 Collection::Remove (orig_value
);
121 from_resource_dictionary_api
= false;
123 g_hash_table_remove (hash
, key
);
129 ResourceDictionary::Set (const char *key
, Value
*value
)
131 Value
*v
= new Value (*value
);
133 /* check if the item exists first */
137 if (g_hash_table_lookup_extended (hash
, key
,
138 &orig_key
, (gpointer
*)&orig_value
)) {
142 from_resource_dictionary_api
= true;
143 Collection::Remove (orig_value
);
145 from_resource_dictionary_api
= false;
147 g_hash_table_replace (hash
, g_strdup (key
), v
);
153 ResourceDictionary::Get (const char *key
, bool *exists
)
158 *exists
= g_hash_table_lookup_extended (hash
, key
,
159 &orig_key
, (gpointer
*)&v
);
164 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
166 ResourceDictionary::AddedToCollection (Value
*value
, MoonError
*error
)
168 if (value
->Is(Type::DEPENDENCY_OBJECT
)) {
169 DependencyObject
*obj
= value
->AsDependencyObject ();
170 DependencyObject
*parent
= obj
? obj
->GetParent () : NULL
;
171 // Call SetSurface() /before/ setting the logical parent
172 // because Storyboard::SetSurface() needs to be able to
173 // distinguish between the two cases.
176 MoonError::FillIn (error
, MoonError::INVALID_OPERATION
, "Element is already a child of another element.");
180 obj
->SetSurface (GetSurface ());
181 obj
->SetParent (this, error
);
185 obj
->AddPropertyChangeListener (this);
187 if (!from_resource_dictionary_api
) {
188 const char *key
= obj
->GetName();
191 MoonError::FillIn (error
, MoonError::ARGUMENT_NULL
, "key was null");
195 if (ContainsKey (key
)) {
196 MoonError::FillIn (error
, MoonError::ARGUMENT
, "An item with the same key has already been added");
202 bool rv
= Collection::AddedToCollection (value
, error
);
204 if (rv
&& !from_resource_dictionary_api
&& value
->Is(Type::DEPENDENCY_OBJECT
)) {
205 DependencyObject
*obj
= value
->AsDependencyObject ();
206 const char *key
= obj
->GetName();
208 g_hash_table_insert (hash
, g_strdup (key
), new Value (obj
));
215 remove_from_hash_by_value (gpointer key
,
219 Value
*v
= (Value
*)value
;
221 return (v
->Is (Type::DEPENDENCY_OBJECT
) && v
->AsDependencyObject() == user_data
);
224 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
226 ResourceDictionary::RemovedFromCollection (Value
*value
)
228 if (value
->Is (Type::DEPENDENCY_OBJECT
)) {
229 DependencyObject
*obj
= value
->AsDependencyObject ();
231 obj
->RemovePropertyChangeListener (this);
232 obj
->SetParent (NULL
, NULL
);
233 obj
->SetSurface (NULL
);
235 Collection::RemovedFromCollection (value
);
237 if (!from_resource_dictionary_api
)
238 g_hash_table_foreach_remove (hash
, remove_from_hash_by_value
, value
->AsDependencyObject ());
242 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
244 ResourceDictionary::SetSurface (Surface
*surface
)
246 if (GetSurface() == surface
)
251 for (guint i
= 0; i
< array
->len
; i
++) {
252 value
= (Value
*) array
->pdata
[i
];
253 if (value
->Is (Type::DEPENDENCY_OBJECT
)) {
254 DependencyObject
*obj
= value
->AsDependencyObject ();
255 obj
->SetSurface (surface
);
259 Collection::SetSurface (surface
);
262 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
264 ResourceDictionary::UnregisterAllNamesRootedAt (NameScope
*from_ns
)
268 for (guint i
= 0; i
< array
->len
; i
++) {
269 value
= (Value
*) array
->pdata
[i
];
270 if (value
->Is (Type::DEPENDENCY_OBJECT
)) {
271 DependencyObject
*obj
= value
->AsDependencyObject ();
272 obj
->UnregisterAllNamesRootedAt (from_ns
);
276 Collection::UnregisterAllNamesRootedAt (from_ns
);
279 // XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection
281 ResourceDictionary::RegisterAllNamesRootedAt (NameScope
*to_ns
, MoonError
*error
)
285 for (guint i
= 0; i
< array
->len
; i
++) {
289 value
= (Value
*) array
->pdata
[i
];
290 if (value
->Is (Type::DEPENDENCY_OBJECT
)) {
291 DependencyObject
*obj
= value
->AsDependencyObject ();
292 obj
->RegisterAllNamesRootedAt (to_ns
, error
);
296 Collection::RegisterAllNamesRootedAt (to_ns
, error
);