Пример #1
0
 /// <summary>
 /// If name is null or invalid, throws an InvalidNameException.
 ///
 /// Otherwise, returns the value (as opposed to the contents) of the named cell.  The return
 /// value should be either a string, a double, or a SpreadsheetUtilities.FormulaError.
 /// </summary>
 public override object GetCellValue(string name)
 {
     //if the name is valid gets the cell and returns its value
     isValidName(name);
     if (dictionary.ContainsKey(name))
     {
         cell cell = new cell();
         dictionary.TryGetValue(name, out cell);
         double doubleCheck;
         //gets double value and returns it
         if (double.TryParse(cell.getContent().ToString(), out doubleCheck))
         {
             return(doubleCheck);
         }
         //gets evaluates formaule and returns is calculated value and returns it
         bool isFormula = cell.getContent().GetType() == typeof(Formula);
         if (isFormula)
         {
             Formula f = (Formula)cell.getContent();
             return(f.Evaluate(lookup));
         }
         //returns string value of cell
         bool isString = cell.getContent().GetType() == typeof(String);
         if (isString)
         {
             return((String)cell.getContent());
         }
     }
     //if cell is empty
     return("");
 }
Пример #2
0
        /// <summary>
        /// Writes the contents of this spreadsheet to the named file using an XML format.
        /// The XML elements should be structured as follows:
        ///
        /// <spreadsheet version="version information goes here">
        ///
        /// <cell>
        /// <name>
        /// cell name goes here
        /// </name>
        /// <contents>
        /// cell contents goes here
        /// </contents>
        /// </cell>
        ///
        /// </spreadsheet>
        ///
        /// There should be one cell element for each non-empty cell in the spreadsheet.
        /// If the cell contains a string, it should be written as the contents.
        /// If the cell contains a double d, d.ToString() should be written as the contents.
        /// If the cell contains a Formula f, f.ToString() with "=" prepended should be written as the contents.
        ///
        /// If there are any problems opening, writing, or closing the file, the method should throw a
        /// SpreadsheetReadWriteException with an explanatory message.
        /// </summary>
        public override void Save(string filename)
        {
            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Indent      = true;
            settings.IndentChars = ("\t");
            try
            {   //Opens writer and creates a file to write too then closes file
                using (XmlWriter writer = XmlWriter.Create(filename, settings))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("spreadsheet");
                    writer.WriteAttributeString(null, "version", null, Version);
                    //goes through dictionary getting names and cells
                    foreach (string name in dictionary.Keys)
                    {
                        cell cell = new cell();
                        dictionary.TryGetValue(name, out cell);
                        //if empty cell dont write it to xml
                        if (GetCellContents(name) == "")
                        {
                            continue;
                        }
                        writer.WriteStartElement("cell");
                        writer.WriteElementString("name", name);
                        double doubleCheck;
                        //if double sets that to contents element
                        if (double.TryParse(GetCellContents(name).ToString(), out doubleCheck))
                        {
                            writer.WriteElementString("contents", doubleCheck.ToString());
                            writer.WriteEndElement();
                        }
                        //if formula puts that as element content
                        else if (GetCellContents(name).ToString().ElementAt(0) == '=')
                        {
                            Formula f = (Formula)cell.getContent();
                            writer.WriteElementString("contents", "=" + f.ToString());
                            writer.WriteEndElement();
                        }
                        //if string sets that to element content
                        else if (GetCellContents(name).ToString().ElementAt(0) != '=')
                        {
                            writer.WriteElementString("contents", (String)cell.getContent());
                            writer.WriteEndElement();
                        }
                    }
                    //ends document
                    writer.WriteEndDocument();
                    Changed = false;
                }
            }
            catch
            {
                throw new SpreadsheetReadWriteException("Saving file failed, file path may be incorrect");
            }
        }
Пример #3
0
        /// <summary>
        /// If text is null, throws an ArgumentNullException.
        ///
        /// Otherwise, if name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, the contents of the named cell becomes text.  The method returns a
        /// set consisting of name plus the names of all other cells whose value depends,
        /// directly or indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        protected override ISet <string> SetCellContents(string name, string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException();
            }

            //if its a valid name create a cell add it to a dictionary and adds it name to the set
            isValidName(name);
            cell          cell = new cell();
            ISet <string> set  = new HashSet <string>();

            if (!dictionary.ContainsKey(name))
            {
                cell.setContent(text);
                dictionary.Add(name, cell);
                set.Add(name);
                //gets any of the cells that depend on this one and recalculates
                RecursivlyGetDependents(name, set);
                GetCellsToRecalculate(set);
                return(set);
            }
            //if cell already exists removes it from the dictionary, and removes its dependencies from the graph
            else if (dictionary.ContainsKey(name))
            {
                dictionary.TryGetValue(name, out cell);
                bool isFormula = cell.getContent().GetType() == typeof(Formula);
                if (isFormula)
                {
                    Formula f = (Formula)cell.getContent();
                    foreach (string dependee in f.GetVariables())
                    {
                        graph.RemoveDependency(dependee, name);
                    }
                }
                set.Add(name);
                //gets any of the cells that depend on this one and recalculates
                RecursivlyGetDependents(name, set);
                GetCellsToRecalculate(set);
                dictionary.Remove(name);
                cell.setContent(text);
                dictionary.Add(name, cell);
                return(set);
            }
            return(set);
        }
