blob: e585a770bafd13416ff1d118505978daf9576083 [file] [log] [blame]
/*******************************************************************************
* 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; }
}