Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/ConditionalFormatting/ExcelConditionalFormattingColorScaleValue.cs @ 12074

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

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 15.3 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 * Eyal Seagull        Added            2012-04-03
30 *******************************************************************************/
31using System;
32using System.Collections.Generic;
33using System.Linq;
34using System.Text;
35using System.Drawing;
36using System.Xml;
37using OfficeOpenXml.Utils;
38using System.Text.RegularExpressions;
39using System.Globalization;
40using System.Security;
41
42namespace OfficeOpenXml.ConditionalFormatting
43{
44  /// <summary>
45  /// 18.3.1.11 cfvo (Conditional Format Value Object)
46  /// Describes the values of the interpolation points in a gradient scale.
47  /// </summary>
48  public class ExcelConditionalFormattingColorScaleValue
49    : XmlHelper
50  {
51    /****************************************************************************************/
52
53    #region Private Properties
54    private eExcelConditionalFormattingValueObjectPosition _position;
55    private eExcelConditionalFormattingRuleType _ruleType;
56    private ExcelWorksheet _worksheet;
57    #endregion Private Properties
58
59    /****************************************************************************************/
60
61    #region Constructors
62    /// <summary>
63    /// Initialize the cfvo (§18.3.1.11) node
64    /// </summary>
65    /// <param name="position"></param>
66    /// <param name="type"></param>
67    /// <param name="color"></param>
68    /// <param name="value"></param>
69    /// <param name="formula"></param>
70    /// <param name="ruleType"></param>
71    /// <param name="address"></param>
72    /// <param name="priority"></param>
73    /// <param name="worksheet"></param>
74    /// <param name="itemElementNode">The cfvo (§18.3.1.11) node parent. Can be any of the following:
75    /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49)</param>
76    /// <param name="namespaceManager"></param>
77    internal ExcelConditionalFormattingColorScaleValue(
78      eExcelConditionalFormattingValueObjectPosition position,
79      eExcelConditionalFormattingValueObjectType type,
80      Color color,
81      double value,
82      string formula,
83      eExcelConditionalFormattingRuleType ruleType,
84      ExcelAddress address,
85      int priority,
86      ExcelWorksheet worksheet,
87      XmlNode itemElementNode,
88      XmlNamespaceManager namespaceManager)
89      : base(
90        namespaceManager,
91        itemElementNode)
92    {
93      Require.Argument(priority).IsInRange(1, int.MaxValue, "priority");
94      Require.Argument(address).IsNotNull("address");
95      Require.Argument(worksheet).IsNotNull("worksheet");
96
97      // Save the worksheet for private methods to use
98      _worksheet = worksheet;
99
100      // Schema order list
101      SchemaNodeOrder = new string[]
102      {
103        ExcelConditionalFormattingConstants.Nodes.Cfvo,
104        ExcelConditionalFormattingConstants.Nodes.Color
105      };
106
107      // Check if the parent does not exists
108      if (itemElementNode == null)
109      {
110        // Get the parent node path by the rule type
111        string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType(
112          ruleType);
113
114        // Check for en error (rule type does not have <cfvo>)
115        if (parentNodePath == string.Empty)
116        {
117          throw new Exception(
118            ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);
119        }
120
121        // Point to the <cfvo> parent node
122        itemElementNode = _worksheet.WorksheetXml.SelectSingleNode(
123          string.Format(
124            "//{0}[{1}='{2}']/{3}[{4}='{5}']/{6}",
125          // {0}
126            ExcelConditionalFormattingConstants.Paths.ConditionalFormatting,
127          // {1}
128            ExcelConditionalFormattingConstants.Paths.SqrefAttribute,
129          // {2}
130            address.Address,
131          // {3}
132            ExcelConditionalFormattingConstants.Paths.CfRule,
133          // {4}
134            ExcelConditionalFormattingConstants.Paths.PriorityAttribute,
135          // {5}
136            priority,
137          // {6}
138            parentNodePath),
139          _worksheet.NameSpaceManager);
140
141        // Check for en error (rule type does not have <cfvo>)
142        if (itemElementNode == null)
143        {
144          throw new Exception(
145            ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);
146        }
147      }
148
149      // Point to the <cfvo> parent node (<colorScale>, <dataBar> or <iconSet>)
150      // This is different than normal, as TopNode does not point to the node itself but to
151      // its PARENT. Later, in the CreateNodeByOrdem method the TopNode will be updated.
152      TopNode = itemElementNode;
153
154      // Save the attributes
155      Position = position;
156      RuleType = ruleType;
157      Type = type;
158      Color = color;
159      Value = value;
160      Formula = formula;
161    }
162
163    /// <summary>
164    /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>
165    /// </summary>
166    /// <param name="position"></param>
167    /// <param name="type"></param>
168    /// <param name="color"></param>
169    /// <param name="value"></param>
170    /// <param name="formula"></param>
171    /// <param name="ruleType"></param>
172    /// <param name="priority"></param>
173    /// <param name="address"></param>
174    /// <param name="worksheet"></param>
175    /// <param name="namespaceManager"></param>
176    internal ExcelConditionalFormattingColorScaleValue(
177      eExcelConditionalFormattingValueObjectPosition position,
178      eExcelConditionalFormattingValueObjectType type,
179      Color color,
180      double value,
181      string formula,
182      eExcelConditionalFormattingRuleType ruleType,
183      ExcelAddress address,
184      int priority,
185      ExcelWorksheet worksheet,
186      XmlNamespaceManager namespaceManager)
187      : this(
188        position,
189        type,
190        color,
191        value,
192        formula,
193        ruleType,
194        address,
195        priority,
196        worksheet,
197        null,
198        namespaceManager)
199    {
200    }
201
202    /// <summary>
203    /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>
204    /// </summary>
205    /// <param name="position"></param>
206    /// <param name="type"></param>
207    /// <param name="color"></param>
208    /// <param name="ruleType"></param>
209    /// <param name="priority"></param>
210    /// <param name="address"></param>
211    /// <param name="worksheet"></param>
212    /// <param name="namespaceManager"></param>
213    internal ExcelConditionalFormattingColorScaleValue(
214      eExcelConditionalFormattingValueObjectPosition position,
215      eExcelConditionalFormattingValueObjectType type,
216      Color color,
217      eExcelConditionalFormattingRuleType ruleType,
218      ExcelAddress address,
219      int priority,
220      ExcelWorksheet worksheet,
221      XmlNamespaceManager namespaceManager)
222      : this(
223        position,
224        type,
225        color,
226        0,
227        null,
228        ruleType,
229        address,
230        priority,
231        worksheet,
232        null,
233        namespaceManager)
234    {
235    }
236    #endregion Constructors
237
238    /****************************************************************************************/
239
240    #region Methods
241    /// <summary>
242    /// Get the node order (1, 2 ou 3) according to the Position (Low, Middle and High)
243    /// and the Rule Type (TwoColorScale ou ThreeColorScale).
244    /// </summary>
245    /// <returns></returns>
246    private int GetNodeOrder()
247    {
248      return ExcelConditionalFormattingValueObjectType.GetOrderByPosition(
249        Position,
250        RuleType);
251    }
252
253    /// <summary>
254    /// Create the 'cfvo'/'color' nodes in the right order. They should appear like this:
255    ///   "cfvo"   --> Low Value (value object)
256    ///   "cfvo"   --> Middle Value (value object)
257    ///   "cfvo"   --> High Value (value object)
258    ///   "color"  --> Low Value (color)
259    ///   "color"  --> Middle Value (color)
260    ///   "color"  --> High Value (color)
261    /// </summary>
262    /// <param name="nodeType"></param>
263    /// <param name="attributePath"></param>
264    /// <param name="attributeValue"></param>
265    private void CreateNodeByOrdem(
266      eExcelConditionalFormattingValueObjectNodeType nodeType,
267      string attributePath,
268      string attributeValue)
269    {
270      // Save the current TopNode
271      XmlNode currentTopNode = TopNode;
272
273      string nodePath = ExcelConditionalFormattingValueObjectType.GetNodePathByNodeType(nodeType);
274      int nodeOrder = GetNodeOrder();
275      eNodeInsertOrder nodeInsertOrder = eNodeInsertOrder.SchemaOrder;
276      XmlNode referenceNode = null;
277
278      if (nodeOrder > 1)
279      {
280        // Find the node just before the one we need to include
281        referenceNode = TopNode.SelectSingleNode(
282          string.Format(
283            "{0}[position()={1}]",
284          // {0}
285            nodePath,
286          // {1}
287            nodeOrder - 1),
288          _worksheet.NameSpaceManager);
289
290        // Only if the prepend node exists than insert after
291        if (referenceNode != null)
292        {
293          nodeInsertOrder = eNodeInsertOrder.After;
294        }
295      }
296
297      // Create the node in the right order
298      var node = CreateComplexNode(
299        TopNode,
300        string.Format(
301          "{0}[position()={1}]",
302        // {0}
303          nodePath,
304        // {1}
305          nodeOrder),
306        nodeInsertOrder,
307        referenceNode);
308
309      // Point to the new node as the temporary TopNode (we need it for the XmlHelper functions)
310      TopNode = node;
311
312      // Add/Remove the attribute (if the attributeValue is empty then it will be removed)
313      SetXmlNodeString(
314        node,
315        attributePath,
316        attributeValue,
317        true);
318
319      // Point back to the <cfvo>/<color> parent node
320      TopNode = currentTopNode;
321    }
322    #endregion Methos
323
324    /****************************************************************************************/
325
326    #region Exposed Properties
327    /// <summary>
328    ///
329    /// </summary>
330    internal eExcelConditionalFormattingValueObjectPosition Position
331    {
332      get { return _position; }
333      set { _position = value; }
334    }
335
336    /// <summary>
337    ///
338    /// </summary>
339    internal eExcelConditionalFormattingRuleType RuleType
340    {
341      get { return _ruleType; }
342      set { _ruleType = value; }
343    }
344
345    /// <summary>
346    ///
347    /// </summary>
348    public eExcelConditionalFormattingValueObjectType Type
349    {
350      get
351      {
352        var typeAttribute = GetXmlNodeString(
353          string.Format(
354            "{0}[position()={1}]/{2}",
355          // {0}
356            ExcelConditionalFormattingConstants.Paths.Cfvo,
357          // {1}
358            GetNodeOrder(),
359          // {2}
360            ExcelConditionalFormattingConstants.Paths.TypeAttribute));
361
362        return ExcelConditionalFormattingValueObjectType.GetTypeByAttrbiute(typeAttribute);
363      }
364      set
365      {
366        CreateNodeByOrdem(
367          eExcelConditionalFormattingValueObjectNodeType.Cfvo,
368          ExcelConditionalFormattingConstants.Paths.TypeAttribute,
369          ExcelConditionalFormattingValueObjectType.GetAttributeByType(value));
370
371        bool removeValAttribute = false;
372
373        // Make sure unnecessary attributes are removed (occures when we change
374        // the value object type)
375        switch (Type)
376        {
377          case eExcelConditionalFormattingValueObjectType.Min:
378          case eExcelConditionalFormattingValueObjectType.Max:
379            removeValAttribute = true;
380            break;
381        }
382
383        // Check if we need to remove the @val attribute
384        if (removeValAttribute)
385        {
386          string nodePath = ExcelConditionalFormattingValueObjectType.GetNodePathByNodeType(
387            eExcelConditionalFormattingValueObjectNodeType.Cfvo);
388          int nodeOrder = GetNodeOrder();
389
390          // Remove the attribute (removed when the value = '')
391          CreateComplexNode(
392            TopNode,
393            string.Format(
394              "{0}[position()={1}]/{2}=''",
395            // {0}
396              nodePath,
397            // {1}
398              nodeOrder,
399            // {2}
400              ExcelConditionalFormattingConstants.Paths.ValAttribute));
401        }
402      }
403    }
404
405    /// <summary>
406    ///
407    /// </summary>
408    public Color Color
409    {
410      get
411      {
412        // Color Code like "FF5B34F2"
413        var colorCode = GetXmlNodeString(
414          string.Format(
415            "{0}[position()={1}]/{2}",
416          // {0}
417            ExcelConditionalFormattingConstants.Paths.Color,
418          // {1}
419            GetNodeOrder(),
420          // {2}
421            ExcelConditionalFormattingConstants.Paths.RgbAttribute));
422
423        return ExcelConditionalFormattingHelper.ConvertFromColorCode(colorCode);
424      }
425      set
426      {
427        // Use the color code to store (Ex. "FF5B35F2")
428        CreateNodeByOrdem(
429          eExcelConditionalFormattingValueObjectNodeType.Color,
430          ExcelConditionalFormattingConstants.Paths.RgbAttribute,
431          value.ToArgb().ToString("x"));
432      }
433    }
434
435    /// <summary>
436    /// Get/Set the 'cfvo' node @val attribute
437    /// </summary>
438    public Double Value
439    {
440      get
441      {
442        return GetXmlNodeDouble(
443          string.Format(
444            "{0}[position()={1}]/{2}",
445          // {0}
446            ExcelConditionalFormattingConstants.Paths.Cfvo,
447          // {1}
448            GetNodeOrder(),
449          // {2}
450            ExcelConditionalFormattingConstants.Paths.ValAttribute));
451      }
452      set
453      {
454        string valueToStore = string.Empty;
455
456        // Only some types use the @val attribute
457        if ((Type == eExcelConditionalFormattingValueObjectType.Num)
458          || (Type == eExcelConditionalFormattingValueObjectType.Percent)
459          || (Type == eExcelConditionalFormattingValueObjectType.Percentile))
460        {
461          valueToStore = value.ToString();
462        }
463
464        CreateNodeByOrdem(
465          eExcelConditionalFormattingValueObjectNodeType.Cfvo,
466          ExcelConditionalFormattingConstants.Paths.ValAttribute,
467          valueToStore);
468      }
469    }
470
471    /// <summary>
472    /// Get/Set the Formula of the Object Value (uses the same attribute as the Value)
473    /// </summary>
474    public string Formula
475    {
476      get
477      {
478        // Return empty if the Object Value type is not Formula
479        if (Type != eExcelConditionalFormattingValueObjectType.Formula)
480        {
481          return string.Empty;
482        }
483
484        // Excel stores the formula in the @val attribute
485        return GetXmlNodeString(
486          string.Format(
487            "{0}[position()={1}]/{2}",
488          // {0}
489            ExcelConditionalFormattingConstants.Paths.Cfvo,
490          // {1}
491            GetNodeOrder(),
492          // {2}
493            ExcelConditionalFormattingConstants.Paths.ValAttribute));
494      }
495      set
496      {
497        // Only store the formula if the Object Value type is Formula
498        if (Type == eExcelConditionalFormattingValueObjectType.Formula)
499        {
500          CreateNodeByOrdem(
501            eExcelConditionalFormattingValueObjectNodeType.Cfvo,
502            ExcelConditionalFormattingConstants.Paths.ValAttribute,
503            (value == null) ? string.Empty : value.ToString());
504        }
505      }
506    }
507    #endregion Exposed Properties
508
509    /****************************************************************************************/
510  }
511}
Note: See TracBrowser for help on using the repository browser.