Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/DataValidation/ExcelDataValidation.cs @ 14853

Last change on this file since 14853 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 13.6 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Mats Alm                       Added                   2011-01-01
30 * Jan Källman                    License changed GPL-->LGPL  2011-12-27
31 *******************************************************************************/
32using System;
33using System.Collections.Generic;
34using System.Globalization;
35using System.Linq;
36using System.Text;
37using OfficeOpenXml.Utils;
38using System.Xml;
39using System.Text.RegularExpressions;
40using OfficeOpenXml.DataValidation.Formulas.Contracts;
41using OfficeOpenXml.DataValidation.Contracts;
42
43namespace OfficeOpenXml.DataValidation
44{
45    /// <summary>
46    /// Excel datavalidation
47    /// </summary>
48    public abstract class ExcelDataValidation : XmlHelper, IExcelDataValidation
49    {
50        private const string _itemElementNodeName = "d:dataValidation";
51
52
53        private readonly string _errorStylePath = "@errorStyle";
54        private readonly string _errorTitlePath = "@errorTitle";
55        private readonly string _errorPath = "@error";
56        private readonly string _promptTitlePath = "@promptTitle";
57        private readonly string _promptPath = "@prompt";
58        private readonly string _operatorPath = "@operator";
59        private readonly string _showErrorMessagePath = "@showErrorMessage";
60        private readonly string _showInputMessagePath = "@showInputMessage";
61        private readonly string _typeMessagePath = "@type";
62        private readonly string _sqrefPath = "@sqref";
63        private readonly string _allowBlankPath = "@allowBlank";
64        protected readonly string _formula1Path = "d:formula1";
65        protected readonly string _formula2Path = "d:formula2";
66
67        internal ExcelDataValidation(ExcelWorksheet worksheet, string address, ExcelDataValidationType validationType)
68            : this(worksheet, address, validationType, null)
69        { }
70
71        /// <summary>
72        /// Constructor
73        /// </summary>
74        /// <param name="worksheet">worksheet that owns the validation</param>
75        /// <param name="itemElementNode">Xml top node (dataValidations)</param>
76        /// <param name="validationType">Data validation type</param>
77        /// <param name="address">address for data validation</param>
78        internal ExcelDataValidation(ExcelWorksheet worksheet, string address, ExcelDataValidationType validationType, XmlNode itemElementNode)
79            : this(worksheet, address, validationType, itemElementNode, null)
80        {
81
82        }
83
84        /// <summary>
85        /// Constructor
86        /// </summary>
87        /// <param name="worksheet">worksheet that owns the validation</param>
88        /// <param name="itemElementNode">Xml top node (dataValidations) when importing xml</param>
89        /// <param name="validationType">Data validation type</param>
90        /// <param name="address">address for data validation</param>
91        /// <param name="namespaceManager">Xml Namespace manager</param>
92        internal ExcelDataValidation(ExcelWorksheet worksheet, string address, ExcelDataValidationType validationType, XmlNode itemElementNode, XmlNamespaceManager namespaceManager)
93            : base(namespaceManager != null ? namespaceManager : worksheet.NameSpaceManager)
94        {
95            Require.Argument(address).IsNotNullOrEmpty("address");
96            address = CheckAndFixRangeAddress(address);
97            if (itemElementNode == null)
98            {
99                //var xmlDoc = worksheet.WorksheetXml;
100                TopNode = worksheet.WorksheetXml.SelectSingleNode("//d:dataValidations", worksheet.NameSpaceManager);
101                // did not succeed using the XmlHelper methods here... so I'm creating the new node using XmlDocument...
102                var nsUri = NameSpaceManager.LookupNamespace("d");
103                //itemElementNode = TopNode.OwnerDocument.CreateElement(_itemElementNodeName, nsUri);
104                itemElementNode = TopNode.OwnerDocument.CreateElement(_itemElementNodeName.Split(':')[1], nsUri);
105                TopNode.AppendChild(itemElementNode);
106            }
107            TopNode = itemElementNode;
108            ValidationType = validationType;
109            Address = new ExcelAddress(address);
110            Init();
111        }
112
113        private void Init()
114        {
115            // set schema node order
116            SchemaNodeOrder = new string[]{
117                "type",
118                "errorStyle",
119                "operator",
120                "allowBlank",
121                "showInputMessage",
122                "showErrorMessage",
123                "errorTitle",
124                "error",
125                "promptTitle",
126                "prompt",
127                "sqref",
128                "formula1",
129                "formula2"
130            };
131        }
132
133        private string CheckAndFixRangeAddress(string address)
134        {
135            if (address.Contains(','))
136            {
137                throw new FormatException("Multiple addresses may not be commaseparated, use space instead");
138            }
139            address = address.ToUpper(CultureInfo.InvariantCulture);
140            if (Regex.IsMatch(address, @"[A-Z]+:[A-Z]+"))
141            {
142                address = AddressUtility.ParseEntireColumnSelections(address);
143            }
144            return address;
145        }
146
147        private void SetNullableBoolValue(string path, bool? val)
148        {
149            if (val.HasValue)
150            {
151                SetXmlNodeBool(path, val.Value);
152            }
153            else
154            {
155                DeleteNode(path);
156            }
157        }
158
159        /// <summary>
160        /// This method will validate the state of the validation
161        /// </summary>
162        /// <exception cref="InvalidOperationException">If the state breaks the rules of the validation</exception>
163        public virtual void Validate()
164        {
165            var address = Address.Address;
166            // validate Formula1
167            if (string.IsNullOrEmpty(Formula1Internal))
168            {
169                throw new InvalidOperationException("Validation of " + address + " failed: Formula1 cannot be empty");
170            }
171        }
172
173        #region Public properties
174
175        /// <summary>
176        /// True if the validation type allows operator to be set.
177        /// </summary>
178        public bool AllowsOperator
179        {
180            get
181            {
182                return ValidationType.AllowOperator;
183            }
184        }
185
186        /// <summary>
187        /// Address of data validation
188        /// </summary>
189        public ExcelAddress Address
190        {
191            get
192            {
193                return new ExcelAddress(GetXmlNodeString(_sqrefPath));
194            }
195            private set
196            {
197                var address = AddressUtility.ParseEntireColumnSelections(value.Address);
198                SetXmlNodeString(_sqrefPath, address);
199            }
200        }
201        /// <summary>
202        /// Validation type
203        /// </summary>
204        public ExcelDataValidationType ValidationType
205        {
206            get
207            {
208                var typeString = GetXmlNodeString(_typeMessagePath);
209                return ExcelDataValidationType.GetBySchemaName(typeString);
210            }
211            private set
212            {
213                SetXmlNodeString(_typeMessagePath, value.SchemaName, true);
214            }
215        }
216
217        /// <summary>
218        /// Operator for comparison between the entered value and Formula/Formulas.
219        /// </summary>
220        public ExcelDataValidationOperator Operator
221        {
222            get
223            {
224                var operatorString = GetXmlNodeString(_operatorPath);
225                if (!string.IsNullOrEmpty(operatorString))
226                {
227                    return (ExcelDataValidationOperator)Enum.Parse(typeof(ExcelDataValidationOperator), operatorString);
228                }
229                return default(ExcelDataValidationOperator);
230            }
231            set
232            {
233                if (!ValidationType.AllowOperator)
234                {
235                    throw new InvalidOperationException("The current validation type does not allow operator to be set");
236                }
237                SetXmlNodeString(_operatorPath, value.ToString());
238            }
239        }
240
241        /// <summary>
242        /// Warning style
243        /// </summary>
244        public ExcelDataValidationWarningStyle ErrorStyle
245        {
246            get
247            {
248                var errorStyleString = GetXmlNodeString(_errorStylePath);
249                if (!string.IsNullOrEmpty(errorStyleString))
250                {
251                    return (ExcelDataValidationWarningStyle)Enum.Parse(typeof(ExcelDataValidationWarningStyle), errorStyleString);
252                }
253                return ExcelDataValidationWarningStyle.undefined;
254            }
255            set
256            {
257                if (value == ExcelDataValidationWarningStyle.undefined)
258                {
259                    DeleteNode(_errorStylePath);
260                }
261                SetXmlNodeString(_errorStylePath, value.ToString());
262            }
263        }
264
265        /// <summary>
266        /// True if blanks should be allowed
267        /// </summary>
268        public bool? AllowBlank
269        {
270            get
271            {
272                return GetXmlNodeBoolNullable(_allowBlankPath);
273            }
274            set
275            {
276                SetNullableBoolValue(_allowBlankPath, value);
277            }
278        }
279
280        /// <summary>
281        /// True if input message should be shown
282        /// </summary>
283        public bool? ShowInputMessage
284        {
285            get
286            {
287                return GetXmlNodeBoolNullable(_showInputMessagePath);
288            }
289            set
290            {
291                SetNullableBoolValue(_showInputMessagePath, value);
292            }
293        }
294
295        /// <summary>
296        /// True if error message should be shown
297        /// </summary>
298        public bool? ShowErrorMessage
299        {
300            get
301            {
302                return GetXmlNodeBoolNullable(_showErrorMessagePath);
303            }
304            set
305            {
306                SetNullableBoolValue(_showErrorMessagePath, value);
307            }
308        }
309
310        /// <summary>
311        /// Title of error message box
312        /// </summary>
313        public string ErrorTitle
314        {
315            get
316            {
317                return GetXmlNodeString(_errorTitlePath);
318            }
319            set
320            {
321                SetXmlNodeString(_errorTitlePath, value);
322            }
323        }
324
325        /// <summary>
326        /// Error message box text
327        /// </summary>
328        public string Error
329        {
330            get
331            {
332                return GetXmlNodeString(_errorPath);
333            }
334            set
335            {
336                SetXmlNodeString(_errorPath, value);
337            }
338        }
339
340        public string PromptTitle
341        {
342            get
343            {
344                return GetXmlNodeString(_promptTitlePath);
345            }
346            set
347            {
348                SetXmlNodeString(_promptTitlePath, value);
349            }
350        }
351
352        public string Prompt
353        {
354            get
355            {
356                return GetXmlNodeString(_promptPath);
357            }
358            set
359            {
360                SetXmlNodeString(_promptPath, value);
361            }
362        }
363
364        /// <summary>
365        /// Formula 1
366        /// </summary>
367        protected string Formula1Internal
368        {
369            get
370            {
371                return GetXmlNodeString(_formula1Path);
372            }
373        }
374
375        /// <summary>
376        /// Formula 2
377        /// </summary>
378        protected string Formula2Internal
379        {
380            get
381            {
382                return GetXmlNodeString(_formula2Path);
383            }
384        }
385
386        #endregion
387
388        protected void SetValue<T>(Nullable<T> val, string path)
389            where T : struct
390        {
391            if (!val.HasValue)
392            {
393                DeleteNode(path);
394            }
395            var stringValue = val.Value.ToString().Replace(',', '.');
396            SetXmlNodeString(path, stringValue);
397        }
398    }
399}
Note: See TracBrowser for help on using the repository browser.