Пример #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 private double lookup(string name)
 {
     //if name does not exsists thwos exception
     if (!dictionary.ContainsKey(name))
     {
         ///this is the bug
         throw new ArgumentException();
     }
     if (dictionary.ContainsKey(name))
     {
         cell cell = new cell();
         dictionary.TryGetValue(name, out cell);
         double doubleCheck;
         //if named cell has a double value return it to the formula class
         if (double.TryParse(cell.getContent().ToString(), out doubleCheck))
         {
             return(doubleCheck);
         }
         object value;
         //if the named cell has its own formula recursivly get its value
         bool isFormula = cell.getContent().GetType() == typeof(Formula);
         if (isFormula)
         {
             Formula f = (Formula)cell.getContent();
             value = f.Evaluate(lookup);
             if (double.TryParse(value.ToString(), out doubleCheck))
             {
                 return(doubleCheck);
             }
             //if any of the dependent cells have error it is propagated
             bool isError = value.GetType() == typeof(FormulaError);
             if (isError)
             {
                 throw new ArgumentException();
             }
         }
         else
         {
             throw new ArgumentException();
         }
     }
     //should never reach here
     return(0);
 }
Пример #5
0
        /// <summary>
        /// If name is null or invalid, throws an InvalidNameException.
        /// Otherwise, returns the contents (as opposed to the value) of the named cell.  The return
        /// value should be either a string, a double, or a Formula.
        public override object GetCellContents(string name)
        {
            //if the name is valid gets the cell and returns its contents
            //this method also throws exceptions

            isValidName(name);
            name = Normalize(name);
            //if named cell is present gets it contents
            if (dictionary.ContainsKey(name))
            {
                cell cell = new cell();
                dictionary.TryGetValue(name, out cell);
                double doubleCheck;
                //for double content
                if (cell.getContent().GetType() == typeof(Double))
                {
                    return(cell.getContent());
                }
                //for formula content
                bool isFormula = cell.getContent().GetType() == typeof(Formula);
                if (isFormula)
                {
                    Formula f = (Formula)cell.getContent();
                    return(f);
                }
                //for string content
                bool isString = cell.getContent().GetType() == typeof(String);
                if (isString)
                {
                    return((String)cell.getContent());
                }
            }
            //for empty cell
            return("");
        }
Пример #6
0
        /// <summary>
        /// Enumerates the names of all the non-empty cells in the spreadsheet.
        /// </summary>
        public override IEnumerable <string> GetNamesOfAllNonemptyCells()
        {
            LinkedList <string> names = new LinkedList <string>();

            foreach (string name in dictionary.Keys)
            {
                cell check = new cell();
                dictionary.TryGetValue(name, out check);
                //if content is not empty add to the list
                if (check.getContent() != "")
                {
                    names.AddFirst(name);
                }
            }
            return(names);
        }
Пример #7
0
        /// <summary>
        /// If the formula parameter is null, throws an ArgumentNullException.
        /// Otherwise, if name is null or invalid, throws an InvalidNameException.
        /// Otherwise, if changing the contents of the named cell to be the formula would cause a
        /// circular dependency, throws a CircularException.  (No change is made to the spreadsheet.)
        /// Otherwise, the contents of the named cell becomes formula.  The method returns a
        /// Set consisting of name plus the names of all other cells whose value depends,
        /// directly or indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        protected override ISet <string> SetCellContents(string name, Formula formula)
        {
            if (formula == null)
            {
                throw new ArgumentNullException();
            }
            //checks if its a valid name
            isValidName(name);
            name = Normalize(name);
            cell          cell = new cell();
            ISet <string> set  = new HashSet <string>();

            //if the cell isnt already created for that name create it.
            if (!dictionary.ContainsKey(name))
            {
                //create cell and add the formula to it
                cell.setContent(formula);
                //add the cell to the dictionary the name is the key.
                dictionary.Add(name, cell);
                set.Add(name);

                //sets the variables in the formula as a dependee of the new cell
                foreach (string dependees in formula.GetVariables())
                {
                    graph.AddDependency(dependees, name);
                }
                //checks for circular dependency and recalculates the cells nesseccary
                GetCellsToRecalculate(set);
                //gets all the dependents of the cell and adds to the set
                RecursivlyGetDependents(name, set);
                //checks for circular dependency and recalculates the cells nesseccary
                GetCellsToRecalculate(set);
                return(set);
            }
            //if the cell is already created remove it from the dictionary
            else if (dictionary.ContainsKey(name))
            {
                //gets the cell out and removes any dependees from the cell
                dictionary.TryGetValue(name, out cell);
                bool isFormula = cell.getContent().GetType() == typeof(Formula);
                if (isFormula)
                {
                    Formula f = (Formula)cell.getContent();
                    foreach (string dependee in f.GetVariables())
                    {
                        graph.RemoveDependency(dependee, name);
                    }
                }
                set.Add(name);
                //addes new dependees to the cell if any
                foreach (string dependee in formula.GetVariables())
                {
                    graph.AddDependency(dependee, name);
                }
                //gets all the dependents of the cell and adds to the set
                GetCellsToRecalculate(set);
                RecursivlyGetDependents(name, set);
                //checks for circular dependency and recalculates the cells nesseccary
                GetCellsToRecalculate(set);
                dictionary.Remove(name);
                //sets the new formula
                cell.setContent(formula);
                //adds the new cell to the dictionary
                dictionary.Add(name, cell);
                return(set);
            }
            return(set);
        }