public VisualizerNode ReplaceChild(VisualizerNode old, VisualizerNode newChild, bool ensureExpanded)
            {
                var copy = new VisualizerNode(obj, ImmutableList.CreateRange(children.Select(c => c == old ? newChild : c)),
                                              ensureExpanded ? true : expanded, selected, level, annotationsMap);

                old.parent = null;
                return(parent == null ? copy : parent.ReplaceChild(this, copy, ensureExpanded));
            }
Beispiel #2
0
        NodeInfo CreateViewNode(IView view, NodesCollectionInfo collectionToAddViewNode, IInspectedObject modelNode, int level, List <NodeInfo> nodesToCollapse)
        {
            string nodeText = modelNode.DisplayName;

            if (modelNode.Comment != "")
            {
                nodeText += " (" + modelNode.Comment + ")";
            }

            bool createCollapsed    = false;
            bool createLazilyLoaded = false;

            if (level < 5)
            {
                if (OnNodeCreated != null)
                {
                    var args = new NodeCreatedEventArgs()
                    {
                        NodeObject = VisualizerNode.FromObject(modelNode)
                    };
                    OnNodeCreated(this, args);
                    createCollapsed    = args.CreateCollapsed.GetValueOrDefault(createCollapsed);
                    createLazilyLoaded = args.CreateLazilyLoaded.GetValueOrDefault(createLazilyLoaded);
                }
                if (createLazilyLoaded && !view.TreeSupportsLoadingOnExpansion)
                {
                    createLazilyLoaded = false;
                }
            }

            var viewNode = view.CreateNode(nodeText, modelNode, collectionToAddViewNode);

            if (createLazilyLoaded)
            {
                view.CreateNode(lazyLoadTag, lazyLoadTag, viewNode.ChildrenNodesCollection);
            }
            else
            {
                foreach (var child in modelNode.Children)
                {
                    CreateViewNode(view, viewNode.ChildrenNodesCollection, child, level + 1, nodesToCollapse);
                }
            }
            if (createCollapsed)
            {
                nodesToCollapse.Add(viewNode);
            }
            return(viewNode);
        }
        static MessageTimestamp GetNodeTimestamp(VisualizerNode node)
        {
            var obj = (node as VisualizerNode)?.InspectedObject;
            StateInspectorEvent referenceEvt = null;

            if (obj != null)
            {
                referenceEvt = obj.StateChangeHistory.FirstOrDefault();
            }
            if (referenceEvt != null)
            {
                return(referenceEvt.Trigger.Timestamp.Adjust(referenceEvt.Output.LogSource.TimeOffsets));
            }
            return(MessageTimestamp.MaxValue);
        }
            public VisualizerNode Follow(VisualizerNode rootNode)
            {
                VisualizerNode ret             = null;
                bool           inspectingRoots = true;

                foreach (var segment in path)
                {
                    VisualizerNode found = (
                        from n in inspectingRoots ? rootNode.Children : ret.Children
                        let obj = n.InspectedObject
                                  where obj != null
                                  where inspectingRoots ? (obj == segment && obj.Owner.Key == outputsGroupKey) : (obj == segment)
                                  select n
                        ).FirstOrDefault();
                    if (found == null)
                    {
                        return(null);
                    }
                    ret             = found;
                    inspectingRoots = false;
                }
                return(ret);
            }
        static VisualizerNode MakeRootNode(
            IReadOnlyList <IStateInspectorOutputsGroup> groups,
            EventHandler <NodeCreatedEventArgs> nodeCreationHandler,
            ImmutableDictionary <ILogSource, string> annotationsMap,
            VisualizerNode existingRoot
            )
        {
            var existingRoots = existingRoot.Children.ToLookup(c => c.InspectedObject);

            var children = ImmutableList.CreateRange(
                groups.SelectMany(
                    group => group.Roots.Select(rootObj =>
            {
                var existingNode = existingRoots[rootObj].FirstOrDefault();
                if (existingNode != null)
                {
                    return(existingNode.SetAnnotationsMap(annotationsMap));
                }
                var newNode = MakeVisualizerNode(rootObj, 1, annotationsMap);
                newNode.SetInitialProps(nodeCreationHandler);                                 // call handler on second phase when all children and parents are initiated
                return(newNode);
            })
                    )
                );

            children = children.Sort((n1, n2) => MessageTimestamp.Compare(GetNodeTimestamp(n1), GetNodeTimestamp(n2)));

            var result = new VisualizerNode(null, children, true, false, 0, annotationsMap);

            if (!result.HasSelectedNodes && result.Children.Count > 0)
            {
                result = result.Children[0].Select(true);
            }

            return(result);
        }
