public IEnumerable <SpreadSheetCell> GetSheetCells(string input)
        {
            var cellVals = input.Split(" ");

            if (cellVals.Length % 3 != 0)
            {
                throw new SpreadSheetException("字符串的格式不正确,插入的值必须为3的备注");
            }
            var result     = new List <SpreadSheetCell>();
            var cellGroups = cellVals.CutArrayForAppointCount(3);

            foreach (var group in cellGroups)
            {
                if (!int.TryParse(group[0], out int x))
                {
                    throw new SpreadSheetException("插入的cell的x坐标必须为整数");
                }

                if (!int.TryParse(group[1], out int y))
                {
                    throw new SpreadSheetException("插入的cell的y坐标必须为整数");
                }
                var cell = new SpreadSheetCell(x, y, group[2]);
                result.Add(cell);
            }
            return(result);
        }
 //when new exprssion is inputed into cell all previous connections to cell are terminated using this function
 private void UnSubscribeFromCells(SpreadSheetCell nCell)
 {
     while (nCell._mConnections.Peek() != null)
     {
         SpreadSheetCell tempCell = nCell._mConnections.Pop();
         tempCell.PropertyChanged -= nCell.connectedCellPropertyChanged;
     }
 }
        //when new exprssion is inputed into cell a new stack is formed of connections to cells
        private void SubscribeToCells(string expression, SpreadSheetCell nCell)
        {
            List <string> cellList = getCellsFromExp(expression);

            foreach (string item in cellList)
            {
                Tuple <int, int> nCellPos = getCellPosition(item);
                SpreadSheetCell  tempCell = (SpreadSheetCell)getCell(nCellPos.Item1, nCellPos.Item2);
                tempCell.PropertyChanged += nCell.connectedCellPropertyChanged;
                nCell._mConnections.Push(tempCell);
            }
        }
Beispiel #4
0
 public SpreadSheet(int width, int height)
 {
     Width  = width;
     Height = height;
     cells  = new SpreadSheetCell[width * height];
     for (int x = 0; x < width; x++)
     {
         for (int y = 0; y < height; y++)
         {
             cells[width * y + x] = new SpreadSheetCell();
         }
     }
 }
Beispiel #5
0
 //Every new action that we dow will be pushed onto the undostack
 public void addAction(SpreadSheetCell cell, string property)
 {
     if (property == "Text")
     {
         cell.editType = "t";
         undoStack.Push(cell);
     }
     else if (property == "Color")
     {
         cell.editType = "c";
         undoStack.Push(cell);
     }
 }
        //checks contents content of cell and acts accordingly
        private void Check(Cell nCell)
        {
            SpreadSheetCell tempCell = nCell as SpreadSheetCell;

            if (tempCell._hasConnections)
            {
                UnSubscribeFromCells(tempCell);                          //since the text within the cell has been changed
            }
            //all connections with other cells are broken
            if (string.IsNullOrEmpty(tempCell.Text))
            {
                tempCell.setValue("");
                CellPropChanged(nCell, new PropertyChangedEventArgs("Value"));
            }
            else if (tempCell.Text[0] == '=')
            {
                if (outOfBounds(tempCell))
                {
                    tempCell.setValue("#REF!");
                    return;
                }
                else
                {
                    tempCell.makeNewExpTree(tempCell.Text.Substring(1));
                    if (getCellsFromExp(tempCell.Text.Substring(1)) != null)
                    {
                        SubscribeToCells(tempCell.Text.Substring(1), tempCell);
                    }
                    if (tempCell.hasSelfReference())
                    {
                        tempCell.setValue("#SELFREF!");
                        UnSubscribeFromCells(tempCell);
                    }
                    else
                    {
                        if (getCellsFromExp(tempCell.Text.Substring(1)).Count <= 1)
                        {
                            tempCell.makeNewExpTree("");
                        }
                        tempCell.evalTree();
                    }
                }
                CellPropChanged(nCell, new PropertyChangedEventArgs("Value"));
            }
            else
            {
                tempCell.setValue(tempCell.Text);
                CellPropChanged(nCell, new PropertyChangedEventArgs("Value"));
            }
        }
