/// <summary>
        /// Makes a request to a remote media server to import the binary file from a URI to
        /// a resource that is part of the server's content hierarchy.
        /// </summary>
        /// <param name="sourceUri">the URI where binary should be pulled</param>
        /// <param name="importHere">the <see cref="ICpResource"/> object that represents the
        /// destination of the imported binary
        /// </param>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">the callback to execute when results become available</param>
        /// <exception cref="Error_ResourceNotOnServer">
        /// Thrown when attempting to delete a resource object that
        /// is not part of the server's content hierarchy.
        /// </exception>
        /// <exception cref="NullReferenceException">
        /// Thrown when attempting a remove a resource that has
        /// a null/empty value for its contentUri.
        /// </exception>
        /// <exception cref="Error_CannotGetParent">
        /// Thrown if the parent of this object is null.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// Thrown if the parent of this object is not a <see cref="CpMediaContainer"/>.
        /// </exception>
        public void RequestImportResource(System.Uri sourceUri, ICpResource importHere, object Tag, CpMediaDelegates.Delegate_ResultImportResource callback)
        {
            // calls parent's implementation of method
            CpMediaContainer parent = (CpMediaContainer)this.Parent;

            parent.RequestImportResource(sourceUri, importHere, Tag, callback);
        }
        /// <summary>
        /// Requests a remote media server to delete a resource from its local file system.
        /// </summary>
        /// <param name="deleteThisResource">the resource to request for deletion</param>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">callback to execute when results have been obtained</param>
        /// <exception cref="Error_ResourceNotOnServer">
        /// Thrown when attempting to delete a resource object that
        /// is not part of the server's content hierarchy.
        /// </exception>
        /// <exception cref="NullReferenceException">
        /// Thrown when attempting a remove a resource that has
        /// a null/empty value for its contentUri.
        /// </exception>
        /// <exception cref="Error_CannotGetParent">
        /// Thrown if the parent of this object is null.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// Thrown if the parent of this object is not a <see cref="CpMediaContainer"/>.
        /// </exception>
        public void RequestDeleteResource(ICpResource deleteThisResource, object Tag, CpMediaDelegates.Delegate_ResultDeleteResource callback)
        {
            // calls parent's implementation of method
            CpMediaContainer parent = (CpMediaContainer)this.Parent;

            parent.RequestDeleteResource(deleteThisResource, Tag, callback);
        }
        /// <summary>
        /// Creates a
        /// <see cref="CpMediaContainer"/>
        /// object, given a metadata instantiation
        /// block.
        /// </summary>
        /// <param name="info">
        /// The metadata to use when instantiating the media.
        /// </param>
        /// <returns>a new media container</returns>
        public static CpMediaContainer CreateContainer(MediaBuilder.container info)
        {
            CpMediaContainer newObj = new CpMediaContainer();

            MediaBuilder.SetObjectProperties(newObj, info);
            return(newObj);
        }
