public EditorViewModel()

in tools/Graph Explorer/GraphExplorer/ViewModels/EditorViewModel.cs [517:705]


        public EditorViewModel(MainWindow v, Models.Model model)
        {
            this.view = v;
            this.model = model;

            // Initialize the mapping from names onto renderers.
            this.NodeRenderers = new Dictionary<string, INodeRenderer>();
            this.EdgeRenderers = new Dictionary<string, IEdgeRenderer>();

            // Load the list of renderers through MEF.
            var catalog = new AggregateCatalog();

            // Put in the directory where the table extractor lives into the catalog
            // Use the directory where the main executable is found
            var assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            catalog.Catalogs.Add(new DirectoryCatalog(assemblyPath));

            CompositionContainer container = new CompositionContainer(catalog);

            try
            {
                // Load all the plugins in the catalog, i.e. in the directory provided.
                container.SatisfyImportsOnce(this);

                // at this point the extractor should have been filled in. The metadata is
                // also available.
                foreach (var plugin in this.NodePlugins)
                {
                    this.NodeRenderers[plugin.Metadata.Label] = plugin.Value.CreateRenderer(model);
                }

                foreach (var plugin in this.EdgePlugins)
                {
                    this.EdgeRenderers[plugin.Metadata.Label] = plugin.Value.CreateRenderer(model);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            NodeSelected += UpdateNodeInfoPage;
            EdgeSelected += UpdateEdgeInfoPage;

            this.SetTheme(this.model.IsDarkMode);

            // Handler for events in this view model
            this.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
            {
            };

            // Handler for events bubbling up from the model.
            model.PropertyChanged += async (object sender, PropertyChangedEventArgs e) =>
            {
                if (e.PropertyName == nameof(Model.QueryFontSize))
                {
                    QueryEditorFontSize = this.model.QueryFontSize;
                    this.OnPropertyChanged(nameof(QueryEditorFontSize));
                }
                else if (e.PropertyName == nameof(Model.ErrorMessage))
                {
                    this.ErrorMessage = this.model.ErrorMessage;
                    this.OnPropertyChanged(nameof(ErrorMessage));
                }
                else if (e.PropertyName == nameof(Model.CaretPositionString))
                {
                    this.CaretPositionString = this.model.CaretPositionString;
                }
                else if (e.PropertyName == nameof(Model.EditorPosition))
                {
                    var p = this.model.EditorPosition;

                    this.view.CypherEditor.TextArea.Caret.Position = new ICSharpCode.AvalonEdit.TextViewPosition(p.Item1, p.Item2);
                    this.view.CypherEditor.TextArea.Caret.BringCaretToView();
                }
                else if (e.PropertyName == nameof(Model.IsDarkMode))
                {
                    this.SetTheme(this.model.IsDarkMode);

                    // Update the view
                    await this.RepaintNodesAsync(this.model.NodesShown);
                }
                else if (e.PropertyName == nameof(Model.StyleDocumentSource))
                {
                    // Store the file along with the script
                    var uri = this.model.ScriptUri;
                    var fileName = uri.LocalPath;

                    var directory = Path.GetDirectoryName(fileName);
                    var configFileName = Path.Combine(directory, "Config.js");
                    File.WriteAllText(configFileName, model.StyleDocumentSource);

                    // The config file was changed, but the browser will keep a cached copy. To avoid
                    // this, the script is updated to reflect a new file name.
                    var script = File.ReadAllText(fileName);

                    // The script contains a reference to the config file:
                    //     <script type="text/javascript" src="Config.js?ts=1234567890"></script>
                    // The digit sequence needs to be changed so that the browser does not
                    // use a cached version of the config file.
                    var idx = script.IndexOf("Config.js?ts=") + "Config.js?ts=".Length;

                    var cnt = 0;
                    while (char.IsDigit(script[idx + cnt])) 
                        cnt++;

                    script = script.Remove(idx, cnt);
                    script = script.Insert(idx, DateTime.Now.Ticks.ToString());

                    File.WriteAllText(fileName, script);

                    this.view.Browser.NavigationCompleted += Browser_NavigationCompleted;

                    this.view.Browser.Reload();
                }
                else if (e.PropertyName == nameof(Model.NodesShown))
                {
                    // The nodes have been changed, so do a repaint
                    await this.RepaintNodesAsync(this.model.NodesShown);
                }
                else if (e.PropertyName == nameof(Model.QueryResults))
                {
                    if (this.GraphModeSelected)
                    {
                        this.model.NodesShown = Model.HarvestNodeIdsFromGraph(this.model.QueryResults);
                    }
                    else
                    {
                        var html = Model.GenerateHtml(this.model.QueryResults);
                        this.view.TextBrowser.NavigateToString(html);
                    }
                }
            };

            this.executeQueryCommand = new RelayCommand(
                 async p =>
                 {
                     string source = this.GetSource();

                     this.SelectedNode = 0;
                     this.SelectedEdge = 0;

                     // First execute the query to get the result graph in memory:
                     List<IRecord> result = await this.model.ExecuteCypherAsync(source);
                     if (result != null)
                     {
                         // The query executed correctly. 
                         if (this.model.ConnectResultNodes)
                         {

                             if (this.GraphModeSelected && !Model.CanBeRenderedAsGraph(result))
                             {
                                 this.GraphModeSelected = false;
                                 this.TextModeSelected = true;
                             }
                             this.model.QueryResults = result;

                         }
                         else
                         {

                             string resultJson = Model.GenerateJSON(result);

                             var backgroundColorBrush = this.view.FindResource("MaterialDesignPaper") as SolidColorBrush;
                             var foregroundColorBrush = this.view.FindResource("MaterialDesignBody") as SolidColorBrush;

                             var backgroundColor = JavascriptColorString(backgroundColorBrush.Color);
                             var foregroundColor = JavascriptColorString(foregroundColorBrush.Color);

                             await view.Browser.ExecuteScriptAsync(string.Format("draw({0}, '{1}', '{2}');", resultJson, backgroundColor, foregroundColor));

                         }
                     }
                 },

                 // Running is allowed when there is text there to submit as a query and
                 // there is a connection to the database.
                 p =>
                 {
                     return v.CypherEditor.Document.Text.Any();
                 });

            this.printGraphCommand = new RelayCommand(
                async p =>
                {
                    await this.view.Browser.ExecuteScriptAsync("this.print();");
                }
            );
        }