Beispiel #7
0
        //Performs the redo action
        public SpreadSheetCell redoAction(SpreadSheetCell cell)
        {
            if (redoStack.Count > 0)
            {
                //Pop the previous state off of the stack
                SpreadSheetCell RevertToThis = redoStack.Pop();

                undoStack.Push(cell);

                cell.editType = RevertToThis.editType;

                cell = RevertToThis;
            }
            return cell;
        }
        public void SignalPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SpreadSheetCell tempCell = sender as SpreadSheetCell;

            if (e.PropertyName == "Text")
            {
                Check(sender as Cell);

                CellPropChanged(tempCell, new PropertyChangedEventArgs("Text"));
            }
            else
            {
                CellPropChanged(tempCell, new PropertyChangedEventArgs("Value"));
            }
        }
        //makes new SpreadSheet with a specific amount cells
        public Spreadsheet(int newRows, int newColumns)
        {
            _Array = new Cell[newRows, newColumns];
            ExpTree newTree = new ExpTree("0");

            for (int x = 0; x < newRows; x++)
            {
                for (int y = 0; y < newColumns; y++)
                {
                    string cellName = getCellName(x, y);
                    _Array[x, y] = new SpreadSheetCell(x, y);
                    _Array[x, y].PropertyChanged += SignalPropertyChanged;
                    ExpTree.SetVar(cellName, _Array[x, y]);
                }
            }
        }
            //this function makes sure that the refrenced cells dont cause a loop
            private bool helperHasSelfReference(SpreadSheetCell nCell, HashSet <Tuple <int, int> > nHashSet)
            {
                Tuple <int, int> tempCell = new Tuple <int, int>(nCell.Row, nCell.Column);

                if (nHashSet.Contains(tempCell))
                {
                    return(true);
                }
                nHashSet.Add(tempCell);
                foreach (var tCell in nCell._mConnections.Where(a => a != null))
                {
                    if (helperHasSelfReference(tCell, nHashSet))
                    {
                        return(true);
                    }
                }
                nHashSet.Remove(tempCell);
                return(false);
            }
        //Checks if any of the cells refered to by the cell are out of bounds
        private bool outOfBounds(SpreadSheetCell nCell)
        {
            List <string>            cellList = getCellsFromExp(nCell.Text.Substring(1));
            List <Tuple <int, int> > tempList = new List <Tuple <int, int> >();

            if (cellList != null)
            {
                foreach (string name in cellList)
                {
                    tempList.Add(getCellPosition(name));
                }
                foreach (var coord in tempList)
                {
                    if (coord.Item1 > this.RowCount || coord.Item2 > this.ColumnCount)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #12
0
            //Checks to see if a cell exists. It will return the cell if it does, otherwise
            //it will return null.
            private StandardCell checkReference(string name, SpreadSheetCell[,] sheet)
            {
                char p1 = name[0];
                string p2 = name.Substring(1);

                int error = 0;

                if ((char.IsUpper(p1)) && int.TryParse(p2, out error))
                {
                    //Will be used to find the correct column
                    string[] columnIndex = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

                    //Convert the numerical value of the string to an int for the row number (subtract 1 because rows really start at 0)
                    int row = Convert.ToInt32(p2) - 1;
                    int col = 0;
                    //Checks if the row is within the correct range. If it is execute
                    if (row >= 0 && row <= 50)
                    {
                        //Now we will find the column
                        for (int i = 0; i < columnIndex.Length; i++)
                        {
                            //If the letter in the string matches a corresponding letter in the column index then set the numerical value
                            //of the column to the vlaue
                            if (columnIndex[i].ToString() == (p1.ToString()))
                            {
                                col = i;
                                break;
                            }
                        }
                    }
                    return (StandardCell)sheet[row, col];
                }
                else
                    return null;
            }
            public bool hasSelfReference()
            {
                SpreadSheetCell nCell = this;

                return(helperHasSelfReference(nCell, new HashSet <Tuple <int, int> >()));
            }
Beispiel #14
0
        //Performs the undo action
        public SpreadSheetCell undoAction(SpreadSheetCell cell)
        {
            //We must check if there is something to undo
            if (undoStack.Count > 0)
            {
                //Pop the previous state off of the stack
                SpreadSheetCell RevertToThis = undoStack.Pop();

                cell.editType = RevertToThis.editType;

                redoStack.Push(cell);

                cell = RevertToThis;

                if (cell.getColor() == 0)
                    cell.setColor(-1);
            }
            return cell;
        }
Beispiel #15
0
        public XmlWriter makeTagBlock(SpreadSheetCell sheetCell, XmlWriter xmlWriter)
        {
            //The main header for the cell block
            xmlWriter.WriteStartElement("SheetCell");
            //Add in the cell attributes
            xmlWriter.WriteElementString("Color", sheetCell.getColor().ToString());
            xmlWriter.WriteElementString("RowIndex", sheetCell.getRowIndex().ToString());
            xmlWriter.WriteElementString("ColumnIndex", sheetCell.getColumnIndex().ToString());
            xmlWriter.WriteElementString("Text", sheetCell.getText().ToString());
            //The end to the block (aka "</SheetCell>"
            xmlWriter.WriteEndElement();

            return xmlWriter;
        }
Beispiel #16
0
 public void setCell(SpreadSheetCell cell)
 {
     sheetArray[cell.getRowIndex(), cell.getColumnIndex()] = cell;
 }
Beispiel #17
0
            //Suppose to update the text that the cell contains
            //I completely renovated this function since homework 4
            public void updateValue(SpreadSheetCell[,] TwoDArray)
            {
                bool updated = false;

                while (updated == false)
                {
                    //First we will check if the text is empty of if it hasn't actually been updated
                    if (this._text == null || this._text == this._value)
                        updated = true;
                    //Otherwise we will need to make some updates to the cell
                    else
                    {
                        //If the cell is not an expression or a reference
                        if (this._text[0].ToString() != "=")
                        {
                            this._value = this._text;
                            updated = true;
                        }
                        //My code would always break if I just entered an equals sign... Figured I should fix that
                        else if (this._text == "=")
                        {
                            this._value = this._text;
                            updated = true;
                        }
                        else
                        {
                            /*First we want to make our evaluation tree and get all of the referenced nodes*/
                            /**/Expression newExp = new Expression(this._text.Substring(1));             /**/
                            /**/List<string> refList = newExp.getAllNodes();                             /**/
                            /*******************************************************************************/

                            //If the node isn't a single variable or value (i.e. A1 or 33) we will want to go through all of the
                            //other nodes connected on the expression tree. We will need them for evaulating the expression.
                            if (refList.Count() > 0)
                            {
                                //We will go through each reference in the list we created and filled about
                                for (int i = 0; i < refList.Count(); i++)
                                {
                                    //Create a tempory cell for the given index in the list of references
                                    StandardCell tempRefCell = checkReference(refList[i], TwoDArray);

                                    //If the cell doesn't exist, then we will want to break the loop
                                    if (tempRefCell == null)
                                        break;

                                    //We will use this a few times for checking value is a number
                                    int error = 0;

                                    //If the tempRefCell doesn't contain the cell we are modifying (this) then we will
                                    //want to add it the list of rerferences for the tempRefCell
                                    if (tempRefCell.references.Contains(this) != true)
                                        tempRefCell.references.Add(this);

                                    //We need to parse the refernce in the two parts (column and row)
                                    char p1 = refList[i][0];
                                    string p2 = refList[i].Substring(1);

                                    //Create our variables for the row and columns
                                    int row, col;

                                    //If p1 is uppercase and the rest of the string is a number then we know that it's
                                    //a cell reference
                                    if ((char.IsUpper(p1)) && int.TryParse(p2, out error))
                                    {
                                        //Set row to (row - 1) [we start at 0 and not 1]
                                        row = Convert.ToInt32(p2) - 1;
                                        col = 0;

                                        //Will be used to find the correct column
                                        string[] columnIndex = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

                                        //Convert the numerical value of the string to an int for the row number (subtract 1 because rows really start at 0)
                                        //Checks if the row is within the correct range. If it is execute
                                        if (row >= 0 && row <= 50)
                                        {
                                            //Now we will find the column
                                            for (int j = 0; j < columnIndex.Length; j++)
                                            {
                                                //If the letter in the string matches a corresponding letter in the column index then set the numerical value
                                                //of the column to the vlaue
                                                if (columnIndex[j].ToString() == (p1.ToString()))
                                                {
                                                    col = j;
                                                    break;
                                                }
                                            }
                                        }

                                        newExp.setDictionaryValue(refList[i], TwoDArray[row, col].getValue());
                                    }
                                }
                                //Evaluate the expression and set it to the cell value. Set updated to true
                                this._value = newExp.eval().ToString();
                                updated = true;
                            }
                            //If the expression is just a single node
                            else
                            {
                                if (checkReference(newExp.getExpression(), TwoDArray) != null)
                                    this._value = checkReference(newExp.getExpression(), TwoDArray).getValue();
                                else
                                    this._value = newExp.eval().ToString();
                                updated = true;
                            }
                        }
                    }
                }
            }