/******************************************************************************* * You may amend and distribute as you like, but don't remove this header! * * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. * See http://www.codeplex.com/EPPlus for details. * * Copyright (C) 2011 Jan Källman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html * * All code and executables are provided "as is" with no warranty either express or implied. * The author accepts no liability for any damage or loss of business that this product may cause. * * Code change notes: * * Author Change Date * ****************************************************************************** * Mats Alm Added 2011-01-08 * Jan Källman License changed GPL-->LGPL 2011-12-27 *******************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using OfficeOpenXml.Utils; using OfficeOpenXml.DataValidation.Formulas.Contracts; using System.Text.RegularExpressions; using System.Collections; namespace OfficeOpenXml.DataValidation.Formulas { internal class ExcelDataValidationFormulaList : ExcelDataValidationFormula, IExcelDataValidationFormulaList { #region class DataValidationList private class DataValidationList : IList, ICollection { private IList _items = new List(); private EventHandler _listChanged; public event EventHandler ListChanged { add { _listChanged += value; } remove { _listChanged -= value; } } private void OnListChanged() { if (_listChanged != null) { _listChanged(this, EventArgs.Empty); } } #region IList members int IList.IndexOf(string item) { return _items.IndexOf(item); } void IList.Insert(int index, string item) { _items.Insert(index, item); OnListChanged(); } void IList.RemoveAt(int index) { _items.RemoveAt(index); OnListChanged(); } string IList.this[int index] { get { return _items[index]; } set { _items[index] = value; OnListChanged(); } } void ICollection.Add(string item) { _items.Add(item); OnListChanged(); } void ICollection.Clear() { _items.Clear(); OnListChanged(); } bool ICollection.Contains(string item) { return _items.Contains(item); } void ICollection.CopyTo(string[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } int ICollection.Count { get { return _items.Count; } } bool ICollection.IsReadOnly { get { return false; } } bool ICollection.Remove(string item) { var retVal = _items.Remove(item); OnListChanged(); return retVal; } IEnumerator IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } #endregion public void CopyTo(Array array, int index) { _items.CopyTo((string[])array, index); } int ICollection.Count { get { return _items.Count; } } public bool IsSynchronized { get { return ((ICollection)_items).IsSynchronized; } } public object SyncRoot { get { return ((ICollection)_items).SyncRoot; } } } #endregion public ExcelDataValidationFormulaList(XmlNamespaceManager namespaceManager, XmlNode itemNode, string formulaPath) : base(namespaceManager, itemNode, formulaPath) { Require.Argument(formulaPath).IsNotNullOrEmpty("formulaPath"); _formulaPath = formulaPath; var values = new DataValidationList(); values.ListChanged += new EventHandler(values_ListChanged); Values = values; SetInitialValues(); } private string _formulaPath; private void SetInitialValues() { var @value = GetXmlNodeString(_formulaPath); if (!string.IsNullOrEmpty(@value)) { if (@value.StartsWith("\"") && @value.EndsWith("\"")) { @value = @value.TrimStart('"').TrimEnd('"'); var items = @value.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries); foreach (var item in items) { Values.Add(item); } } else { ExcelFormula = @value; } } } void values_ListChanged(object sender, EventArgs e) { if (Values.Count > 0) { State = FormulaState.Value; } var valuesAsString = GetValueAsString(); // Excel supports max 255 characters in this field. if (valuesAsString.Length > 255) { throw new InvalidOperationException("The total length of a DataValidation list cannot exceed 255 characters"); } SetXmlNodeString(_formulaPath, valuesAsString); } public IList Values { get; private set; } protected override string GetValueAsString() { var sb = new StringBuilder(); foreach (var val in Values) { if (sb.Length == 0) { sb.Append("\""); sb.Append(val); } else { sb.AppendFormat(",{0}", val); } } sb.Append("\""); return sb.ToString(); } internal override void ResetValue() { Values.Clear(); } } }