public ViewModel()

in tools/Explorer/ViewModels/ViewModel.cs [452:962]


        public ViewModel(MainWindow view, Model model)
        {
            this.view = view;
            this.model = model;

            model.DatabaseChanging += (databaseName) => {
                this.Status = $"Opening database {databaseName}...";
            };

            model.DatabaseChanged += (databaseName) => {
                this.Status = "";
            };

            // Take care of events bubbling up from the model.
            model.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
            {
                if (e.PropertyName == "CaretPositionString")
                {
                    this.CaretPositionString = model.CaretPositionString;
                }
                else if (e.PropertyName == "Status")
                {
                    this.Status = model.Status;
                }
                else if (e.PropertyName == "Databases")
                {
                    this.Databases = model.Databases;
                }
                else if (e.PropertyName == "SelectedDatabase")
                {
                    this.SelectedDatabase = model.SelectedDatabase;
                    this.UpdateConnectionInfo();
                }
                else if (e.PropertyName == "QueryResult")
                {
                    this.QueryResult = model.QueryResult;
                }
                else if (e.PropertyName == "Username" || e.PropertyName == "HostName" || e.PropertyName == "SelectedDatabase")
                {
                    this.UpdateConnectionInfo();
                }
                else
                {
                    throw new ArgumentException("Property " + e.PropertyName + " was not handled");
                }
            };

            this.AboutBoxCommand = new RelayCommand(
                p =>
                {
                    var aboutBox = new Views.AboutBox();
                    aboutBox.Show();
                }
            );

            this.XQueryHelpCommand = new RelayCommand(
                p =>
                {
                    var psi = new ProcessStartInfo
                    {
                        FileName = "https://www.w3.org/standards/xml/query",
                        UseShellExecute = true
                    };
                    Process.Start(psi);
                }
            );

            this.BaseXHelpCommand = new RelayCommand(
                p =>
                {
                    var psi = new ProcessStartInfo
                    {
                        FileName = "http://BaseX.org",
                        UseShellExecute = true
                    };
                    Process.Start(psi);
                }
            );

            this.ShowExternalVariablesDialogCommand = new RelayCommand(
                p =>
                {
                    var window = new ExternalVariablesControl();
                    window.ShowDialog();
                }
            );

            this.SaveResultsCommand = new RelayCommand(
                p =>
                {
                    var dialog = new SaveFileDialog
                    {
                        DefaultExt = ".xml",
                        AddExtension = true,
                        Filter = "XML files (*.xml)|*.xml|CSV (Comma delimited) (*.csv)|*.csv|All files (*.*)|*.*",
                    };

                    var documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    dialog.InitialDirectory = string.Format(Properties.Settings.Default.QueriesPath, documentsFolder);

                    bool? res = dialog.ShowDialog();

                    if (res.HasValue && res.Value)
                    {
                        var stream = dialog.OpenFile();
                        this.view.ResultsEditor.Save(stream);
                    }
                }
            );
            
            this.OpenQueryCommand = new RelayCommand(
                p =>
                {
                    this.OpenQueryFile();
                }
            );

            this.ExitApplicationCommand = new RelayCommand(
                p => {
                    this.view.Close();
                });

            this.KeyboardExecuteQueryCommand = new RelayCommand(
                p =>
                {
                    var item = view.queryTabPage.SelectedItem as Wpf.Controls.TabItem;
                    this.ExecuteQueryCommand.Execute(item.Content);
                },
                p =>
                {
                    var item = view.queryTabPage.SelectedItem as Wpf.Controls.TabItem;
                    return this.ExecuteQueryCommand.CanExecute(item.Content);
                });

            this.KeyboardCheckQueryCommand = new RelayCommand(
                p =>
                {
                    var item = view.queryTabPage.SelectedItem as Wpf.Controls.TabItem;
                    this.CheckQueryCommand.Execute(item.Content);
                },
                p =>
                {
                    var item = view.queryTabPage.SelectedItem as Wpf.Controls.TabItem;
                    return this.CheckQueryCommand.CanExecute(item.Content);
                });


            this.WindowsCommand = new RelayCommand(
                p =>
                {
                    this.OpenWindowsDialog();
                },
                p => { return true; }
            );

            this.CloseAllWindowsCommand = new RelayCommand(
                p =>
                {
                    this.view.DetailsTab.Items.Clear();
                },
                p => this.view.DetailsTab.Items.Count > 0
            );

            this.SaveCommand = new RelayCommand(
                p => // The parameter is the index of the selected tab
                {
                    var tab = view.queryTabPage.SelectedValue as Wpf.Controls.TabItem;
                    var editor = tab.Content as QueryEditor;

                    if (string.IsNullOrEmpty(tab.Tag as string))
                    {
                        var filename = SaveQueryFileAs(editor);
                        if (filename != null)
                        {
                            // The user entered a file, he did not cancel
                            tab.Tag = filename;

                            // Update the tab's title
                            tab.Title = Path.GetFileNameWithoutExtension(filename);
                            // Remove dirty indication
                            editor.IsModified = false;
                        }
                    }
                    else
                    {
                        SaveQueryFile(tab.Tag as string, editor);
                        editor.IsModified = false;
                    }
                },
                p =>
                {
                    return true;
                }
            );

            this.SaveAsCommand = new RelayCommand(
                p => // The parameter is the index of the selected tab
                {
                    var tab = view.queryTabPage.SelectedValue as Wpf.Controls.TabItem;
                    var editor = tab.Content as QueryEditor;

                    var filename = SaveQueryFileAs(editor);
                    if (filename != null)
                    {
                        tab.Tag = filename;

                        // Update the tab's title
                        tab.Title = Path.GetFileNameWithoutExtension(filename);

                        editor.IsModified = false;
                    }
                },
                p =>
                {
                    return true;
                }
            );

            this.CreateNewQueryCommand = new RelayCommand(
                p =>
                {
                    this.view.queryTabPage.SelectedItem = this.CreateNewQueryTabItem();
                }
            );

            this.OpenQueuedQueriesWindow = new RelayCommand(
                p =>
                {
                    // Open the queued queries window. This is a singleton
                    this.QueuedQueriesWindow.Show();
                    this.QueuedQueriesWindow.Activate();

                });


            this.IncreaseResultsFontSizeCommand = new RelayCommand(
                p1 => Properties.Settings.Default.ResultsFontSize += 2,
                p2 => this.view.ResultsEditor != null && this.view.ResultsEditor.FontSize < 48
            );
        

            this.DecreaseResultsFontSizeCommand = new RelayCommand(
                p1 => Properties.Settings.Default.ResultsFontSize -= 2,
                p2 => this.view.ResultsEditor != null && this.view.ResultsEditor.FontSize > 8
            );
        

            this.IncreaseQueryFontSizeCommand = new RelayCommand(
                p1 => Properties.Settings.Default.QueryFontSize += 2,
                p2 =>
                {
                    if (this.view.queryTabPage == null)
                        return false;
                    else
                    {
                        return this.view.queryTabPage.SelectedContent is QueryEditor queryEditor && queryEditor.FontSize < 48;
                    }
                });
        

            this.DecreaseQueryFontSizeCommand = new RelayCommand(
                p1 => Properties.Settings.Default.QueryFontSize -= 2,
                p2 =>
                {
                    if (this.view.queryTabPage == null)
                        return false;
                    else
                    {
                        return this.view.queryTabPage.SelectedContent is QueryEditor queryEditor && queryEditor.FontSize > 8;
                    }
                }
            );
        
            this.ResultsUndoCommand = new RelayCommand(
                p =>
                {
                    ResultsEditor editor = p as ResultsEditor;
                    editor.Undo();
                },
                p =>
                {
                    if (p is ResultsEditor editor)
                        return editor.CanUndo;
                    else
                        return false;
                }
            );
        
            this.ResultsRedoCommand = new RelayCommand(
                p =>
                {
                    ResultsEditor editor = p as ResultsEditor;
                    editor.Redo();
                },
                p =>
                {
                    if (p is ResultsEditor editor)
                        return editor.CanRedo;
                    else
                        return false;
                }
            );

            this.QueryUndoCommand = new RelayCommand(
                p =>
                {
                    QueryEditor editor = p as QueryEditor;
                    editor.Undo();
                },
                p =>
                {
                    if (p is QueryEditor editor)
                        return editor.CanUndo;
                    else
                        return false;
                }
            );
        

            this.QueryRedoCommand = new RelayCommand(
                p =>
                {
                    QueryEditor editor = p as QueryEditor;
                    editor.Redo();
                },
                p =>
                {
                    if (p is QueryEditor editor)
                        return editor.CanRedo;
                    else
                        return false;
                }
            );

            this.ExecuteQueryCommand = new RelayCommand(
                async p =>
                {
                    var queryEditor = p as QueryEditor;
                    string query;

                    if (queryEditor.SelectionLength > 0)
                    {
                        // The user selected some text, so use that as the query.
                        query = queryEditor.SelectedText;
                    }
                    else
                    {
                        // No selection, so assume whole editor content
                        query = queryEditor.Text;
                    }

                    string result;
                    Stopwatch queryExecutionTime = new Stopwatch();
                    queryExecutionTime.Start();

                    var tabItem = queryEditor.Parent as Wpf.Controls.TabItem;
                    using (var session = await model.Server.GetSessionAsync(this.model.SelectedDatabase.Name))
                    {
                        try
                        {
                            tabItem.Icon = new Image
                            {
                                Source = new BitmapImage(new Uri("images/Hourglass_16x.png", UriKind.Relative)),
                                Width = 16,
                                Height = 16,
                            };
                            result = await this.ExecuteQueryAsync(query, session);
                        }
                        catch (Exception e)
                        {
                            result = e.Message;
                        }
                        finally
                        {
                            tabItem.Icon = null;
                        }
                    }

                    queryExecutionTime.Stop();

                    // Log the result in the QueryResult so we can select it again if the 
                    // user comes back to the query editor.
                    this.CachedQueryResult[queryEditor] = result;

#if !NETCOREAPP
                    // Log the fact that a query has been evaluated to telemetry.
                    (Application.Current as App).Telemetry?.TrackEvent(
                        "QueryExecution", new Dictionary<string, string>()
                        {
                            ["Query"] = query,
                            ["ExecutionTime"] = queryExecutionTime.ElapsedMilliseconds.ToString()
                        }
                    );
#endif
                    this.model.QueryResult = result;
                },

                // Running is allowed when there is text there to submit as a query and
                // there is a connection to the database.
                p =>
                {
                    if (p is QueryEditor queryEditor)
                        return (queryEditor.Text.Length > 0) && this.SelectedDatabase != null && !string.IsNullOrEmpty(this.SelectedDatabase.Name);
                    else
                        return false;
                });

            this.CheckQueryCommand = new RelayCommand(
               async p =>
               {
                   var queryEditor = p as QueryEditor;
                   string query;

                   if (queryEditor.SelectionLength > 0)
                   {
                       // The user selected some text, so use that as the query.
                       query = queryEditor.SelectedText;
                   }
                   else
                   {
                       // No selection, so assume whole editor content
                       query = queryEditor.Text;
                   }

                   string result;
                   Stopwatch queryCheckTime = new Stopwatch();
                   queryCheckTime.Start();

                   using (var session = await model.Server.GetSessionAsync(this.model.SelectedDatabase.Name))
                   {
                       try
                       {
                           result = await session.CheckQueryAsync(query);
                       }
                       catch (Exception e)
                       {
                           result = e.Message;
                       }
                   }

                   queryCheckTime.Stop();

                   // Log the result in the QueryResult so we can select it again if the 
                   // user comes back to the query editor.
                   this.CachedQueryResult[queryEditor] = result;

#if !NETCOREAPP
                   // Log the fact that a query has been evaluated to telemetry.
                   (Application.Current as App).Telemetry?.TrackEvent(
                      "CheckQuery", new Dictionary<string, string>()
                      {
                          ["Query"] = query,
                          ["ExecutionTime"] = queryCheckTime.ElapsedMilliseconds.ToString()
                      }
                  );
#endif
                   this.model.QueryResult = result;
               },

               // Running is allowed when there is text there to submit as a query and
               // there is a connection to the database.
               p =>
               {
                   if (p is QueryEditor queryEditor)
                       return (queryEditor.Text.Length > 0) && this.SelectedDatabase != null && !string.IsNullOrEmpty(this.SelectedDatabase.Name);
                   else
                       return false;
               });


            this.SubmitQueryCommand = new RelayCommand(
              async p =>
              {
                  var queryEditor = p as QueryEditor;
                  string query;

                  if (queryEditor.SelectionLength > 0)
                  {
                      // The user selected some text, so use that as the query.
                      query = queryEditor.SelectedText;
                  }
                  else
                  {
                      // No selection, so assume whole editor content
                      query = queryEditor.Text;
                  }

                  string result;
                  try
                  {
                      using var session = await this.model.GetSessionAsync(this.model.SelectedDatabase.Name);
                      result = await session.SubmitQueryAsync(query);
                  }
                  catch (Exception e)
                  {
                      result = e.Message;
                  }
                  this.model.JobIdToQuery[result] = query;
                  this.model.QueryResult = result;
              },

               // Running is allowed when there is text there to submit as a query and
               // there is a connection to the database.
               p =>
               {
                   if (p is QueryEditor queryEditor)
                       return (queryEditor.Text.Length > 0);
                   else
                       return false;
               });
        }