Beispiel #6
0
        bool IPresenter.TrySelectObject(ILogSource source, TextLogEventTrigger creationTrigger, Func <IVisualizerNode, int> disambiguationFunction)
        {
            EnsureTreeView();

            Func <IInspectedObject, bool> predecate = obj =>
            {
                return(obj.Owner.Outputs.Any(o => o.LogSource == source) &&
                       obj.StateChangeHistory.Any(change => change.Trigger.CompareTo(creationTrigger) == 0));
            };

            var candidates = EnumRoots().SelectMany(EnumTree).Where(predecate).ToList();

            if (candidates.Count > 0)
            {
                IInspectedObject obj;
                if (candidates.Count == 1 || disambiguationFunction == null)
                {
                    obj = candidates[0];
                }
                else
                {
                    obj = candidates
                          .Select(c => new { Obj = c, Rating = disambiguationFunction(VisualizerNode.FromObject(c)) })
                          .OrderByDescending(x => x.Rating)
                          .First().Obj;
                }
                var n = FindOrCreateNode(obj);
                if (n != null)
                {
                    view.SelectedNodes = new[] { n.Value };
                    view.ScrollSelectedNodesInView();
                    return(true);
                }
            }
            return(false);
        }
 public InspectedObjectPath(VisualizerNode node) : this(node?.InspectedObject)
 {
 }
        public StateInspectorPresenter(
            IView view,
            IStateInspectorVisualizerModel model,
            IUserNamesProvider shortNames,
            ILogSourcesManager logSources,
            LoadedMessages.IPresenter loadedMessagesPresenter,
            IBookmarks bookmarks,
            IModelThreads threads,
            IPresentersFacade presentersFacade,
            IClipboardAccess clipboardAccess,
            SourcesManager.IPresenter sourcesManagerPresenter,
            IColorTheme theme,
            IChangeNotification changeNotification
            )
        {
            this.view                    = view;
            this.model                   = model;
            this.shortNames              = shortNames;
            this.threads                 = threads;
            this.presentersFacade        = presentersFacade;
            this.bookmarks               = bookmarks;
            this.clipboardAccess         = clipboardAccess;
            this.sourcesManagerPresenter = sourcesManagerPresenter;
            this.loadedMessagesPresenter = loadedMessagesPresenter;
            this.theme                   = theme;
            this.changeNotification      = changeNotification.CreateChainedChangeNotification(initiallyActive: false);

            var annotationsVersion = 0;

            logSources.OnLogSourceAnnotationChanged += (sender, e) =>
            {
                annotationsVersion++;
                changeNotification.Post();
            };

            var getAnnotationsMap = Selectors.Create(
                () => logSources.Items,
                () => annotationsVersion,
                (sources, _) =>
                sources
                .Where(s => !s.IsDisposed && !string.IsNullOrEmpty(s.Annotation))
                .ToImmutableDictionary(s => s, s => s.Annotation)
                );

            VisualizerNode rootNode   = new VisualizerNode(null, ImmutableList <VisualizerNode> .Empty, true, false, 0, ImmutableDictionary <ILogSource, string> .Empty);
            var            updateRoot = Updaters.Create(
                () => model.Groups,
                getAnnotationsMap,
                (groups, annotationsMap) => rootNode = MakeRootNode(groups, OnNodeCreated, annotationsMap, rootNode)
                );

            this.getRootNode = () =>
            {
                updateRoot();
                return(rootNode);
            };
            this.updateRootNode = reducer =>
            {
                var oldRoot = getRootNode();
                var newRoot = reducer(oldRoot);
                if (oldRoot != newRoot)
                {
                    rootNode = newRoot;
                    changeNotification.Post();
                }
            };

            this.getSelectedNodes = Selectors.Create(
                getRootNode,
                (root) =>
            {
                var result = ImmutableArray.CreateBuilder <VisualizerNode>();

                void traverse(VisualizerNode n)
                {
                    if (!n.HasSelectedNodes)
                    {
                        return;
                    }
                    if (n.IsSelected)
                    {
                        result.Add(n);
                    }
                    foreach (var c in n.Children)
                    {
                        traverse(c);
                    }
                }

                traverse(root);

                return(result.ToImmutable());
            }
                );

            this.getSelectedInspectedObjects = Selectors.Create(
                getSelectedNodes,
                nodes => ImmutableArray.CreateRange(nodes.Select(n => n.InspectedObject))
                );

            this.getStateHistoryItems = Selectors.Create(
                getSelectedInspectedObjects,
                () => selectedHistoryEvents,
                MakeSelectedObjectHistory
                );

            this.getIsHistoryItemBookmarked = Selectors.Create(
                () => bookmarks.Items,
                boormarksItems =>
            {
                Predicate <IStateHistoryItem> result = (item) =>
                {
                    var change = (item as StateHistoryItem)?.Event;
                    if (change == null || change.Output.LogSource.IsDisposed)
                    {
                        return(false);
                    }
                    var bmk = bookmarks.Factory.CreateBookmark(
                        change.Trigger.Timestamp.Adjust(change.Output.LogSource.TimeOffsets),
                        change.Output.LogSource.GetSafeConnectionId(), change.Trigger.StreamPosition, 0);
                    var pos = boormarksItems.FindBookmark(bmk);
                    return(pos.Item2 > pos.Item1);
                };
                return(result);
            }
                );

            this.getFocusedMessageInfo = () => loadedMessagesPresenter.LogViewerPresenter.FocusedMessage;

            this.getFocusedMessageEqualRange = Selectors.Create(
                getFocusedMessageInfo,
                focusedMessageInfo =>
            {
                var cache = new Dictionary <IStateInspectorOutputsGroup, FocusedMessageEventsRange>();
                Func <IStateInspectorOutputsGroup, FocusedMessageEventsRange> result = forGroup =>
                {
                    if (!cache.TryGetValue(forGroup, out FocusedMessageEventsRange eventsRange))
                    {
                        eventsRange = new FocusedMessageEventsRange(focusedMessageInfo,
                                                                    forGroup.Events.CalcFocusedMessageEqualRange(focusedMessageInfo));
                        cache.Add(forGroup, eventsRange);
                    }
                    return(eventsRange);
                };
                return(result);
            }
                );

            this.getPaintNode = Selectors.Create(
                getFocusedMessageEqualRange,
                MakePaintNodeDelegate
                );

            this.getFocusedMessagePositionInHistory = Selectors.Create(
                getStateHistoryItems,
                getFocusedMessageInfo,
                (changes, focusedMessage) =>
            {
                return
                (focusedMessage == null ? null :
                 new ListUtils.VirtualList <StateInspectorEvent>(changes.Length,
                                                                 i => changes[i].Event).CalcFocusedMessageEqualRange(focusedMessage));
            }
                );

            this.getCurrentTimeLabelText = Selectors.Create(
                getFocusedMessageInfo,
                focusedMsg => focusedMsg != null ? $"at {focusedMsg.Time}" : ""
                );

            this.getCurrentProperties = Selectors.Create(
                getSelectedInspectedObjects,
                getFocusedMessageEqualRange,
                () => selectedProperty,
                MakeCurrentProperties
                );

            this.getPropertyItems = Selectors.Create(
                getCurrentProperties,
                props => (IReadOnlyList <IPropertyListItem>)props.Cast <IPropertyListItem>().ToImmutableArray()
                );

            this.getObjectsProperties = Selectors.Create(
                getCurrentProperties,
                props => (IReadOnlyList <KeyValuePair <string, object> >)props.Select(p => p.ToDataSourceItem()).ToImmutableArray()
                );

            view.SetViewModel(this);
        }
            public VisualizerNode Select(bool value)
            {
                var copy = new VisualizerNode(obj, children, expanded, value, level, annotationsMap);

                return(parent.ReplaceChild(this, copy, true));
            }
            public VisualizerNode Expand(bool value)
            {
                var copy = new VisualizerNode(obj, children, value, selected, level, annotationsMap);

                return(parent.ReplaceChild(this, copy, false));
            }