using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace GraphingCalculator { /// /// Interaction logic for EvaluateWindow.xaml /// public partial class EvaluateWindow : Window { private Dictionary variables = new Dictionary(); #region Properties public string InputExpression { get { return inputExpression.Text; } set { inputExpression.Text = value; } } #endregion #region Constructors public EvaluateWindow() { InitializeComponent(); } public EvaluateWindow(string txt) { InitializeComponent(); InputExpression = txt; // Convenience: evaluate already buttonEval_Click(this, new RoutedEventArgs()); } #endregion #region User input private void buttonAdd_Click(object sender, RoutedEventArgs e) { string errorMessage = ""; double val = 0; outputResult.Clear(); // Verify boxes are not empty if (inputVarName.Text == "" || inputVarValue.Text == "") errorMessage = "Name or value cannot be empty!"; // Get number if (errorMessage == "" && !double.TryParse(inputVarValue.Text, out val)) { try { Expression expr = new Expression(inputVarValue.Text); val = expr.Evaluate(); } catch { errorMessage = "Value must be a number!"; } } // Verify name is unique if (errorMessage == "" && variables.ContainsKey(inputVarName.Text)) { var res = MessageBox.Show("A variable with the same name already exists. Replace it with the new value?", "Warning", MessageBoxButton.YesNo); if (res != MessageBoxResult.Yes) errorMessage = "A variable with the same name already exists!"; } // Verify name doesn't contain forbidden characters if (errorMessage == "") { bool ok = char.IsLetter (inputVarName.Text.First()); foreach (var i in inputVarName.Text) if (!char.IsLetterOrDigit(i)) ok = false; if (!ok) errorMessage = "Forbidden variable name, it can only contain letters or digits!"; } // Add variable if (errorMessage == "") { variables[inputVarName.Text] = val; // Remove if it exists already for (int i = 0; i < listVars.Items.Count; i++) { string str = listVars.Items[i] as string; if (str != null && str.StartsWith(inputVarName.Text + " = ")) listVars.Items.RemoveAt(i); } // Add variable listVars.Items.Add(inputVarName.Text + " = " + inputVarValue.Text); // Clear text boxes inputVarName.Clear(); inputVarValue.Clear(); } else { outputResult.Foreground = Brushes.DarkRed; outputResult.Text = "Error adding variable: " + errorMessage; } } private void buttonEval_Click(object sender, RoutedEventArgs e) { // Create expression Expression expression = new Expression(inputExpression.Text); double result = 0; // Add variables foreach (var i in variables) expression.Variables.Add(i.Key, i.Value); // Try to evaluate try { result = expression.Evaluate(); } catch (Exception ex) { outputResult.Text = "Error evaluating: " + ex.Message; outputResult.Foreground = Brushes.DarkRed; #region Log Log.LogEvent("Failed to evaluate expression '{0}'. Message: {1}", inputExpression.Text, ex.Message); Log.LogEvent("> Stack trace: {0}", ex.StackTrace); if (listVars.Items.Count > 0) Log.LogEvent("> Variables: "); foreach (var i in listVars.Items) Log.LogEvent(">> {0}", i.ToString()); #endregion return; } // Output results outputResult.Text = Math.Round(result, 15).ToString(); outputResult.Foreground = Brushes.Black; #region Log // Log what happened here Log.LogEvent("Evaluated expression '{0}' result={1}", inputExpression.Text, outputResult.Text); if (listVars.Items.Count > 0) Log.LogEvent("> WHERE: "); foreach (var i in listVars.Items) Log.LogEvent(">> {0}", i.ToString()); #endregion } private void buttonClose_Click(object sender, RoutedEventArgs e) { this.Close(); } private void contextEdit_Click(object sender, RoutedEventArgs e) { // Make sure we have 1 selected item if (listVars.SelectedItems.Count != 1) return; // Get key var item = listVars.SelectedItem as string; if (item == null) return; string key = item.Substring(0, item.IndexOf(" = ")); // Place in input boxes inputVarName.Text = key; inputVarValue.Text = variables[key].ToString(); // Remove item listVars.Items.Remove(listVars.SelectedItem); variables.Remove(key); } private void contextDelete_Click(object sender, RoutedEventArgs e) { // Make sure we have 1 selected item if (listVars.SelectedItems.Count != 1) return; // Get key var item = listVars.SelectedItem as string; if (item == null) return; string key = item.Substring(0, item.IndexOf(" = ")); // Remove listVars.Items.Remove(listVars.SelectedItem); variables.Remove(key); } private void contextClear_Click(object sender, RoutedEventArgs e) { listVars.Items.Clear(); variables.Clear(); } private void Window_KeyUp(object sender, KeyEventArgs e) { e.Handled = true; if (e.Key == Key.Escape) buttonClose_Click(this, new RoutedEventArgs()); else if (e.Key == Key.Enter) buttonEval_Click(this, new RoutedEventArgs()); else if (e.Key == Key.Insert) buttonAdd_Click(this, new RoutedEventArgs()); else e.Handled = false; } #endregion } }