Example #4
0
 /// <summary>
 /// <see cref="CpMediaContainer"/> objects
 /// use this method to event changes in their state. This
 /// method simply fires the
 /// <see cref="CpRootContainer.OnContainerChanged"/>
 /// event.
 /// </summary>
 /// <param name="thisChanged"><see cref="CpMediaContainer"/> that observed the change.</param>
 internal void FireOnContainerChanged(CpMediaContainer thisChanged)
 {
     if (this.OnContainerChanged != null)
     {
         this.OnContainerChanged(this, thisChanged);
     }
 }
        /// <summary>
        /// Makes a request to a remote media server to export one of its binary files
        /// to another location.
        /// </summary>
        /// <param name="exportThis">
        /// The resource (of this media object) that should be exported.
        /// </param>
        /// <param name="sendHere">
        /// The uri where the binary should be sent.
        /// </param>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">the callback to execute when results become available</param>
        /// <exception cref="Error_CannotGetParent">
        /// Thrown if the parent of this object is null.
        /// </exception>
        public void RequestExportResource(ICpResource exportThis, System.Uri sendHere, object Tag, CpMediaDelegates.Delegate_ResultExportResource callback)
        {
            // calls parent's implementation of method
            CpMediaContainer parent = (CpMediaContainer)this.Parent;

            parent.RequestExportResource(exportThis, sendHere, Tag, callback);
        }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersRemove"/> calls this
        /// method to indicate that child objects have been removed
        /// from the container.
        /// </summary>
        /// <param name="thisChanged">the container that witnessed the change</param>
        /// <param name="removeThese">an ArrayList of STRONG REFERENCES to <see cref="ICpMedia"/> objects</param>
        internal void NotifySinkRemove(CpMediaContainer thisChanged, ArrayList removeThese)
        {
            ArrayList removedObjects = new ArrayList(removeThese.Count);

            lock (this.m_Matches.SyncRoot)
            {
                foreach (ICpMedia obj in this.m_Matches)
                {
                    if (removeThese.Contains(obj))
                    {
                        removedObjects.Add(obj);
                    }
                }

                foreach (ICpMedia obj in removedObjects)
                {
                    this.m_Matches.Remove(obj);
                }
            }

            if (removedObjects.Count > 0)
            {
                if (this.OnMatchesRemoved != null)
                {
                    this.OnMatchesRemoved(this, removedObjects);
                }
            }
        }
        /// <summary>
        /// Calls the parent object's implementation of <see cref="CpMediaContainer.CheckRuntimeBindings"/>.
        /// </summary>
        /// <param name="st">stack trace object, created in the method that desires runtime checking</param>
        public override void CheckRuntimeBindings(StackTrace st)
        {
            if (this.Parent != null)
            {
                CpMediaContainer parent = (CpMediaContainer)this.Parent;

                parent.CheckRuntimeBindings(st);
            }
        }
 internal void NotifySinkBrowsingError(CpMediaContainer thisChanged, Exception e)
 {
     if (thisChanged == this.m_MonitorThis)
     {
         this.m_BrowsingError = e;
         if (this.OnUpdateDone != null)
         {
             this.OnUpdateDone(this, null);
         }
     }
 }
        /// <summary>
        /// This method will invoke a CDS browse request and provide the results
        /// directly the application-caller.
        /// <para>
        /// Implementation simply calls the parent owner's implementation of
        /// <see cref="CpMediaContainer.RequestBrowse "/>(ICpMedia, CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag, string, uint, uint, string).
        /// </para>
        /// </summary>
        /// <param name="BrowseFlag">browse metadata or direct children</param>
        /// <param name="Filter">
        /// Comma-separated value list of metadata names to include
        /// in the response. For all metadata, use * character.
        /// </param>
        /// <param name="StartingIndex">
        /// If obtaining children, the start index of the results.
        /// Otherwise set to zero.
        /// </param>
        /// <param name="RequestedCount">
        /// If obtaining children the max number of child objects
        /// to retrieve. Otherwise use zero.
        /// </param>
        /// <param name="SortCriteria">
        /// Comma-separated value list of metadata names to use for
        /// sorting, such that preceding each metadata name (but after
        /// the comma) a + or - character is present to indicate
        /// ascending or descending sort order for that property.
        /// </param>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">the callback to execute when results become available</param>
        /// <exception cref="ApplicationException">
        /// Thrown if the BrowseFlag value is BrowseDirectChildren because only the
        /// object's metadata can be obtained use browse.
        /// </exception>
        public void RequestBrowse(CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag BrowseFlag, string Filter, uint StartingIndex, uint RequestedCount, string SortCriteria, object Tag, CpMediaDelegates.Delegate_ResultBrowse callback)
        {
            if (BrowseFlag == CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN)
            {
                throw new ApplicationException("BrowseFlag cannot be BROWSEDIRECTCHILDREN");
            }

            CpMediaContainer parent = (CpMediaContainer)this.Parent;

            parent.RequestBrowse(this, BrowseFlag, Filter, StartingIndex, RequestedCount, SortCriteria, Tag, callback);
        }
 /// <summary>
 /// Decrements the number of spiders that have indicated
 /// this item to be of interest to them.
 /// This method is called by CdsSpider to indicate
 /// that the spider is not interested in the container anymore.
 /// If no spiders are interested in the item, then
 /// the item is removed.
 /// </summary>
 internal void DecrementSpiderMatches()
 {
     System.Threading.Interlocked.Decrement(ref this.m_SpiderClients);
     if (this.m_SpiderClients == 0)
     {
         CpMediaContainer p = (CpMediaContainer)this.Parent;
         if (p != null)
         {
             p.RemoveObject(this);
         }
     }
 }
