Exemplo n.º 1
0
        // undo a previously made singular cell change, pop from changeList
        public void UndoCell(Tuple <Cell, string> tuple)
        {
            Cell cell = tuple.Item1; // get cell from tuple in changeList

            // get the column and row of the cell
            int column = cell.ColumnIndex;
            int row    = cell.RowIndex;

            Cell temp = this.GetCell(column, row);            // get the corresponding node in the spreadsheet

            undoRedoCell = temp;                              // set undoRedoCell to this spreadsheet cell, will help avoid duplications of undos

            Cell saveCell = new SpreadsheetCell(column, row); // create a new cell that will be added to the redo changeList

            // copy the spreadsheet cell's current property values over to this new cell
            saveCell.Color = temp.Color;
            saveCell.Text  = temp.Text;

            string change = tuple.Item2; // copy the string from the tuples second value

            AddRedo(saveCell, change);   // pass the new cell and string to AddRedo function

            // change the spreadsheet cell's property values based on the tuple cell's values
            temp.Color = cell.Color;
            temp.Text  = cell.Text;

            undoChangeList.RemoveAt(undoChangeList.Count - 1); // remove the cell from the undo change list
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks for Circular References in Spreadsheet Cells
        /// </summary>
        /// <param name="variableCell">Cell that current cell depends on</param>
        /// <param name="currentCell">The current cell being changed</param>
        /// <returns></returns>
        public bool CheckCircularReference(SpreadsheetCell variableCell, SpreadsheetCell currentCell)
        {
            // Self-Reference is a form of Circular Reference so return
            if (variableCell == currentCell)
            {
                return(true);
            }

            // If current cell is not in its dependent dictionary return
            if (!dependentCells.ContainsKey(currentCell))
            {
                return(false);
            }

            foreach (SpreadsheetCell dependentCell in dependentCells[currentCell])
            {
                // Recursively Check Other Cell Dependencies
                if (CheckCircularReference(variableCell, dependentCell))
                {
                    // Circular Reference Found
                    return(true);
                }
            }

            // Dependencies Have No Circular References
            return(false);
        }
Exemplo n.º 3
0
 private string CalculateValue(string text, SpreadsheetCell senderCell)
 {
     text = text.Substring(1);                                                          //removes the first character of the string, which is =
     if (text.Length > 1)                                                               //if there are variables to replace, they will be at least 2 chars
     {
         MatchCollection           splitOperands   = Regex.Matches(text, @"\w+\.?\d*"); //temporary way to get all the variables.
         HashSet <SpreadsheetCell> referencedCells = new HashSet <SpreadsheetCell>();
         foreach (Match mat in splitOperands)
         {
             if (!Regex.Match(mat.Value, @"^\d+").Success)     // if the match starts with a number then its not a coordinate and we dont have to retrieve a value.
             {
                 SpreadsheetCell cell = GetCell(mat.Value) as SpreadsheetCell;
                 cell.ValueChanged += senderCell.OnValueChanged;
                 senderCell.AddReferenceToCell(cell);        //tell the sender cell what its referencing. Hashsets can only have unique values, so adding something that is already here will do nothing.
                 referencedCells.Add(cell);                  //keep track of which cells this specific expression looks for.
                 text = text.Replace(mat.Value, cell.Value); //replaces that substring in the text with that cell's value.
             }
         }
         referencedCells.SymmetricExceptWith(senderCell.ReferencedCells); //removes all the cell references that are the same.
         foreach (SpreadsheetCell cell in referencedCells)                // all the cells that were referenced previously but are no longer being referenced.
         {
             cell.ValueChanged -= senderCell.OnValueChanged;              // unsubsribes from the cell that is no longer being referenced.
             senderCell.RemoveReferenceToCell(cell);
         }
         ExpTree tree = new ExpTree(text);
         text = tree.Eval().ToString();
     }
     return(text);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Will show the color dialog and allow change the background color of a cell.
        /// </summary>
        /// <param name="sender">Spreadsheet.</param>
        /// <param name="e">Background Color Notification.</param>
        private void ChangeBackgToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog myDialog = new ColorDialog();

            // Keeps the user from selecting a custom color.
            myDialog.AllowFullOpen = true;

            // Allows the user to get help. (The default is false.)
            myDialog.ShowHelp = true;

            // If OK was not pressed, then set the cd color to white
            if (myDialog.ShowDialog() != DialogResult.OK)
            {
                myDialog.Color = Color.FromArgb(-1);
            }

            // For all selected cells, change the background color in the spreadsheet.
            foreach (DataGridViewCell gridCell in this.dataGridView1.SelectedCells)
            {
                SpreadsheetCell dataCell = this.mainSpreadSheet.GetCell(gridCell.RowIndex, gridCell.ColumnIndex);
                this.mainSpreadSheet.SetCellColor(gridCell.RowIndex, gridCell.ColumnIndex, (uint)myDialog.Color.ToArgb());
            }

            this.dataGridView1.ClearSelection(); // Clears off user highlighted cells.
        }
Exemplo n.º 5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="cell"></param>
 /// <returns></returns>
 private bool CheckSelfReference(SpreadsheetCell sender, SpreadsheetCell cell)
 {
     if (cell == sender)
     {
         sender.CellValue = "!(self reference)";
         this.OnPropertyChanged(sender, "CellChanged");
         return(true);
     }
     return(false);
 }
Exemplo n.º 6
0
 /// <summary>
 /// Clears the dependency of a cell from any lists
 /// </summary>
 /// <param name="cell">Cell to clear dependency</param>
 private void RemoveCellDependency(SpreadsheetCell cell)
 {
     foreach (HashSet <SpreadsheetCell> dependencySet in this.dependentCells.Values)
     {
         if (dependencySet.Contains(cell))
         {
             dependencySet.Remove(cell);
         }
     }
 }
        private void parseSingleVariable(SpreadsheetCell c)
        {
            string txt = c.Text;                        //use text field to set value
            int    row = 0, col = 0, singularValue = 0; //=ColRow (ex. =B2)
            double cellVal = 0.0, junk = 0.0;
            bool   res = false;

            res = int.TryParse(txt.Substring(1), out singularValue);
            if (txt.Substring(1) == c.ToVarName)
            {
                c.Value   = "#REF!";
                c.bgColor = "#FF0000";
                return;
            }
            if (!res)
            {
                int.TryParse(txt.Substring(2), out row); //parse row#  //substring to grab all numbers for row
                row--;                                   //change indexing mode
                if ('a' <= txt[1] && txt[1] <= 'z')      //columns are letters => ascii math
                {
                    col = (int)(txt[1] - 'a');           //support lower-case letters (extra)
                }
                else
                {
                    col = (int)(txt[1] - 'A');           //support upper-case (default)
                }
                //Debug.WriteLine("row={0}, col={1}", row, col);
                Double.TryParse(this.sheet[row][col].Value, out cellVal);
                string temp = this.sheet[row][col].Value; //set value (not text, else infinite loop)
                c.Value = temp;                           // singularValue;
                                                          //int.TryParse(t.Substring(1), out curRow); //get row
                                                          //int col = (int)(t[0] - 'A');                  //get column
                                                          //double.TryParse(sheet[row - 1][col].Value, out leafVal);  //find value mapped to given cell
                if (!c.references.TryGetValue(txt.Substring(1), out junk))
                {
                    if (this.sheet[row][col].Value != "")            //this bypasses short-circuit eval.
                    {
                        c.references.Add(txt.Substring(1), cellVal); //add dictionary reference to cell
                    }
                    else
                    {
                        c.references.Add(txt.Substring(1), 0); //add null dictionary reference to cell
                    }
                }
                if (!sheet[row][col].referencedBy.TryGetValue(c.ToVarName, out junk))
                {
                    sheet[row][col].referencedBy.Add(c.ToVarName, cellVal); //make cell know it's referenced
                }
            }
            else
            {
                c.Value = singularValue.ToString();
            }
        }
Exemplo n.º 8
0
        // push undo to change list
        public void AddUndo(object sender, string change)
        {
            Cell copy = sender as Cell;

            // the three conditions that allow for a push are as follows:
            // if list is empty or the cell attempting to push is not the same as undoRedoCell or the cell is a different cell entirely,
            // then push to list
            if (undoStack.Count == 0 || undoRedoCell != copy || (copy.RowIndex != undoChangeList[undoChangeList.Count - 1].Item1.RowIndex || copy.ColumnIndex != undoChangeList[undoChangeList.Count - 1].Item1.ColumnIndex))
            {
                // copy column and row from sender cell
                int column = copy.ColumnIndex;
                int row    = copy.RowIndex;

                Cell temp = new SpreadsheetCell(column, row); // get corresponding cell from spreadsheet

                // copy property values from sender cell
                temp.Color = copy.Color;
                temp.Text  = copy.Text;

                string menuChange = string.Empty;

                // set string to be passed to tuple
                if (change == "text" || change == "color")
                {
                    menuChange = change;
                }
                else
                {
                    menuChange = "cell";
                }

                // create new tuple with created cell and string
                Tuple <Cell, string> stackValue;
                stackValue = new Tuple <Cell, string>(temp, menuChange);

                undoChangeList.Add(stackValue); // push tuple to undo change list

                // only pushes to undo stack if the change is a text change
                // colors are done elsewhere due to needing to allow for group changes
                if (change == "text")
                {
                    List <Cell> list = new List <Cell>();
                    list.Add(copy);
                    undoStack.Add(list);
                }
            }

            string cellChange = undoChangeList[undoChangeList.Count - 1].Item2; // get string from pushed tuple

            OnAddUndo(this, cellChange);                                        // fire event that notifies UI of change

            undoRedoCell = null;                                                // reset undoRedoCell to null
        }
Exemplo n.º 9
0
        /// <summary>
        /// Subscribe Dependent Cells as Listeners
        /// </summary>
        /// <param name="listener"></param>
        /// <param name="variables"></param>
        private void SubscribeDependencies(SpreadsheetCell listener, string[] variables)
        {
            foreach (string variable in variables)
            {
                SpreadsheetCell variableCell = GetCell(variable);

                if (variableCell != null)
                {
                    variableCell.DependencyChanged += listener.OnDependencyChanged;
                }
            }
        }
Exemplo n.º 10
0
        // Pull function
        private void Pull(string text, SpreadsheetCell currentCell)
        {
            string pull;
            string pulledValue;
            int    pullColumn;
            int    pullRow;

            int[] rowDigits = new int[2];

            if (text[0] == '=')
            {
                pull       = text.Substring(1, text.Length - 1);
                pull       = pull.Trim();
                pullColumn = char.ToUpper(pull[0]) - 65;

                pull = pull.Substring(1, pull.Length - 1);

                if (pull.Length > 1)
                {
                    for (int i = 0; i < pull.Length; i++)
                    {
                        rowDigits[i] = pull[i] - 48;
                    }

                    pullRow  = 10 * rowDigits[0];
                    pullRow += rowDigits[1] - 1;
                }

                else
                {
                    pullRow = pull[0] - 49;
                }

                pulledValue = this.GetCell(pullRow, pullColumn).CellText;

                // If the pulled cell is also pulling from another cell, keep following
                if (pulledValue[0] == '=')
                {
                    Pull(pulledValue, currentCell);
                }
                // End condition to bring out
                else
                {
                    currentCell.ValueText = pulledValue;
                }
            }

            else
            {
                currentCell.ValueText = text;
            }
            return;
        }
Exemplo n.º 11
0
#pragma warning restore SA1130 // Use lambda syntax

        /// <summary>
        /// Initializes a new instance of the <see cref="Spreadsheet"/> class.It creates an array of 2D
        /// rows and columns .
        /// </summary>
        /// <param name="rowCount"> Takes number of rows in order to initalize in the 2d array.
        /// </param>
        /// <param name="columnCount"> Takes numbers of columns in order to initalize in the 2d array.
        /// </param>
        public Spreadsheet(int rowCount, int columnCount)
        {
            this.ArrayOfCells = new Cell[rowCount, columnCount];
            for (int i = 0; i < this.NumberOfRows; i++)
            {
                for (int j = 0; j < this.NumberOfColumns; j++)
                {
                    Cell cell = new SpreadsheetCell(i, j);
                    cell.PropertyChanged   += this.OnSpreadsheetPropertyChanged;
                    this.ArrayOfCells[i, j] = cell;
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Sets a variable name and value for dictionary of ExpressionTree
        /// </summary>
        /// <param name="expressionTree">ExpressionTree being evaluated</param>
        /// <param name="varName">Name of the variable</param>
        private void SetCellVariable(SpreadsheetEngine.ExpressionTree expressionTree, string varName)
        {
            SpreadsheetCell cell = this.GetCell(varName);

            if (double.TryParse(cell.CellValue, out double cellValue))
            {
                expressionTree.SetVariable(varName, cellValue);
            }
            else
            {
                expressionTree.SetVariable(varName, 0.0);
            }
        }
Exemplo n.º 13
0
        // Event handler when SpreadsheetCell is changed
        public void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // Value is what is shown in form
            // Text is the formula held in cell
            string          text        = e.PropertyName;
            SpreadsheetCell currentCell = (SpreadsheetCell)sender;

            Pull(text, currentCell);

            // Raising the event that a cell value has been changed
            CellPropertyChanged(currentCell, new PropertyChangedEventArgs(currentCell.ValueText));
            return;
        }
Exemplo n.º 14
0
 public SpreadSheet(int row, int column)
 {
     cells = new SpreadsheetCell[row, column];
     for (int i = 0; i < row; ++i)
     {
         for (int j = 0; j < column; ++j)
         {
             cells[i, j] = new SpreadsheetCell(i, j);
             //subscribe so that the spreadsheet class knows when a cell value is changed
             cells[i, j].PropertyChanged += Cells_PropertyChanged;
         }
     }
 }
        /// <summary>
        /// This method implements when a cell's Value changes.
        /// it gets updates in the DataGridView.
        /// Event Handler.
        /// </summary>
        /// <param name="sender"> for the cell.</param>
        /// <param name="e">for thecell. </param>
        private void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SpreadsheetCell updateCell = sender as SpreadsheetCell;

            if (e.PropertyName == "Value")
            {
                // Modify the value in the ColumnIndex cell of the RowIndex row.
                this.dataGridView1.Rows[updateCell.RowIndex].Cells[updateCell.ColumnIndex].Value = updateCell.Value;
            }
            else if (e.PropertyName == "Color")
            {
                this.dataGridView1.Rows[updateCell.RowIndex].Cells[updateCell.ColumnIndex].Style.BackColor = Color.FromArgb((int)updateCell.BGColor);
            }
        }
Exemplo n.º 16
0
        public Spreadsheet(int columns, int rows)
        {
            columnCount = columns;
            rowCount    = rows;

            cells = new SpreadsheetCell[columns, rows]; //allocating memory
            for (int i = 0; i < columns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    cells[i, j] = new SpreadsheetCell(i, j);                    //creates a cell with its position in the array.
                    cells[i, j].PropertyChanged += Spreadsheet_PropertyChanged; //tells the cell to call Spreadsheet_propertyChanged when PropertyChanged is called.
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Cells in UI grid values are set to the values of the logic engine cell.
        /// </summary>
        /// <param name="sender">sender.</param>
        /// <param name="e">e.</param>
        private void MainSpreadSheet_PropertyChangedValue(object sender, PropertyChangedEventArgs e)
        {
            SpreadsheetCell temp = sender as SpreadsheetCell;

            if (e.PropertyName == "Value")
            {
                SpreadsheetCell cell = (SpreadsheetCell)sender;
                this.dataGridView1[cell.ColumnIndex, cell.RowIndex].Value = cell.Value;
            }

            if (e.PropertyName == "BGColor")
            {
                this.dataGridView1.Rows[temp.RowIndex].Cells[temp.ColumnIndex].Style.BackColor = Color.FromArgb((int)temp.BGColor);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// method that invokes the property changed event.
        /// </summary>
        /// <param name="sender">object being changed.</param>
        /// <param name="e">property being changed.</param>
        protected void OnCellPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SpreadsheetCell sheetCell = (SpreadsheetCell)sender;

            if (e.PropertyName == "Color")
            {
                this.CellPropertyChanged("Color", new PropertyChangedEventArgs(sheetCell.RowIndex.ToString() + ","
                                                                               + sheetCell.ColIndex.ToString() + "," + sheetCell.BGColor));
                return;
            }

            if (e.PropertyName == "Value")
            {
                this.CellPropertyChanged(this, new PropertyChangedEventArgs(sheetCell.RowIndex.ToString() + ","
                                                                            + sheetCell.ColIndex.ToString() + "," + sheetCell.Value));
                return;
            }

            if (sheetCell.Text.Length == 0 || sheetCell.Text[0] != '=')
            {
                sheetCell.Value = sheetCell.Text;
                if (sheetCell.VarDict.Count > 0)
                {
                    foreach (KeyValuePair <string, double> index in sheetCell.VarDict.ToList())
                    {
                        sheetCell.UnmatchTreeToCell(this.GetCellText(index.Key));
                    }
                }

                this.CellPropertyChanged(sheetCell, new PropertyChangedEventArgs("Text"));
            }
            else
            {
                sheetCell.BuildTree(sheetCell.Text.Substring(1));
                if (this.CheckReference(sheetCell))
                {
                    foreach (KeyValuePair <string, double> index in sheetCell.VarDict.ToList())
                    {
                        sheetCell.MatchTreeToCell(this.GetCellText(index.Key));
                    }

                    sheetCell.Value = sheetCell.EvaluateExpression();
                }

                this.CellPropertyChanged(this, new PropertyChangedEventArgs(sheetCell.RowIndex.ToString() + ","
                                                                            + sheetCell.ColIndex.ToString() + "," + sheetCell.Value));
            }
        }
Exemplo n.º 19
0
        public void Clearsheet()
        {
            int row    = cells.GetLength(0);
            int column = cells.GetLength(1);

            cells = new SpreadsheetCell[row, column];
            for (int i = 0; i < row; ++i)
            {
                for (int j = 0; j < column; ++j)
                {
                    cells[i, j] = new SpreadsheetCell(i, j);
                    //subscribe so that the spreadsheet class knows when a cell value is changed
                    cells[i, j].PropertyChanged += Cells_PropertyChanged;
                }
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Called when a Cell's Property Changes to Update Spreadsheet
        /// </summary>
        /// <param name="sender">Cell whose property changed</param>
        /// <param name="e">Type of property change</param>
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CellText")
            {
                // Clear Dictionary of Dependencies
                RemoveCellDependency(sender as SpreadsheetCell);

                // Build Expression Tree and Evaluate Cell Value
                EvaluateSpreadsheetCell(sender as SpreadsheetCell);
            }
            else if (e.PropertyName == "BGColor")
            {
                // Tell UI to Update Cell Color
                SpreadsheetCell cellChanged = sender as SpreadsheetCell;
                CellPropertyChanged(cellChanged, new PropertyChangedEventArgs("BGColorChanged"));
            }
        }
Exemplo n.º 21
0
        //returns a list of the used cells
        public List <Cell> GetUsedCells()
        {
            List <Cell> returnedCells = new List <Cell>();

            for (int i = 0; i < columnCount; i++)
            {
                for (int j = 0; j < rowCount; j++)
                {
                    SpreadsheetCell tempCell = GetCell(i, j) as SpreadsheetCell;
                    if (tempCell.Value != null)
                    {
                        returnedCells.Add(tempCell); //copies the cell at that position in the array.
                    }
                }
            }
            return(returnedCells);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Adds a cell to a list of cells that depend on another cell
        /// </summary>
        /// <param name="listenerCell">New cell to add</param>
        /// <param name="variables">List of existing dependencies</param>
        private void AddCellDependency(SpreadsheetCell listenerCell, string[] variables)
        {
            foreach (string variable in variables)
            {
                SpreadsheetCell variableCell = this.GetCell(variable);

                if (variableCell != null)
                {
                    if (!this.dependentCells.ContainsKey(variableCell))
                    {
                        this.dependentCells[variableCell] = new HashSet <SpreadsheetCell>();
                    }

                    this.dependentCells[variableCell].Add(listenerCell);
                }
            }
        }
Exemplo n.º 23
0
        // push change to stack
        public void AddRedo(object sender, string change)
        {
            Cell cell = sender as SpreadsheetCell;

            // copy column and row from sender cell
            int column = cell.ColumnIndex;
            int row    = cell.RowIndex;

            Cell temp = new SpreadsheetCell(column, row); // create new cell to be used in tuple

            // copy property values from sender cell to tuple cell
            temp.Color = cell.Color;
            temp.Text  = cell.Text;

            Tuple <Cell, string> tuple = new Tuple <Cell, string>(temp, change); // create new tuple

            redoChangeList.Add(tuple);                                           // push tuple to redo change list

            OnAddRedo(sender, change);                                           // fire event that notifies UI of change
        }
        public event PropertyChangedEventHandler CellPropertyChanged; //event field

        //Constructor -- initializes sheet and bound variables, creates cells, and subscribes to events
        public SpreadsheetClass(int nRows, int nCols)
        {
            sheet = new SpreadsheetCell[nRows][];//init rows array (1st dimension)
            for (int i = 0; i < nRows; i++)
            {
                sheet[i] = new SpreadsheetCell[nCols];//init cols array (2nd dimension)
            }
            for (int i = 0; i < nRows; i++)
            {
                for (int j = 0; j < nCols; j++)                               //initialize cells & locations
                {
                    SpreadsheetCell nCell = SpreadsheetCell.CreateCell(i, j); //make each cell
                    sheet[i][j]            = nCell;                           //assign to correct place
                    nCell.PropertyChanged += OnCellPropertyChanged;           //subscribe to events
                }
            }

            columnCount = nCols;
            rowCount    = nRows;//set both bounds
        }
Exemplo n.º 25
0
        /// <summary>
        /// Will trigger when a cell property has changed.
        /// </summary>
        /// <param name="sender"> SpreadsheetCell. </param>
        /// <param name="e"> arguments. </param>
        public void CellPropertyChanged(object sender, EventArgs e)
        {
            if (sender.GetType() == typeof(SpreadsheetCell))
            {
                SpreadsheetCell cell = sender as SpreadsheetCell;
                if (this.Variables.ContainsKey(cell.Index))
                {
                    if (double.TryParse(cell.Value, out double val))
                    {
                        this.Variables[cell.Index] = val;
                    }
                    else
                    {
                        this.Variables[cell.Index] = 0;
                    }

                    this.ExpressionCell.Value = this.Evaluate().ToString();
                }
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Spreadsheet"/> class.
        /// </summary>
        /// <param name="rows">The number of rows of cells to add to the spreadsheet.</param>
        /// <param name="columns">The number of columns of cells to add to the spreadsheet.</param>
        public Spreadsheet(int rows, int columns)
        {
            SpreadsheetCell[,] cells = new SpreadsheetCell[rows, columns];

            // Initialize each cell within the array.
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    // Create new cell, subscribe to property changed event, add to 2D array.
                    SpreadsheetCell cell = new SpreadsheetCell(i, j);
                    cell.PropertyChanged += this.Sheet_PropertyChanged;
                    cells[i, j]           = cell;
                }
            }

            // Update member variables.
            this.Cells       = cells;
            this.rowCount    = rows;
            this.columnCount = columns;
        }
Exemplo n.º 27
0
        public Spreadsheet(int columns, int rows, List <Cell> cellList)
        {
            columnCount = columns;
            rowCount    = rows;

            cells = new SpreadsheetCell[columns, rows]; //allocating memory
            for (int i = 0; i < columns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    cells[i, j] = new SpreadsheetCell(i, j);                    //creates a cell with its position in the array.
                    cells[i, j].PropertyChanged += Spreadsheet_PropertyChanged; //tells the cell to call Spreadsheet_propertyChanged when PropertyChanged is called.
                }
            }

            foreach (Cell cell in cellList)
            {
                cells[cell.ColumnIndex, cell.RowIndex] = cell as SpreadsheetCell;
                cells[cell.ColumnIndex, cell.RowIndex].PropertyChanged += Spreadsheet_PropertyChanged; //tells the cell to call Spreadsheet_propertyChanged when PropertyChanged is called.
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// this function loads the xml file.
        /// </summary>
        /// <param name="stream"> file name.</param>
        public void Load(Stream stream)
        {
            Cell temporyCell = new SpreadsheetCell(-1, -1);

            // Create a file to read
            XmlReader file = XmlReader.Create(stream);

            // Clear all cells before loading
            foreach (Cell cell in this.ArrayOfCells)
            {
                cell.BGColor = 0xFFFFFFFF;
                cell.Text    = string.Empty;
            }

            // Read through the file
            while (!file.EOF)
            {
                if (file.NodeType == XmlNodeType.Element && file.Name == "cell")
                {
                    temporyCell = this.ArrayOfCells[int.Parse(file.GetAttribute("row")), int.Parse(file.GetAttribute("column"))];
                    file.Read();
                }
                else if (file.NodeType == XmlNodeType.Element && file.Name == "BGColor")
                {
                    temporyCell.BGColor = uint.Parse(file.ReadElementContentAsString());
                }
                else if (file.NodeType == XmlNodeType.Element && file.Name == "Text")
                {
                    temporyCell.Text = file.ReadElementContentAsString();
                }
                else
                {
                    file.Read();
                }
            }

            // Close the file
            file.Close();
        }
Exemplo n.º 29
0
        private Cell undoRedoCell;                           // keep track of the cell currently being worked on in the undo/redo process to avoid overlap

        // constructor
        public Spreadsheet(int x, int y)
        {
            sheet          = new SpreadsheetCell[x, y]; // create new spreadsheet with dimensions x, y
            undoStack      = new List <List <Cell> >();
            undoChangeList = new List <Tuple <Cell, string> >();
            redoStack      = new List <List <Cell> >();
            redoChangeList = new List <Tuple <Cell, string> >();

            // fill in spreadsheet with cell objects
            for (int i = 0; i < x; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    sheet[i, j]               = new SpreadsheetCell(i, j); // create new cell
                    sheet[i, j].TextChanged  += CellTextChanged;           // subscribe to this cell's text event notification
                    sheet[i, j].ValueChanged += CellValueChanged;          // subscribe to this cell's value event notification
                    sheet[i, j].ColorChanged += CellColorChanged;          // subscribe to this cell's color event notification
                    sheet[i, j].Undo         += AddUndo;                   // subscribe to this cell's undo event notification
                }
            }

            columnCount = x;
            rowCount    = y;
        }
Exemplo n.º 30
0
        /// <summary>
        /// Evaluates Cell's Value based on Entered Text
        /// </summary>
        /// <param name="cell"></param>
        private void EvaluateSpreadsheetCell(SpreadsheetCell cell)
        {
            if (cell is SpreadsheetCell currentCell && currentCell != null)
            {
                // Empty Cell
                if (string.IsNullOrEmpty(currentCell.CellText))
                {
                    currentCell.CellValue = string.Empty;
                    this.OnPropertyChanged(cell, "CellChanged");
                }

                // Non-Formula
                else if (currentCell.CellText[0] != '=')
                {
                    currentCell.CellValue = currentCell.CellText;
                    this.OnPropertyChanged(cell, "CellChanged");
                }

                // Formula
                else
                {
                    // Build the Expression Tree Based on Cell Text
                    SpreadsheetEngine.ExpressionTree expressionTree = new SpreadsheetEngine.ExpressionTree(currentCell.CellText.Substring(1));

                    // Get the Variable Names from the Expression Tree
                    string[] variableNames = expressionTree.GetVariableNames();

                    foreach (string variable in variableNames)
                    {
                        SpreadsheetCell variableCell = this.GetCell(variable);

                        // Check for Bad / Self References
                        if (!CheckValidReference(currentCell, variableCell) || CheckSelfReference(currentCell, variableCell))
                        {
                            return;
                        }

                        // Adjust Variable Values
                        if (variableCell.CellValue != string.Empty && !variableCell.CellValue.Contains(" "))
                        {
                            expressionTree.SetVariable(variable, Convert.ToDouble(variableCell.CellValue));
                        }
                        else
                        {
                            // Set Default Variable Value to 0.0
                            expressionTree.SetVariable(variable, 0.0);
                        }
                    }

                    // Mark Cells Dependent on the One Being Changed
                    AddCellDependency(currentCell, variableNames);

                    // Check Dependent Cells for Circular References
                    foreach (string variable in variableNames)
                    {
                        SpreadsheetCell variableCell = this.GetCell(variable);
                        if (CheckCircularReference(variableCell, currentCell))
                        {
                            currentCell.CellValue = "!(circular reference)";
                            this.OnPropertyChanged(currentCell, "CellChanged");
                            return;
                        }
                    }

                    // If no Errors, Evaluate the Formula and Update the Value
                    currentCell.CellValue = expressionTree.Evaluate().ToString();
                    this.OnPropertyChanged(cell, "CellChanged");
                }

                // Update the Dependent Cells of Cell Being Changed
                if (dependentCells.ContainsKey(currentCell))
                {
                    foreach (SpreadsheetCell dependentCell in dependentCells[currentCell])
                    {
                        EvaluateSpreadsheetCell(dependentCell);
                    }
                }
            }
        }