| /******************************************************************************* | |
| * 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 | |
| * ****************************************************************************** | |
| * Jan Källman Initial Release 2009-10-01 | |
| * Jan Källman License changed GPL-->LGPL 2011-12-16 | |
| * Richard Tallent Fix inadvertent removal of XML node 2012-10-31 | |
| * Richard Tallent Remove VertAlign node if no alignment specified 2012-10-31 | |
| *******************************************************************************/ | |
| using System; | |
| using System.Collections.Immutable; | |
| using System.Globalization; | |
| using System.Xml; | |
| namespace AppsheetEpplus; | |
| /// <summary> | |
| /// A richtext part | |
| /// </summary> | |
| public class ExcelRichText : XmlHelper { | |
| protected override ImmutableArray<string> SchemaNodeOrder { get; } = [ | |
| "rPr", | |
| "t", | |
| "b", | |
| "i", | |
| "strike", | |
| "u", | |
| "vertAlign", | |
| "sz", | |
| "color", | |
| "rFont", | |
| "family", | |
| "scheme", | |
| "charset", | |
| ]; | |
| internal ExcelRichText( | |
| XmlNamespaceManager ns, | |
| XmlNode topNode, | |
| ExcelRichTextCollection collection) | |
| : base(ns, topNode) { | |
| _collection = collection; | |
| } | |
| internal delegate void CallbackDelegate(); | |
| private CallbackDelegate _callback; | |
| internal void SetCallback(CallbackDelegate callback) { | |
| _callback = callback; | |
| } | |
| private const string _textPath = "d:t"; | |
| /// <summary> | |
| /// The text | |
| /// </summary> | |
| public string Text { | |
| get { | |
| // Bug 15151 | |
| if (TopNode.Name == "t") { | |
| return TopNode.InnerText; | |
| } | |
| return GetXmlNodeString(_textPath); | |
| } | |
| set { | |
| _collection.ConvertRichtext(); | |
| // Don't remove if blank -- setting a blank rich text value on a node is common, | |
| // for example when applying both bold and italic to text. | |
| SetXmlNodeString(_textPath, value, false); | |
| if (PreserveSpace) { | |
| XmlElement elem = TopNode.SelectSingleNode(_textPath, NameSpaceManager) as XmlElement; | |
| elem.SetAttribute("xml:space", "preserve"); | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| /// <summary> | |
| /// Preserves whitespace. Default true | |
| /// </summary> | |
| public bool PreserveSpace { | |
| get { | |
| XmlElement elem = TopNode.SelectSingleNode(_textPath, NameSpaceManager) as XmlElement; | |
| if (elem != null) { | |
| return elem.GetAttribute("xml:space") == "preserve"; | |
| } | |
| return false; | |
| } | |
| set { | |
| _collection.ConvertRichtext(); | |
| XmlElement elem = TopNode.SelectSingleNode(_textPath, NameSpaceManager) as XmlElement; | |
| if (elem != null) { | |
| if (value) { | |
| elem.SetAttribute("xml:space", "preserve"); | |
| } else { | |
| elem.RemoveAttribute("xml:space"); | |
| } | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _boldPath = "d:rPr/d:b"; | |
| /// <summary> | |
| /// Bold text | |
| /// </summary> | |
| public bool Bold { | |
| get => ExistNode(_boldPath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| if (value) { | |
| CreateNode(_boldPath); | |
| } else { | |
| DeleteNode(_boldPath); | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _italicPath = "d:rPr/d:i"; | |
| /// <summary> | |
| /// Italic text | |
| /// </summary> | |
| public bool Italic { | |
| get => | |
| //return GetXmlNodeBool(ITALIC_PATH, false); | |
| ExistNode(_italicPath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| if (value) { | |
| CreateNode(_italicPath); | |
| } else { | |
| DeleteNode(_italicPath); | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _strikePath = "d:rPr/d:strike"; | |
| /// <summary> | |
| /// Strike-out text | |
| /// </summary> | |
| public bool Strike { | |
| get => ExistNode(_strikePath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| if (value) { | |
| CreateNode(_strikePath); | |
| } else { | |
| DeleteNode(_strikePath); | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _underlinePath = "d:rPr/d:u"; | |
| /// <summary> | |
| /// Underlined text | |
| /// </summary> | |
| public bool UnderLine { | |
| get => ExistNode(_underlinePath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| if (value) { | |
| CreateNode(_underlinePath); | |
| } else { | |
| DeleteNode(_underlinePath); | |
| } | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _vertAlignPath = "d:rPr/d:vertAlign/@val"; | |
| /// <summary> | |
| /// Vertical Alignment | |
| /// </summary> | |
| public ExcelVerticalAlignmentFont VerticalAlign => | |
| Enum.TryParse<ExcelVerticalAlignmentFont>( | |
| GetXmlNodeString(TopNode, _vertAlignPath), | |
| true, | |
| out var result) | |
| ? result | |
| : ExcelVerticalAlignmentFont.None; | |
| private const string _sizePath = "d:rPr/d:sz/@val"; | |
| /// <summary> | |
| /// Font size | |
| /// </summary> | |
| public float Size { | |
| get => Convert.ToSingle(GetXmlNodeDecimal(_sizePath)); | |
| set { | |
| _collection.ConvertRichtext(); | |
| SetXmlNodeString(_sizePath, value.ToString(CultureInfo.InvariantCulture)); | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _fontPath = "d:rPr/d:rFont/@val"; | |
| /// <summary> | |
| /// Name of the font | |
| /// </summary> | |
| public string FontName { | |
| get => GetXmlNodeString(_fontPath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| SetXmlNodeString(_fontPath, value); | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| private const string _colorPath = "d:rPr/d:color/@rgb"; | |
| /// <summary> | |
| /// Text color | |
| /// </summary> | |
| public string Color { | |
| get => GetXmlNodeString(_colorPath); | |
| set { | |
| _collection.ConvertRichtext(); | |
| SetXmlNodeString(_colorPath, value); | |
| if (_callback != null) { | |
| _callback(); | |
| } | |
| } | |
| } | |
| public ExcelRichTextCollection _collection { get; set; } | |
| } |