void ContentControl::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error) { if (args->GetProperty ()->GetOwnerType () != Type::CONTENTCONTROL) { Control::OnPropertyChanged (args, error); return; } if (args->GetId () == ContentControl::ContentProperty) { if (args->GetOldValue() && args->GetOldValue()->Is(GetDeployment (), Type::FRAMEWORKELEMENT)) { if (GetContentSetsParent ()) { args->GetOldValue()->AsFrameworkElement()->SetLogicalParent (NULL, error); if (error->number) return; } } if (args->GetNewValue() && args->GetNewValue()->Is(GetDeployment (), Type::FRAMEWORKELEMENT)) { if (GetContentSetsParent ()) { args->GetNewValue()->AsFrameworkElement()->SetLogicalParent (this, error); if (error->number) return; } } if (HasHandlers (ContentControl::ContentControlChangedEvent)) Emit (ContentControl::ContentControlChangedEvent, new ContentControlChangedEventArgs (args->GetOldValue(), args->GetNewValue())); InvalidateMeasure (); } NotifyListenersOfPropertyChange (args, error); }
void HttpRequest::Open (const char *verb, Uri *uri, DownloaderAccessPolicy policy) { Surface *surface; Application *application; const char *source_location; Uri *src_uri = NULL; VERIFY_MAIN_THREAD; LOG_DOWNLOADER ("HttpRequest::Open (%s, %p = %s, %i)\n", verb, uri, uri == NULL ? NULL : uri->ToString (), policy); g_free (this->verb); delete original_uri; g_free (this->uri); this->verb = g_strdup (verb); this->original_uri = new Uri (*uri); this->uri = uri->ToString (); access_policy = policy; surface = GetDeployment ()->GetSurface (); application = GetDeployment ()->GetCurrentApplication (); if (application->IsRunningOutOfBrowser ()) { source_location = surface->GetSourceLocation (); } else { source_location = GetDeployment ()->GetXapLocation (); if (source_location == NULL) source_location = surface->GetSourceLocation (); } // FIXME: ONLY VALIDATE IF USED FROM THE PLUGIN if (!Downloader::ValidateDownloadPolicy (source_location, uri, policy)) { LOG_DOWNLOADER ("HttpRequest::Open (): aborting due to security policy violation\n"); Failed ("Security Policy Violation"); Abort (); return; } /* Make the uri we request to the derived http request an absolute uri */ if (!uri->isAbsolute && source_location) { src_uri = new Uri (); if (!src_uri->Parse (source_location, true)) { Failed ("Could not parse source location"); delete src_uri; return; } src_uri->Combine (uri); g_free (this->uri); this->uri = src_uri->ToString (); delete src_uri; LOG_DOWNLOADER ("HttpRequest::Open (%s, %p = %s, %i) Url was absolutified to '%s' using source location '%s'\n", verb, uri, uri == NULL ? NULL : uri->ToString (), policy, this->uri, source_location); } OpenImpl (); }
void Border::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error) { if (args->GetProperty ()->GetOwnerType() != Type::BORDER) { FrameworkElement::OnPropertyChanged (args, error); return; } if (args->GetId () == Border::ChildProperty){ if (args->GetOldValue() && args->GetOldValue()->AsUIElement()) { ElementRemoved (args->GetOldValue()->AsUIElement ()); SetSubtreeObject (NULL); if (args->GetOldValue()->Is(GetDeployment (), Type::FRAMEWORKELEMENT)) { args->GetOldValue()->AsFrameworkElement()->SetLogicalParent (NULL, error); if (error->number) return; } } if (args->GetNewValue() && args->GetNewValue()->AsUIElement()) { SetSubtreeObject (args->GetNewValue()->AsUIElement()); ElementAdded (args->GetNewValue()->AsUIElement ()); if (args->GetNewValue()->Is(GetDeployment (), Type::FRAMEWORKELEMENT)) { FrameworkElement *fwe = args->GetNewValue()->AsFrameworkElement (); if (fwe->GetLogicalParent() && fwe->GetLogicalParent() != this) { MoonError::FillIn (error, MoonError::ARGUMENT, "Content is already a child of another element"); return; } args->GetNewValue()->AsFrameworkElement()->SetLogicalParent (this, error); if (error->number) return; } } UpdateBounds (); InvalidateMeasure (); } else if (args->GetId () == Border::PaddingProperty || args->GetId () == Border::BorderThicknessProperty) { InvalidateMeasure (); } else if (args->GetId () == Border::BackgroundProperty) { Invalidate (); } else if (args->GetId () == Border::BorderBrushProperty) { Invalidate (); } NotifyListenersOfPropertyChange (args, error); }
bool ResourceDictionary::Set (const char *key, Value *value) { /* check if the item exists first */ Value* orig_value; gpointer orig_key; if (g_hash_table_lookup_extended (hash, key, &orig_key, (gpointer*)&orig_value)) { return false; } Value orig_copy (*orig_value); Value *v = new Value (*value); from_resource_dictionary_api = true; Collection::Remove (orig_value); // No need to strengthen orig_value as it's deleted immediately Collection::Add (v); from_resource_dictionary_api = false; g_hash_table_replace (hash, g_strdup (key), v); v->Weaken (GetDeployment ()); EmitChanged (CollectionChangedActionReplace, v, &orig_copy, key); return true; // XXX }
Popup::Popup () { SetObjectType (Type::POPUP); shutting_down = false; visible = false; GetDeployment ()->AddHandler (Deployment::ShuttingDownEvent, ShuttingDownCallback, this); }
void MediaBase::SetAllowDownloads (bool allow) { const char *uri; Downloader *dl; if ((allow_downloads && allow) || (!allow_downloads && !allow)) return; if (allow && IsAttached () && source_changed) { source_changed = false; if ((uri = GetSource ()) && *uri) { if (!(dl = GetDeployment ()->CreateDownloader ())) { // we're shutting down return; } dl->Open ("GET", uri, GetDownloaderPolicy (uri)); SetSource (dl, ""); dl->unref (); } } allow_downloads = allow; }
void Image::ImageFailed (ImageErrorEventArgs *args) { BitmapSource *source = (BitmapSource*) GetSource (); if (source->Is (Type::BITMAPIMAGE)) { source->RemoveHandler (BitmapImage::DownloadProgressEvent, download_progress, this); source->RemoveHandler (BitmapImage::ImageOpenedEvent, image_opened, this); source->RemoveHandler (BitmapImage::ImageFailedEvent, image_failed, this); } source->RemoveHandler (BitmapSource::PixelDataChangedEvent, source_pixel_data_changed, this); InvalidateArrange (); InvalidateMeasure (); UpdateBounds (); Invalidate (); args = new ImageErrorEventArgs (this, *(MoonError*)args->GetMoonError ()); if (HasHandlers (ImageFailedEvent)) { Emit (ImageFailedEvent, args); } else { GetDeployment ()->GetSurface ()->EmitError (args); } }
void MediaBase::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error) { if (args->GetProperty ()->GetOwnerType() != Type::MEDIABASE) { FrameworkElement::OnPropertyChanged (args, error); return; } if (args->GetId () == MediaBase::SourceProperty) { const char *uri = args->GetNewValue() ? args->GetNewValue()->AsString () : NULL; if (IsAttached () && AllowDownloads ()) { if (uri && *uri) { Downloader *dl; if ((dl = GetDeployment ()->CreateDownloader ())) { dl->Open ("GET", uri, GetDownloaderPolicy (uri)); SetSource (dl, ""); dl->unref (); } else { // we're shutting down } } else { SetSource (NULL, NULL); } } else { source_changed = true; } InvalidateMeasure (); } NotifyListenersOfPropertyChange (args, error); }
void FrameworkTemplate::ClearXamlBuffer () { if (xaml_buffer) { g_free (xaml_buffer); xaml_buffer = NULL; } if (holdManagedRef && clearManagedRef && !GetDeployment ()->IsShuttingDown ()) { // No need to strengthen the Value* because we're deleting it next clearManagedRef (this, this->parse_template_data->AsGCHandle (), XamlContextWeakRef); } parse_template = NULL; delete parse_template_data; parse_template_data = NULL; GetDeployment ()->RemoveHandler (Deployment::ShuttingDownEvent, ShuttingDownEventCallback, this); }
bool ResourceDictionary::Remove (const char *key) { if (!key) return false; /* check if the item exists first */ Value* orig_value; gpointer orig_key; if (!g_hash_table_lookup_extended (hash, key, &orig_key, (gpointer*)&orig_value)) return false; from_resource_dictionary_api = true; Collection::Remove (orig_value); from_resource_dictionary_api = false; DependencyObject *ob = orig_value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT) ? orig_value->AsDependencyObject () : NULL; if (ob) ob->SetMentor (NULL); // No need to strengthen orig_value before clearing // because we copy it first. Value orig_copy (*orig_value); g_hash_table_remove (hash, key); EmitChanged (CollectionChangedActionRemove, NULL, &orig_copy, key); return true; }
bool Control::Focus (bool recurse) { if (!IsAttached ()) return false; /* according to msdn, these three things must be true for an element to be focusable: * * 1. the element must be visible * 2. the element must have IsTabStop = true * 3. the element must be part of the plugin's visual tree, and must have had its Loaded event fired. */ /* * If the current control is not focusable, we walk the visual tree and stop as soon * as we find the first focusable child. That then becomes focused */ Types *types = GetDeployment ()->GetTypes (); Surface *surface = GetDeployment ()->GetSurface (); DeepTreeWalker walker (this); while (UIElement *e = walker.Step ()) { if (!types->IsSubclassOf (e->GetObjectType (), Type::CONTROL)) continue; Control *c = (Control *)e; if (!c->GetIsEnabled ()) { if (!recurse) return false; walker.SkipBranch (); continue; } // A control is focusable if it is attached to a visual tree whose root // element has been loaded bool loaded = false; for (UIElement *check = this; !loaded && check != NULL; check = check->GetVisualParent ()) loaded |= check->IsLoaded (); if (loaded && c->GetRenderVisible () && c->GetIsTabStop ()) return surface->FocusElement (c); if (!recurse) return false; } return false; }
void Popup::Dispose () { if (!shutting_down && GetIsOpen ()) Hide (GetChild ()); GetDeployment ()->RemoveHandler (Deployment::ShuttingDownEvent, ShuttingDownCallback, this); FrameworkElement::Dispose (); }
void FrameworkTemplate::SetXamlBuffer (parse_template_func parse_template, Value *parse_template_data, const char *xaml_buffer, bool holdManagedRef) { this->holdManagedRef = holdManagedRef; if (!holdManagedRef) this->xaml_buffer = g_strdup (xaml_buffer); this->parse_template = parse_template; this->parse_template_data = new Value (*parse_template_data); if (holdManagedRef && addManagedRef && !GetDeployment ()->IsShuttingDown ()) { addManagedRef (this, this->parse_template_data->AsGCHandle (), XamlContextWeakRef); this->parse_template_data->Weaken (GetDeployment ()); } else { // If we can't add a managed ref to the xaml context we may end up with a circular ref // and so we should destroy this at shutdown rather than leaking it. GetDeployment ()->AddHandler (Deployment::ShuttingDownEvent, ShuttingDownEventCallback, this); } }
void Canvas::ShiftPosition (Point p) { Surface *surface = GetDeployment ()->GetSurface (); if (surface && IsAttached () && surface->IsTopLevel (this)) { ComputeBounds (); } else { Panel::ShiftPosition (p); } }
UIElement * ContentControl::GetDefaultTemplate () { Value *content = GetValue (ContentControl::ContentProperty); if (!content || content->GetIsNull ()) return NULL; if (content->Is (GetDeployment (), Type::UIELEMENT)) return content->AsUIElement (); return Control::GetDefaultTemplate (); }
// XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection void ResourceDictionary::RemovedFromCollection (Value *value, bool is_value_safe) { if (is_value_safe & value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT)) { DependencyObject *obj = value->AsDependencyObject (); if (obj) { obj->RemovePropertyChangeListener (this); obj->RemoveParent (this, NULL); obj->SetIsAttached (false); } } Collection::RemovedFromCollection (value, is_value_safe); if (is_value_safe && value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT)) { if (!from_resource_dictionary_api && value->AsDependencyObject()) { g_hash_table_foreach_remove (hash, remove_from_hash_by_value, value->AsDependencyObject ()); // FIXME we need to EmitChanged something here so the managed RD can remain in sync } } }
bool BitmapImage::ValidateDownloadPolicy () { Surface *surface = Deployment::GetCurrent ()->GetSurface (); Uri *uri = GetUriSource (); const char *location; if (!uri) return true; if (!(location = GetDeployment ()->GetXapLocation ())) location = surface ? surface->GetSourceLocation () : NULL; return Downloader::ValidateDownloadPolicy (location, uri, policy); }
void Canvas::ComputeBounds () { Surface *surface = GetDeployment ()->GetSurface (); Panel::ComputeBounds (); coverage_bounds = bounds; if (surface && IsAttached () && surface->IsTopLevel (this)) { // toplevel canvas don't subscribe to the same bounds computation as others bounds = extents = Rect (0, 0, surface->GetWindow()->GetWidth(), surface->GetWindow()->GetHeight()); bounds_with_children = extents_with_children = Rect (0, 0, surface->GetWindow()->GetWidth(), surface->GetWindow()->GetHeight()); ComputeGlobalBounds (); ComputeSurfaceBounds (); } }
// XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection void ResourceDictionary::UnregisterAllNamesRootedAt (NameScope *from_ns) { Value *value; for (guint i = 0; i < array->len; i++) { value = (Value *) array->pdata[i]; if (value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT)) { DependencyObject *obj = value->AsDependencyObject (); if (obj) obj->UnregisterAllNamesRootedAt (from_ns); } } Collection::UnregisterAllNamesRootedAt (from_ns); }
// XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection void ResourceDictionary::OnIsAttachedChanged (bool attached) { Collection::OnIsAttachedChanged (attached); Value *value; for (guint i = 0; i < array->len; i++) { value = (Value *) array->pdata[i]; if (value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT)) { DependencyObject *obj = value->AsDependencyObject (); if (obj) obj->SetIsAttached (attached); } } }
const char * HttpHandler::GetDownloadDir () { if (download_dir == NULL) { char *buf = g_build_filename (g_get_tmp_dir (), "moonlight-downloads.XXXXXX", NULL); // create a root temp directory for all files download_dir = MakeTempDir (buf); if (download_dir == NULL) { g_free (buf); printf ("Moonlight: Could not create temporary download directory.\n"); } else { GetDeployment ()->TrackPath (download_dir); LOG_DOWNLOADER ("HttpHandler::GetDownloadDir (): Created temporary download directory: %s\n", download_dir); } } return download_dir; }
// XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection void ResourceDictionary::RegisterAllNamesRootedAt (NameScope *to_ns, MoonError *error) { Value *value; for (guint i = 0; i < array->len; i++) { if (error->number) break; value = (Value *) array->pdata[i]; if (value->Is (GetDeployment (), Type::DEPENDENCY_OBJECT)) { DependencyObject *obj = value->AsDependencyObject (); obj->RegisterAllNamesRootedAt (to_ns, error); } } Collection::RegisterAllNamesRootedAt (to_ns, error); }
void HttpRequest::SendAsync () { char *templ; VERIFY_MAIN_THREAD; LOG_DOWNLOADER ("HttpRequest::SendAsync () is_aborted: %i is_completed: %i\n", is_aborted, is_completed); if (is_aborted || is_completed) return; /* create tmp file */ if ((options & DisableFileStorage) == 0) { const char *dir = handler->GetDownloadDir (); if (dir == NULL) { Failed ("Could not create temporary download directory"); return; } templ = g_build_filename (dir, "XXXXXX", NULL); tmpfile_fd = g_mkstemp (templ); if (tmpfile_fd == -1) { char *msg = g_strdup_printf ("Could not create temporary download file %s for url %s\n", templ, GetUri ()); Failed (msg); g_free (msg); g_free (templ); return; } tmpfile = templ; LOG_DOWNLOADER ("HttpRequest::Send () uri %s is being saved to %s\n", GetUri (), tmpfile); } else { LOG_DOWNLOADER ("HttpRequest::Send () uri %s is not being saved to disk\n", GetUri ()); } #if DEBUG GetDeployment ()->AddSource (GetOriginalUri (), tmpfile == NULL ? "Not stored on disk" : tmpfile); #endif SendImpl (); }
bool Control::DoApplyTemplateWithError (MoonError *error) { ControlTemplate *t = GetTemplate (); if (!t) return FrameworkElement::DoApplyTemplateWithError (error); // If the template expands to an element which is *not* a UIElement // we don't apply the template. DependencyObject *root = t->GetVisualTreeWithError (this, error); if (root && !root->Is (Type::UIELEMENT)) { g_warning ("Control::DoApplyTemplate () Template root was not a UIElement"); root->unref (); root = NULL; } if (!root) return FrameworkElement::DoApplyTemplateWithError (error); // No need to ref template_root here as ElementAdded refs it // and it is cleared when ElementRemoved is called. if (template_root != root && template_root != NULL) { template_root->SetParent (NULL, NULL); template_root->SetMentor (NULL); template_root = NULL; } template_root = (UIElement *) root; ElementAdded (template_root); if (IsLoaded ()) GetDeployment ()->EmitLoadedAsync (); root->unref (); return true; }
void Downloader::OpenInitialize () { CleanupUnzipDir (); unzipped = false; send_queued = false; started = false; aborted = false; completed = false; g_free (failed_msg); g_free (filename); failed_msg = NULL; filename = NULL; if (request != NULL) { request->RemoveAllHandlers (this); request->Dispose (); request->unref (); request = NULL; } request = GetDeployment ()->CreateHttpRequest (HttpRequest::DisableAsyncSend); request->AddHandler (HttpRequest::StoppedEvent, StoppedCallback, this); request->AddHandler (HttpRequest::ProgressChangedEvent, ProgressChangedCallback, this); }
bool Application::GetResource (const Uri *resourceBase, const Uri *uri, NotifyFunc notify_cb, EventHandler write_cb, DownloaderAccessPolicy policy, HttpRequest::Options options, Cancellable *cancellable, gpointer user_data) { if (!uri) { g_warning ("Passing a null uri to Application::GetResource"); if (notify_cb) notify_cb (NotifyFailed, GPOINTER_TO_INT(NULL), user_data); return false; } if (get_resource_cb && !uri->IsAbsolute ()) { ManagedStreamCallbacks stream; if (!Uri::IsNullOrEmpty (uri)) { stream = get_resource_cb (resourceBase, uri); } else { memset (&stream, 0, sizeof (stream)); } if (stream.handle) { if (notify_cb) notify_cb (NotifyStarted, GPOINTER_TO_INT(NULL), user_data); if (write_cb) { char buf[4096]; int offset = 0; int nread; if (stream.CanSeek (stream.handle)) stream.Seek (stream.handle, 0, 0); HttpRequestWriteEventArgs *args = new HttpRequestWriteEventArgs (NULL, 0, 0); do { if ((nread = stream.Read (stream.handle, buf, 0, sizeof (buf))) <= 0) break; args->SetData (buf); args->SetOffset (offset); args->SetCount (nread); write_cb (this, args, user_data); offset += nread; } while (true); args->unref (); } if (notify_cb) notify_cb (NotifyCompleted, GPOINTER_TO_INT(NULL), user_data); stream.Close (stream.handle); return true; } } #if 0 // FIXME: drt 171 and 173 expect this to fail simply because the uri // begins with a '/', but other drts (like 238) depend on this // working. I give up. if (!uri->isAbsolute && uri->path && uri->path[0] == '/') { if (notify_cb) notify_cb (NotifyFailed, NULL, user_data); return false; } #endif //no get_resource_cb or empty stream HttpRequest *request; if (!(request = GetDeployment ()->CreateHttpRequest (options))) { if (notify_cb) notify_cb (NotifyFailed, GPOINTER_TO_INT(NULL), user_data); return false; } NotifyCtx *ctx = g_new (NotifyCtx, 1); ctx->user_data = user_data; ctx->notify_cb = notify_cb; ctx->write_cb = write_cb; ctx->request = request; if (notify_cb) { request->AddHandler (HttpRequest::ProgressChangedEvent, application_downloader_progress_changed, ctx); request->AddHandler (HttpRequest::StartedEvent, application_downloader_started, ctx); } if (cancellable) { cancellable->SetCancelFuncAndData (application_downloader_abort, request, ctx); } request->AddHandler (HttpRequest::WriteEvent, application_downloader_write, ctx); request->AddHandler (HttpRequest::StoppedEvent, application_downloader_stopped, ctx); request->Open ("GET", uri, resourceBase, policy); request->Send (); return true; }
HttpRequest::~HttpRequest () { GetDeployment ()->UnregisterHttpRequest (this); }
DependencyObject* FrameworkTemplate::GetVisualTreeWithError (FrameworkElement *templateBindingSource, MoonError *error) { if (holdManagedRef || xaml_buffer) { DependencyObject *result = parse_template (parse_template_data, GetResourceBase (), GetDeployment ()->GetSurface (), templateBindingSource, xaml_buffer, error); if (result) NameScope::GetNameScope (result)->Lock (); return result; } return NULL; }
bool ResourceDictionary::AddWithError (const char* key, Value *value, MoonError *error) { if (!key) { MoonError::FillIn (error, MoonError::ARGUMENT_NULL, "key was null"); return false; } Value *v = NULL; gpointer orig_key; gboolean exists = g_hash_table_lookup_extended (hash, key, &orig_key, (gpointer*)&v); if (exists) { MoonError::FillIn (error, MoonError::ARGUMENT, "An item with the same key has already been added"); return false; } v = new Value (*value); from_resource_dictionary_api = true; bool result = Collection::AddWithError (v, error) != -1; from_resource_dictionary_api = false; if (result) { g_hash_table_insert (hash, g_strdup (key), v); v->Weaken (GetDeployment ()); EmitChanged (CollectionChangedActionAdd, v, NULL, key); if (!strncmp (key, INTERNAL_TYPE_KEY_MAGIC_COOKIE, sizeof (INTERNAL_TYPE_KEY_MAGIC_COOKIE) - 1) && v->Is (GetDeployment (), Type::STYLE)) { DependencyObject *p = GetParent(); if (!p) return result; Style *style = v->AsStyle(); if (p->Is (Type::APPLICATION)) { // we modified the application's resources, so we need to traverse all layers CollectionIterator *iterator = p->GetDeployment()->GetSurface()->GetLayers()->GetIterator(); while (iterator->Next (NULL)) { Value *v = iterator->GetCurrent(NULL); FrameworkElement *fwe = v->AsFrameworkElement(); fwe->StyleResourceChanged (key, style); } delete iterator; } else if (p->Is (Type::FRAMEWORKELEMENT)) { // just traverse down from this frameworkelement ((FrameworkElement*)p)->StyleResourceChanged (key, style); } } } else { delete v; } return result; }
// XXX this was (mostly, except for the type check) c&p from DependencyObjectCollection bool ResourceDictionary::AddedToCollection (Value *value, MoonError *error) { DependencyObject *obj = NULL; bool rv = false; if (value->Is(GetDeployment (), Type::DEPENDENCY_OBJECT)) { obj = value->AsDependencyObject (); // Call SetSurface() /before/ setting the logical parent // because Storyboard::SetSurface() needs to be able to // distinguish between the two cases. if (obj->GetParent () && !can_be_added_twice (GetDeployment (), value)) { MoonError::FillIn (error, MoonError::INVALID_OPERATION, g_strdup_printf ("Element is already a child of another element. %s", GetTypeName ())); return false; } obj->AddParent (this, error); if (error->number) return false; obj->SetIsAttached (IsAttached ()); obj->AddPropertyChangeListener (this); if (!from_resource_dictionary_api) { const char *key = obj->GetName(); if (!key) { MoonError::FillIn (error, MoonError::ARGUMENT_NULL, "key was null"); goto cleanup; } if (ContainsKey (key)) { MoonError::FillIn (error, MoonError::ARGUMENT, "An item with the same key has already been added"); goto cleanup; } } } rv = Collection::AddedToCollection (value, error); if (rv && !from_resource_dictionary_api && obj != NULL) { const char *key = obj->GetName(); Value *obj_value = new Value (obj); g_hash_table_insert (hash, g_strdup (key), obj_value); obj_value->Weaken (GetDeployment ()); EmitChanged (CollectionChangedActionAdd, obj_value, NULL, key); } cleanup: if (!rv) { if (obj) { /* If we set the parent, but the object wasn't added to the collection, make sure we clear the parent */ printf ("ResourceDictionary::AddedToCollection (): not added, clearing parent from %p\n", obj); obj->RemoveParent (this, NULL); } } return rv; }