public BuildControl()

in src/StructuredLogViewer/Controls/BuildControl.xaml.cs [66:301]


        public BuildControl(Build build, string logFilePath)
        {
            InitializeComponent();

            UpdateWatermark();

            searchLogControl.ExecuteSearch = (searchText, maxResults, cancellationToken) =>
            {
                var search = new Search(
                    new[] { Build },
                    Build.StringTable.Instances,
                    maxResults,
                    SettingsService.MarkResultsInTree
                    //, Build.StringTable // disable validation in production
                    );
                var results = search.FindNodes(searchText, cancellationToken);
                return results;
            };
            searchLogControl.ResultsTreeBuilder = BuildResultTree;
            searchLogControl.WatermarkDisplayed += () =>
            {
                Search.ClearSearchResults(Build, SettingsService.MarkResultsInTree);
                UpdateWatermark();
            };

            propertiesAndItemsSearch = new PropertiesAndItemsSearch();

            propertiesAndItemsControl.ExecuteSearch = (searchText, maxResults, cancellationToken) =>
            {
                var context = GetProjectContext() as TimedNode;
                if (context == null)
                {
                    return null;
                }

                var results = propertiesAndItemsSearch.Search(
                    context,
                    searchText,
                    maxResults,
                    SettingsService.MarkResultsInTree,
                    cancellationToken);

                return results;
            };
            propertiesAndItemsControl.ResultsTreeBuilder = BuildResultTree;

            UpdatePropertiesAndItemsWatermark();
            propertiesAndItemsControl.WatermarkDisplayed += () =>
            {
                UpdatePropertiesAndItemsWatermark();
            };
            propertiesAndItemsControl.RecentItemsCategory = "PropertiesAndItems";

            SetProjectContext(null);

            VirtualizingPanel.SetIsVirtualizing(treeView, SettingsService.EnableTreeViewVirtualization);

            DataContext = build;
            Build = build;

            if (build.SourceFilesArchive != null)
            {
                // first try to see if the source archive was embedded in the log
                sourceFileResolver = new SourceFileResolver(build.SourceFiles.Values);
            }
            else
            {
                // otherwise try to read from the .zip file on disk if present
                sourceFileResolver = new SourceFileResolver(logFilePath);
            }

            if (Build.Statistics.TimedNodeCount > 1000)
            {
                projectGraphTab.Visibility = Visibility.Collapsed;
            }

            // Search Log | Properties and Items | Find in Files
            sharedTreeContextMenu = new ContextMenu();
            var sharedCopyAllItem = new MenuItem() { Header = "Copy All" };
            var sharedCopySubtreeItem = new MenuItem() { Header = "Copy subtree" };
            sharedCopyAllItem.Click += (s, a) => CopyAll();
            sharedCopySubtreeItem.Click += (s, a) => CopySubtree();
            sharedTreeContextMenu.Items.Add(sharedCopyAllItem);
            sharedTreeContextMenu.Items.Add(sharedCopySubtreeItem);

            // Files
            filesTreeContextMenu = new ContextMenu();
            var filesCopyAllItem = new MenuItem { Header = "Copy All" };
            var filesCopyPathsItem = new MenuItem { Header = "Copy file paths" };
            var filesCopySubtreeItem = new MenuItem { Header = "Copy subtree" };
            filesCopyAllItem.Click += (s, a) => CopyAll();
            filesCopyPathsItem.Click += (s, a) => CopyPaths();
            filesCopySubtreeItem.Click += (s, a) => CopySubtree();
            filesTreeContextMenu.Items.Add(filesCopyAllItem);
            filesTreeContextMenu.Items.Add(filesCopyPathsItem);
            filesTreeContextMenu.Items.Add(filesCopySubtreeItem);

            // Build Log
            var contextMenu = new ContextMenu();
            contextMenu.Opened += ContextMenu_Opened;
            copyItem = new MenuItem() { Header = "Copy" };
            copySubtreeItem = new MenuItem() { Header = "Copy subtree" };
            viewSubtreeTextItem = new MenuItem() { Header = "View subtree text" };
            searchInSubtreeItem = new MenuItem() { Header = "Search in subtree" };
            excludeSubtreeFromSearchItem = new MenuItem() { Header = "Exclude subtree from search" };
            goToTimeLineItem = new MenuItem() { Header = "Go to timeline" };
            goToTracingItem = new MenuItem() { Header = "Go to tracing" };
            copyChildrenItem = new MenuItem() { Header = "Copy children" };
            sortChildrenItem = new MenuItem() { Header = "Sort children" };
            copyNameItem = new MenuItem() { Header = "Copy name" };
            copyValueItem = new MenuItem() { Header = "Copy value" };
            viewSourceItem = new MenuItem() { Header = "View source" };
            viewFullTextItem = new MenuItem { Header = "View full text" };
            showTimeItem = new MenuItem() { Header = "Show time and duration" };
            openFileItem = new MenuItem() { Header = "Open File" };
            copyFilePathItem = new MenuItem() { Header = "Copy file path" };
            preprocessItem = new MenuItem() { Header = "Preprocess" };
            hideItem = new MenuItem() { Header = "Hide" };
            runItem = new MenuItem() { Header = "Run" };
            debugItem = new MenuItem() { Header = "Debug" };
            copyItem.Click += (s, a) => Copy();
            copySubtreeItem.Click += (s, a) => CopySubtree(treeView);
            viewSubtreeTextItem.Click += (s, a) => ViewSubtreeText();
            searchInSubtreeItem.Click += (s, a) => SearchInSubtree();
            excludeSubtreeFromSearchItem.Click += (s, a) => ExcludeSubtreeFromSearch();
            goToTimeLineItem.Click += (s, a) => GoToTimeLine();
            goToTracingItem.Click += (s, a) => GoToTracing();
            copyChildrenItem.Click += (s, a) => CopyChildren();
            sortChildrenItem.Click += (s, a) => SortChildren();
            copyNameItem.Click += (s, a) => CopyName();
            copyValueItem.Click += (s, a) => CopyValue();
            viewSourceItem.Click += (s, a) => Invoke(treeView.SelectedItem as BaseNode);
            viewFullTextItem.Click += (s, a) => ViewFullText(treeView.SelectedItem as BaseNode);
            showTimeItem.Click += (s, a) => ShowTimeAndDuration();
            openFileItem.Click += (s, a) => OpenFile();
            copyFilePathItem.Click += (s, a) => CopyFilePath();
            preprocessItem.Click += (s, a) => Preprocess(treeView.SelectedItem as IPreprocessable);
            runItem.Click += (s, a) => Run(treeView.SelectedItem as Task, debug: false);
            debugItem.Click += (s, a) => Run(treeView.SelectedItem as Task, debug: true);
            hideItem.Click += (s, a) => Delete();

            contextMenu.Items.Add(runItem);
            contextMenu.Items.Add(debugItem);
            contextMenu.Items.Add(viewSourceItem);
            contextMenu.Items.Add(viewFullTextItem);
            contextMenu.Items.Add(openFileItem);
            contextMenu.Items.Add(preprocessItem);
            contextMenu.Items.Add(searchInSubtreeItem);
            contextMenu.Items.Add(excludeSubtreeFromSearchItem);
            contextMenu.Items.Add(goToTimeLineItem);
            contextMenu.Items.Add(goToTracingItem);
            contextMenu.Items.Add(copyItem);
            contextMenu.Items.Add(copySubtreeItem);
            contextMenu.Items.Add(copyFilePathItem);
            contextMenu.Items.Add(viewSubtreeTextItem);
            contextMenu.Items.Add(copyChildrenItem);
            contextMenu.Items.Add(sortChildrenItem);
            contextMenu.Items.Add(copyNameItem);
            contextMenu.Items.Add(copyValueItem);
            contextMenu.Items.Add(showTimeItem);
            contextMenu.Items.Add(hideItem);

            var existingTreeViewItemStyle = (Style)Application.Current.Resources[typeof(TreeViewItem)];
            var treeViewItemStyle = new Style(typeof(TreeViewItem), existingTreeViewItemStyle);
            treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay }));
            treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.IsSelectedProperty, new Binding("IsSelected") { Mode = BindingMode.TwoWay }));
            treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.VisibilityProperty, new Binding("IsVisible") { Mode = BindingMode.TwoWay, Converter = new BooleanToVisibilityConverter() }));

            treeViewItemStyle.Setters.Add(new EventSetter(MouseDoubleClickEvent, (MouseButtonEventHandler)OnItemDoubleClick));
            treeViewItemStyle.Setters.Add(new EventSetter(PreviewMouseRightButtonDownEvent, (MouseButtonEventHandler)OnPreviewMouseRightButtonDown));
            treeViewItemStyle.Setters.Add(new EventSetter(RequestBringIntoViewEvent, (RequestBringIntoViewEventHandler)TreeViewItem_RequestBringIntoView));
            treeViewItemStyle.Setters.Add(new EventSetter(KeyDownEvent, (KeyEventHandler)OnItemKeyDown));

            treeView.ContextMenu = contextMenu;
            treeView.ItemContainerStyle = treeViewItemStyle;
            treeView.KeyDown += TreeView_KeyDown;
            treeView.SelectedItemChanged += TreeView_SelectedItemChanged;
            treeView.GotFocus += (s, a) => ActiveTreeView = treeView;

            ActiveTreeView = treeView;

            searchLogControl.ResultsList.ItemContainerStyle = treeViewItemStyle;
            searchLogControl.ResultsList.SelectedItemChanged += ResultsList_SelectionChanged;
            searchLogControl.ResultsList.GotFocus += (s, a) => ActiveTreeView = searchLogControl.ResultsList;
            searchLogControl.ResultsList.ContextMenu = sharedTreeContextMenu;

            propertiesAndItemsControl.ResultsList.ItemContainerStyle = treeViewItemStyle;
            propertiesAndItemsControl.ResultsList.SelectedItemChanged += ResultsList_SelectionChanged;
            propertiesAndItemsControl.ResultsList.GotFocus += (s, a) => ActiveTreeView = propertiesAndItemsControl.ResultsList;
            propertiesAndItemsControl.ResultsList.ContextMenu = sharedTreeContextMenu;

            if (archiveFile != null)
            {
                findInFilesControl.ExecuteSearch = FindInFiles;
                findInFilesControl.ResultsTreeBuilder = BuildFindResults;

                findInFilesControl.GotFocus += (s, a) => ActiveTreeView = findInFilesControl.ResultsList;
                findInFilesControl.ResultsList.ItemContainerStyle = treeViewItemStyle;
                findInFilesControl.ResultsList.GotFocus += (s, a) => ActiveTreeView = findInFilesControl.ResultsList;
                findInFilesControl.ResultsList.ContextMenu = sharedTreeContextMenu;

                filesTab.Visibility = Visibility.Visible;
                findInFilesTab.Visibility = Visibility.Visible;
                PopulateFilesTab();
                filesTree.ResultsList.ItemContainerStyle = treeViewItemStyle;

                filesTree.TextChanged += FilesTree_SearchTextChanged;

                var text =
@"This log contains the full text of projects and imported files used during the build.
You can use the 'Files' tab in the bottom left to view these files and the 'Find in Files' tab for full-text search.
For many nodes in the tree (Targets, Tasks, Errors, Projects, etc) pressing SPACE or ENTER or double-clicking 
on the node will navigate to the corresponding source code associated with the node.

More functionality is available from the right-click context menu for each node.
Right-clicking a project node may show the 'Preprocess' option if the version of MSBuild was at least 15.3.";
                build.Unseal();
#if DEBUG
                text = build.StringTable.Intern(text);
#endif
                build.AddChild(new Note { Text = text });
                build.Seal();
            }

            breadCrumb.SelectionChanged += BreadCrumb_SelectionChanged;

            Loaded += BuildControl_Loaded;

            preprocessedFileManager = new PreprocessedFileManager(this.Build, sourceFileResolver);
            preprocessedFileManager.DisplayFile += filePath => DisplayFile(filePath);

            navigationHelper = new NavigationHelper(Build, sourceFileResolver);
            navigationHelper.OpenFileRequested += filePath => DisplayFile(filePath);

            centralTabControl.SelectionChanged += CentralTabControl_SelectionChanged;
        }