Example #11
0
        /// <summary>
        /// Method executes when a contentdirectory events a change in a container.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="NewValue"></param>
        private void Sink_OnContainerUpdateIDsChanged(CpContentDirectory sender, System.String NewValue)
        {
            string    csv_containers = NewValue;
            Hashtable cache          = new Hashtable();
            DText     parser         = new DText();
            DText     parser2        = new DText();

            parser.ATTRMARK  = ",";
            parser2.ATTRMARK = ",";

            if (csv_containers != "")
            {
                parser[0] = csv_containers;
                int dcnt = parser.DCOUNT();

                for (int i = 1; i <= dcnt; i++)
                {
                    string id, update;
                    if (Accumulator_ContainerUpdateIDs.Delimitor == ",")
                    {
                        id     = parser[i++];
                        update = parser[i];
                    }
                    else
                    {
                        string pair = parser[i];
                        parser2[0] = pair;
                        id         = parser2[1];
                        update     = parser2[2];
                    }

                    CpMediaContainer cpc = (CpMediaContainer)this.GetDescendent(id, cache);

                    if (cpc != null)
                    {
                        try
                        {
                            UInt32 updateId = UInt32.Parse(update);
                            if (updateId != cpc.UpdateID)
                            {
                                cpc.ForceUpdate(false);
                            }
                        }
                        catch
                        {
                            cpc.ForceUpdate(false);
                        }
                    }
                }
            }

            cache.Clear();
        }
        /// <summary>
        /// Allows a programmer to request a remote mediaserver to change the metadata
        /// for this item.
        /// </summary>
        /// <param name="useThisMetadata">
        /// Media object that represents what the new metadata should be for the object.
        /// </param>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">
        /// Delegate executes when the results for the method are available.
        /// </param>
        /// <exception cref="Error_CannotGetParent">
        /// Thrown if the parent of this object is null.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// Thrown if this object's parent is not a
        /// <see cref="CpMediaContainer"/> object.
        /// </exception>
        public void RequestUpdateObject(IUPnPMedia useThisMetadata, object Tag, CpMediaDelegates.Delegate_ResultUpdateObject callback)
        {
            CpMediaContainer p = (CpMediaContainer)this.Parent;

            if (p != null)
            {
                p.RequestUpdateObject(this, useThisMetadata, Tag, callback);
            }
            else
            {
                throw new Error_CannotGetParent(this);
            }
        }
        /// <summary>
        /// Makes a request on the remote media server to delete this
        /// object from its parent.
        /// </summary>
        /// <param name="Tag">
        /// Miscellaneous, user-provided object for tracking this
        /// asynchronous call. Can be used as a means to pass a
        /// user-defined "state object" at invoke-time so that
        /// the executed callback during results-processing can be
        /// aware of the component's state at the time of the call.
        /// </param>
        /// <param name="callback">
        /// Delegate executes when the results for the method are available.
        /// </param>
        /// <exception cref="Error_CannotGetParent">
        /// Thrown if the parent of this object is null.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// Thrown if this object's parent is not a
        /// <see cref="CpMediaContainer"/> object.
        /// </exception>
        public void RequestDestroyObject(object Tag, CpMediaDelegates.Delegate_ResultDestroyObject callback)
        {
            CpMediaContainer p = (CpMediaContainer)this.Parent;

            if (p != null)
            {
                p.RequestDestroyObject(this, Tag, callback);
            }
            else
            {
                throw new Error_CannotGetParent(this);
            }
        }
        /// <summary>
        /// Call this method if a spider is no longer interested in an object
        /// that was earlier marked as being of interest to this spider.
        /// </summary>
        /// <param name="obj"></param>
        private void DecrementMatch(ICpMedia obj)
        {
            CpMediaContainer cpc = obj as CpMediaContainer;
            CpMediaItem      cpi = obj as CpMediaItem;

            if (cpc != null)
            {
                cpc.DecrementSpiderMatches();
            }
            else if (cpi != null)
            {
                cpi.DecrementSpiderMatches();
            }
        }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersAdd"/> calls this
        /// method to indicate that a container's contents have changed.
        /// Upon exiting this method, the
        /// CdsSpider acknowledges that the container has changed
        /// and that the container has no obligation to keep its
        /// references to child objects any longer.
        /// </summary>
        /// <param name="thisChanged">the container that has changed</param>
        /// <param name="addThese">
        /// A reliable listing of new matches for the container's current state.
        /// Each element will be a strong reference to an <see cref="ICpMedia"/> object.
        /// Assume that the container has already filtered the results so that
        /// addThese only contains elements that match the comparer for this spider.
        /// </param>
        internal void NotifySinkAdd(CpMediaContainer thisChanged, ArrayList addThese)
        {
            bool eventAdded = false;

            lock (this.m_Matches.SyncRoot)
            {
                if (thisChanged == this.MonitorThis)
                {
                    ExpectingResults = false;
                    if (addThese.Count > 0)
                    {
                        if ((this.m_Matches.Count == 0))
                        {
                            this.m_Matches = new ArrayList(addThese.Count);
                        }

                        if (this.m_Sorter != null)
                        {
                            // perform a sorted insert for each item
                            _SortedList sortThese = new _SortedList(this.m_Sorter, true);
                            foreach (ICpMedia obj in addThese)
                            {
                                sortThese.Set(this.m_Matches, obj, false);
                            }
                        }
                        else
                        {
                            this.m_Matches.AddRange((ICollection)addThese);
                        }

                        eventAdded = true;
                    }
                }
            }

            if (eventAdded)
            {
                if (this.OnMatchesAdded != null)
                {
                    this.OnMatchesAdded(this, addThese);
                }
            }
        }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersOfGoneContainer"/> calls this
        /// method to indicate that the container the spider happens
        /// to be monitoring no longer exists.
        /// </summary>
        /// <param name="thisChanged"></param>
        internal void NotifySinkContainerGone(CpMediaContainer thisChanged)
        {
            lock (this.m_Matches.SyncRoot)
            {
                if (thisChanged == this.MonitorThis)
                {
                    this.m_IsDead = true;
                    if (this.OnContainerGone != null)
                    {
                        this.OnContainerGone(this, null);
                    }

                    if (this.MonitorThis == thisChanged)
                    {
                        this.MonitorThis = null;
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersAdd"/> calls this
        /// method to indicate that a container's contents have changed. 
        /// Upon exiting this method, the
        /// CdsSpider acknowledges that the container has changed
        /// and that the container has no obligation to keep its
        /// references to child objects any longer. 
        /// </summary>
        /// <param name="thisChanged">the container that has changed</param>
        /// <param name="addThese">
        /// A reliable listing of new matches for the container's current state.
        /// Each element will be a strong reference to an <see cref="ICpMedia"/> object.
        /// Assume that the container has already filtered the results so that
        /// addThese only contains elements that match the comparer for this spider.
        /// </param>
        internal void NotifySinkAdd(CpMediaContainer thisChanged, ArrayList addThese)
        {
            bool eventAdded = false;
            lock (this.m_Matches.SyncRoot)
            {
                if (thisChanged == this.MonitorThis)
                {
                    ExpectingResults = false;
                    if (addThese.Count > 0)
                    {
                        if ((this.m_Matches.Count == 0))
                        {
                            this.m_Matches = new ArrayList(addThese.Count);
                        }

                        if (this.m_Sorter != null)
                        {
                            // perform a sorted insert for each item
                            _SortedList sortThese = new _SortedList(this.m_Sorter, true);
                            foreach (ICpMedia obj in addThese)
                            {
                                sortThese.Set(this.m_Matches, obj, false);
                            }
                        }
                        else
                        {
                            this.m_Matches.AddRange((ICollection) addThese);
                        }

                        eventAdded = true;
                    }
                }
            }

            if (eventAdded)
            {
                if (this.OnMatchesAdded != null)
                {
                    this.OnMatchesAdded (this, addThese);
                }
            }
        }
        private CdsSpider GetSpider(CpMediaContainer mc)
        {
            if (InvokeRequired == true)
            {
                int tt = 5;
            }

            CdsSpider spider;
            lock (this.m_ContainerToSpider)
            {
                spider = (CdsSpider) this.m_ContainerToSpider[mc];

                if (spider == null)
                {
                    spider = new CdsSpider();
                    spider.OnMatchesAdded += new CdsSpider.Delegate_OnMatchesChanged(this.Sink_SpiderOnMatchesAdded);
                    spider.OnMatchesCleared += new CdsSpider.Delegate_OnMatchesChanged(this.Sink_SpiderOnMatchesCleared);
                    spider.OnMatchesRemoved += new CdsSpider.Delegate_OnMatchesChanged(this.Sink_SpiderOnMatchesRemoved);
                    spider.OnUpdateDone += new CdsSpider.Delegate_OnMatchesChanged(this.Sink_SpiderOnMatchesUpdated);

                    if (deviceTree.SelectedNode != null)
                    {
                        IMediaContainer selected = deviceTree.SelectedNode.Tag as IMediaContainer;

                        if (selected != null)
                        {
                            if (mc.Parent == selected)
                            {
                                spider.Comparer = MainForm.MatchContainers;
                            }
                            else if (mc.Parent != null)
                            {
                                if (
                                    (mc.Parent.Parent == selected) &&
                                    (! (selected is CpRootCollectionContainer)) &&
                                    (selected != null)
                                    )
                                {
                                    spider.Comparer = MainForm.MatchContainers;
                                }
                                else
                                {
                                    spider.Comparer = MainForm.MatchNever;
                                }
                            }
                            else
                            {
                                spider.Comparer = MainForm.MatchNever;
                            }
                        }
                        else
                        {
                            spider.Comparer = MainForm.MatchNever;
                        }
                    }
                    else
                    {
                        spider.Comparer = MainForm.MatchNever;
                    }

                    spider.Sorter = null;
                    spider.MonitorThis = mc;
                    this.m_ContainerToSpider[mc] = spider;
                }

                spider.Tag = DateTime.Now;
            }
            return spider;
        }
        private void ContainerChangedSink(CpRootContainer sender, CpMediaContainer thisChanged)
        {
            if (InvokeRequired) { this.Invoke(new CpRootContainer.Delegate_OnContainerChanged(ContainerChangedSink), sender, thisChanged); return; }

            // Update the tree view
            this.GetSpider(thisChanged);

            // Throw spiders on every child container
            foreach (CpMediaContainer cpc in thisChanged.Containers)
            {
                this.GetSpider(cpc);
            }

            try
            {
                lock (this.m_ContainerToSpider)
                {

                    TreeNode node = NodeTagSearch(cdsRootNode,thisChanged);
                    if (node == null)
                    {
                        //Update on unknown node
                        Event("Container " + thisChanged.Title,"Unknown Container Changed");
                    }
                    else
                    {
                        Event("Container " + thisChanged.Title,"Changed");

                        // get the curren listing of child containers for the
                        // container reporting the change
                        IList newcontainers = thisChanged.Containers;
                        if (newcontainers != null)
                        {
                            ArrayList noderemovelist = new ArrayList();
                            ArrayList existingcontainers = new ArrayList();

                            // iterate through the treeview's representation
                            // of the last known set of child containers
                            foreach (TreeNode n in node.Nodes)
                            {
                                // get the container associated with the node
                                CpMediaContainer c = (CpMediaContainer) n.Tag;

                                if (newcontainers.Contains(c) == false)
                                {
                                    // If the node's container is no longer associated
                                    // with the container, then the node should be removed.
                                    noderemovelist.Add(n);
                                }
                                else
                                {
                                    // If the node's container is still associated with
                                    // the container, then the container and node
                                    // should remain.
                                    existingcontainers.Add(c);
                                }
                            }

                            foreach (TreeNode n in noderemovelist)
                            {
                                this.CleanupRemovedNode(n);

                                // Remove the subtree of tree nodes.
                                // For some reason, we need to remove
                                // all of the nodes after we clean up.
                                // I had memory leaks when the nodes
                                // were removed from within the code
                                // for CleanupRemovedNode()
                                n.Remove();
                            }

                            foreach (CpMediaContainer c in newcontainers)
                            {
                                // Iterate through the new list of containers, but recurse
                                // and update the treeview only with containers that
                                // are brand new.
                                if (existingcontainers.Contains(c) == false)
                                {
                                    TreeNode cNode;
                                    // Depending on the type of container, ensure
                                    // that we use the right icon in the treeview.
                                    if (c.GetType() == typeof(CpRootContainer))
                                    {
                                        cNode = new TreeNode(c.Title,1,1);
                                    }
                                    else
                                    {
                                        cNode = new TreeNode(c.Title,2,3);
                                    }
                                    cNode.Tag = c;
                                    node.Nodes.Add(cNode);
                                    ContainerChangedSink(null,c);
                                }
                            }
                        }
                    }

                    cdsRootNode.Expand();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
 /// <summary>
 /// Creates a 
 /// <see cref="CpMediaContainer"/>
 /// object, given a metadata instantiation
 /// block.
 /// </summary>
 /// <param name="info">
 /// The metadata to use when instantiating the media.
 /// </param>
 /// <returns>a new media container</returns>
 public static CpMediaContainer CreateContainer(MediaBuilder.container info)
 {
     CpMediaContainer newObj = new CpMediaContainer();
     MediaBuilder.SetObjectProperties(newObj, info);
     return newObj;
 }
 private void OnAllRootsContainerChanged(CpRootContainer sender, CpMediaContainer thisChanged)
 {
     IncrementalFillMediaList();
 }
 /// <summary>
 /// Sets the container to a new parent.
 /// </summary>
 /// <param name="newParent"></param>
 internal void SetParent(CpMediaContainer newParent)
 {
     this.m_Parent = newParent;
 }
        /// <summary>
        /// Simply calls the owner object's implementation of Update().
        /// </summary>
        /// <exception cref="NullReferenceException">
        /// Thrown if the parent object is null.
        /// </exception>
        /// <exception cref="InvalidCastException">
        /// Thrown if the parent object is not a <see cref="CpMediaContainer"/>,
        /// which should always be the case.
        /// </exception>
        public void Update()
        {
            CpMediaContainer parent = (CpMediaContainer)this.Parent;

            parent.Update();
        }
 /// <summary>
 /// <see cref="CpMediaContainer"/> call this method to
 /// indicate that it's done giving notifications
 /// for new/removed/updated items for a while.
 /// </summary>
 /// <param name="thisChanged"></param>
 internal void NotifySinkUpdateDone(CpMediaContainer thisChanged)
 {
     if (thisChanged == this.m_MonitorThis)
     {
         this.m_BrowsingError = null;
         if (this.OnUpdateDone != null)
         {
             this.OnUpdateDone(this, null);
         }
     }
 }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersOfGoneContainer"/> calls this
        /// method to indicate that the container the spider happens
        /// to be monitoring no longer exists.
        /// </summary>
        /// <param name="thisChanged"></param>
        internal void NotifySinkContainerGone(CpMediaContainer thisChanged)
        {
            lock (this.m_Matches.SyncRoot)
            {
                if (thisChanged == this.MonitorThis)
                {
                    this.m_IsDead = true;
                    if (this.OnContainerGone != null)
                    {
                        this.OnContainerGone(this, null);
                    }

                    if (this.MonitorThis == thisChanged)
                    {
                        this.MonitorThis = null;
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="CpMediaContainer.NotifySpidersRemove"/> calls this
        /// method to indicate that child objects have been removed
        /// from the container.
        /// </summary>
        /// <param name="thisChanged">the container that witnessed the change</param>
        /// <param name="removeThese">an ArrayList of STRONG REFERENCES to <see cref="ICpMedia"/> objects</param>
        internal void NotifySinkRemove(CpMediaContainer thisChanged, ArrayList removeThese)
        {
            ArrayList removedObjects = new ArrayList(removeThese.Count);
            lock (this.m_Matches.SyncRoot)
            {
                foreach (ICpMedia obj in this.m_Matches)
                {
                    if (removeThese.Contains(obj))
                    {
                        removedObjects.Add(obj);
                    }
                }

                foreach (ICpMedia obj in removedObjects)
                {
                    this.m_Matches.Remove(obj);
                }
            }

            if (removedObjects.Count > 0)
            {
                if (this.OnMatchesRemoved != null)
                {
                    this.OnMatchesRemoved (this, removedObjects);
                }
            }
        }
 /// <summary>
 /// Sets the container to a new parent.
 /// </summary>
 /// <param name="newParent"></param>
 internal void SetParent(CpMediaContainer newParent)
 {
     this.m_Parent = newParent;
 }
 /// <summary>
 /// <see cref="CpMediaContainer"/> objects
 /// use this method to event changes in their state. This
 /// method simply fires the 
 /// <see cref="CpRootContainer.OnContainerChanged"/>
 /// event.
 /// </summary>
 /// <param name="thisChanged"><see cref="CpMediaContainer"/> that observed the change.</param>
 internal void FireOnContainerChanged(CpMediaContainer thisChanged)
 {
     if (this.OnContainerChanged != null)
     {
         this.OnContainerChanged(this, thisChanged);
     }
 }
 private void OnAllRootsContainerChanged(CpRootContainer sender, CpMediaContainer thisChanged)
 {
     IncrementalFillMediaList();
 }