示例#1
0
        /// <summary>
        /// Does a depth-first traversal, resolving all referenced sub-documents. Does not traverse
        /// any node twice. This effectively treats a directed graph as a tree.</summary>
        /// <param name="root">Root timeline</param>
        /// <param name="resolved">Resolved hash set to add to</param>
        private void ResolveAll(IHierarchicalTimeline root, HashSet <IHierarchicalTimeline> resolved)
        {
            resolved.Add(root);
            foreach (ITimelineReference refInterface in root.References)
            {
                TimelineReference reference = (TimelineReference)refInterface;
                //reference.Resolve();

                IDocument referencedDocument = null;
                Uri       refUri             = reference.Uri;
                if (refUri != null)
                {
                    referencedDocument = LoadOrCreateDocument(refUri, false); //this is not a master document
                }
                if (referencedDocument != null)
                {
                    // Switch from a possible relative path to an absolute path
                    reference.Uri = referencedDocument.Uri;

                    IHierarchicalTimeline child = reference.Target;
                    if (child != null &&
                        !resolved.Contains(child))
                    {
                        ResolveAll(child, resolved);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Counts the number of references to this document by all TimelineDocuments</summary>
        /// <param name="document">Document</param>
        /// <returns>Number references to document</returns>
        private int NumReferences(ITimelineDocument document)
        {
            int count = 0;

            foreach (IDocument topDoc in m_documentRegistry.Documents)
            {
                ITimelineDocument topTimelineDoc = topDoc as ITimelineDocument;
                if (topTimelineDoc != null)
                {
                    if (document == topTimelineDoc)
                    {
                        count++;
                    }

                    foreach (TimelinePath path in D2dTimelineControl.GetHierarchy(topTimelineDoc.Timeline))
                    {
                        IHierarchicalTimeline target = ((ITimelineReference)path.Last).Target;
                        if (document == target.As <ITimelineDocument>())
                        {
                            count++;
                        }
                    }
                }
            }
            return(count);
        }
示例#3
0
        private bool MoveSnapFilter(IEvent testEvent, TimelineControl.SnapOptions options)
        {
            ITimelineReference movingReference = options.FilterContext as ITimelineReference;

            if (movingReference == null)
            {
                return(true);
            }

            IHierarchicalTimeline movingTimeline = movingReference.Target;

            if (movingTimeline == null)
            {
                return(true);
            }

            ITimeline owningTimeline = null;

            if (testEvent is ITimelineReference)
            {
                owningTimeline = ((ITimelineReference)testEvent).Parent;
            }
            else if (testEvent is IInterval)
            {
                owningTimeline = ((IInterval)testEvent).Track.Group.Timeline;
            }
            else if (testEvent is IKey)
            {
                owningTimeline = ((IKey)testEvent).Track.Group.Timeline;
            }
            else if (testEvent is IMarker)
            {
                owningTimeline = ((IMarker)testEvent).Timeline;
            }

            // Is the reference being compared to an object that it owns? Never snap!
            if (owningTimeline == movingTimeline)
            {
                return(false);
            }

            // Is the reference being compared against a sibling object? Snap away.
            if (owningTimeline == movingReference.Parent)
            {
                return(true);
            }

            // to-do: support a true hierarchy. We can't support directed acyclic graphs because
            //  the Layout implementation uses a Dictionary of ITimelineObjects and the same object
            //  can't have multiple layout rectangles. We could support a tree hierarchy, though.
            //// The test object may be a grandchild of the moving reference. Look for a parent.
            //owningTimeline = owningTimeline.Parent;

            return(true);
        }
示例#4
0
        /// <summary>
        /// Loads the document at the given URI. Creates a D2dTimelineRenderer and D2dTimelineControl
        /// (through TimelineDocument's Renderer property) to render and display timelines.
        /// If isMasterDocument is true and if the file doesn't exist, a new document is created.</summary>
        /// <param name="uri">URI of document to load</param>
        /// <param name="isMasterDocument">True iff is master document</param>
        /// <returns>TimelineDocument loaded</returns>
        private TimelineDocument LoadOrCreateDocument(Uri uri, bool isMasterDocument)
        {
            // Documents need to have a absolute Uri, so that the relative references to sub-documents
            //  are not ambiguous, and so that the FileWatcherService can be used.
            string filePath;

            if (uri.IsAbsoluteUri)
            {
                filePath = uri.LocalPath;
            }
            else if (!isMasterDocument)
            {
                filePath = PathUtil.GetAbsolutePath(uri.OriginalString,
                                                    Path.GetDirectoryName(s_repository.ActiveDocument.Uri.LocalPath));
                uri = new Uri(filePath, UriKind.Absolute);
            }
            else
            {
                filePath = PathUtil.GetAbsolutePath(uri.OriginalString, Directory.GetCurrentDirectory());
                uri      = new Uri(filePath, UriKind.Absolute);
            }

            // Check if the repository contains this Uri. Remember that document Uris have to be absolute.
            bool             isNewToThisEditor = true;
            DomNode          node     = null;
            TimelineDocument document = (TimelineDocument)s_repository.GetDocument(uri);

            if (document != null)
            {
                node = document.DomNode;
                isNewToThisEditor = false;
            }
            else if (File.Exists(filePath))
            {
                // read existing document using standard XML reader
                using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    DomXmlReader reader = new DomXmlReader(s_schemaLoader);
                    node = reader.Read(stream, uri);
                }
            }
            else if (isMasterDocument)
            {
                // create new document by creating a Dom node of the root type defined by the schema
                node = new DomNode(Schema.timelineType.Type, Schema.timelineRootElement);
            }

            if (node != null)
            {
                if (document == null)
                {
                    document = node.Cast <TimelineDocument>();

                    D2dTimelineRenderer renderer = CreateTimelineRenderer();
                    document.Renderer = renderer;
                    renderer.Init(document.TimelineControl.D2dGraphics);

                    string      fileName    = Path.GetFileName(filePath);
                    ControlInfo controlInfo = new ControlInfo(fileName, filePath, StandardControlGroup.Center);

                    //Set IsDocument to true to prevent exception in command service if two files with the
                    //  same name, but in different directories, are opened.
                    controlInfo.IsDocument = true;

                    TimelineContext timelineContext = document.Cast <TimelineContext>();
                    timelineContext.ControlInfo = controlInfo;

                    document.Uri = uri;

                    if (isMasterDocument)
                    {
                        s_repository.ActiveDocument = document;//adds 'document'
                    }
                    else
                    {
                        // For sub-documents, we want ActiveDocument to remain the main document so that
                        //  TimelineValidator can identify if a sub-document or master document is being
                        //  modified.
                        IDocument previous = s_repository.ActiveDocument;
                        s_repository.ActiveDocument = document; //adds 'document'
                        s_repository.ActiveDocument = previous; //restores master document
                    }
                }

                IHierarchicalTimeline hierarchical = document.Timeline as IHierarchicalTimeline;
                if (hierarchical != null)
                {
                    ResolveAll(hierarchical, new HashSet <IHierarchicalTimeline>());
                }

                // Listen to events if this is the first time we've seen this.
                if (isNewToThisEditor)
                {
                    // The master document/context needs to listen to events on any sub-document
                    //  so that transactions can be cancelled correctly.
                    if (isMasterDocument)
                    {
                        node.AttributeChanging += DomNode_AttributeChanging;
                    }
                    else
                    {
                        DomNode masterNode = s_repository.ActiveDocument.As <DomNode>();
                        node.SubscribeToEvents(masterNode);
                    }
                }

                // Initialize Dom extensions now that the data is complete
                node.InitializeExtensions();
            }

            return(document);
        }
示例#5
0
        /// <summary>
        /// Does a depth-first traversal, resolving all referenced sub-documents. Does not traverse 
        /// any node twice. This effectively treats a directed graph as a tree.</summary>
        /// <param name="root">Root timeline</param>
        /// <param name="resolved">Resolved hash set to add to</param>
        private void ResolveAll(IHierarchicalTimeline root, HashSet<IHierarchicalTimeline> resolved)
        {
            resolved.Add(root);
            foreach (ITimelineReference refInterface in root.References)
            {
                TimelineReference reference = (TimelineReference)refInterface;
                //reference.Resolve();

                IDocument referencedDocument = null;
                Uri refUri = reference.Uri;
                if (refUri != null)
                    referencedDocument = LoadOrCreateDocument(refUri, false); //this is not a master document

                if (referencedDocument != null)
                {
                    // Switch from a possible relative path to an absolute path
                    reference.Uri = referencedDocument.Uri;

                    IHierarchicalTimeline child = reference.Target;
                    if (child != null &&
                        !resolved.Contains(child))
                    {
                        ResolveAll(child, resolved);
                    }
                }
            }
        }