/*******************************************************************************
* 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
*******************************************************************************/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml;
using OfficeOpenXml.Style.XmlAccess;
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Style;
///
/// Shape style
///
public enum eShapeStyle
{
AccentBorderCallout1,
AccentBorderCallout2,
AccentBorderCallout3,
AccentCallout1,
AccentCallout2,
AccentCallout3,
ActionButtonBackPrevious,
ActionButtonBeginning,
ActionButtonBlank,
ActionButtonDocument,
ActionButtonEnd,
ActionButtonForwardNext,
ActionButtonHelp,
ActionButtonHome,
ActionButtonInformation,
ActionButtonMovie,
ActionButtonReturn,
ActionButtonSound,
Arc,
BentArrow,
BentConnector2,
BentConnector3,
BentConnector4,
BentConnector5,
BentUpArrow,
Bevel,
BlockArc,
BorderCallout1,
BorderCallout2,
BorderCallout3,
BracePair,
BracketPair,
Callout1,
Callout2,
Callout3,
Can,
ChartPlus,
ChartStar,
ChartX,
Chevron,
Chord,
CircularArrow,
Cloud,
CloudCallout,
Corner,
CornerTabs,
Cube,
CurvedConnector2,
CurvedConnector3,
CurvedConnector4,
CurvedConnector5,
CurvedDownArrow,
CurvedLeftArrow,
CurvedRightArrow,
CurvedUpArrow,
Decagon,
DiagStripe,
Diamond,
Dodecagon,
Donut,
DoubleWave,
DownArrow,
DownArrowCallout,
Ellipse,
EllipseRibbon,
EllipseRibbon2,
FlowChartAlternateProcess,
FlowChartCollate,
FlowChartConnector,
FlowChartDecision,
FlowChartDelay,
FlowChartDisplay,
FlowChartDocument,
FlowChartExtract,
FlowChartInputOutput,
FlowChartInternalStorage,
FlowChartMagneticDisk,
FlowChartMagneticDrum,
FlowChartMagneticTape,
FlowChartManualInput,
FlowChartManualOperation,
FlowChartMerge,
FlowChartMultidocument,
FlowChartOfflineStorage,
FlowChartOffpageConnector,
FlowChartOnlineStorage,
FlowChartOr,
FlowChartPredefinedProcess,
FlowChartPreparation,
FlowChartProcess,
FlowChartPunchedCard,
FlowChartPunchedTape,
FlowChartSort,
FlowChartSummingJunction,
FlowChartTerminator,
FoldedCorner,
Frame,
Funnel,
Gear6,
Gear9,
HalfFrame,
Heart,
Heptagon,
Hexagon,
HomePlate,
HorizontalScroll,
IrregularSeal1,
IrregularSeal2,
LeftArrow,
LeftArrowCallout,
LeftBrace,
LeftBracket,
LeftCircularArrow,
LeftRightArrow,
LeftRightArrowCallout,
LeftRightCircularArrow,
LeftRightRibbon,
LeftRightUpArrow,
LeftUpArrow,
LightningBolt,
Line,
LineInv,
MathDivide,
MathEqual,
MathMinus,
MathMultiply,
MathNotEqual,
MathPlus,
Moon,
NonIsoscelesTrapezoid,
NoSmoking,
NotchedRightArrow,
Octagon,
Parallelogram,
Pentagon,
Pie,
PieWedge,
Plaque,
PlaqueTabs,
Plus,
QuadArrow,
QuadArrowCallout,
Rect,
Ribbon,
Ribbon2,
RightArrow,
RightArrowCallout,
RightBrace,
RightBracket,
Round1Rect,
Round2DiagRect,
Round2SameRect,
RoundRect,
RtTriangle,
SmileyFace,
Snip1Rect,
Snip2DiagRect,
Snip2SameRect,
SnipRoundRect,
SquareTabs,
Star10,
Star12,
Star16,
Star24,
Star32,
Star4,
Star5,
Star6,
Star7,
Star8,
StraightConnector1,
StripedRightArrow,
Sun,
SwooshArrow,
Teardrop,
Trapezoid,
Triangle,
UpArrow,
UpArrowCallout,
UpDownArrow,
UpDownArrowCallout,
UturnArrow,
Wave,
WedgeEllipseCallout,
WedgeRectCallout,
WedgeRoundRectCallout,
VerticalScroll
}
///
/// Text alignment
///
public enum eTextAlignment
{
Left,
Center,
Right,
Distributed,
Justified,
JustifiedLow,
ThaiDistributed
}
///
/// Fillstyle.
///
public enum eFillStyle
{
NoFill,
SolidFill,
GradientFill,
PatternFill,
BlipFill,
GroupFill
}
namespace OfficeOpenXml.Drawing
{
///
/// An Excel shape.
///
public sealed class ExcelShape : ExcelDrawing
{
internal ExcelShape(ExcelDrawings drawings, XmlNode node) :
base(drawings, node, "xdr:sp/xdr:nvSpPr/xdr:cNvPr/@name")
{
init();
}
internal ExcelShape(ExcelDrawings drawings, XmlNode node, eShapeStyle style) :
base(drawings, node, "xdr:sp/xdr:nvSpPr/xdr:cNvPr/@name")
{
init();
XmlElement shapeNode = node.OwnerDocument.CreateElement("xdr", "sp", ExcelPackage.schemaSheetDrawings);
shapeNode.SetAttribute("macro", "");
shapeNode.SetAttribute("textlink", "");
node.AppendChild(shapeNode);
shapeNode.InnerXml = ShapeStartXml();
node.AppendChild(shapeNode.OwnerDocument.CreateElement("xdr", "clientData", ExcelPackage.schemaSheetDrawings));
}
private void init()
{
SchemaNodeOrder = new string[] { "prstGeom", "ln", "pPr", "defRPr", "solidFill", "uFill", "latin", "cs", "r", "rPr", "t" };
}
#region "public methods"
const string ShapeStylePath = "xdr:sp/xdr:spPr/a:prstGeom/@prst";
///
/// Shape style
///
public eShapeStyle Style
{
get
{
string v = GetXmlNodeString(ShapeStylePath);
try
{
return (eShapeStyle)Enum.Parse(typeof(eShapeStyle), v, true);
}
catch
{
throw (new Exception(string.Format("Invalid shapetype {0}", v)));
}
}
set
{
string v = value.ToString();
v = v.Substring(0, 1).ToLower(CultureInfo.InvariantCulture) + v.Substring(1, v.Length - 1);
SetXmlNodeString(ShapeStylePath, v);
}
}
ExcelDrawingFill _fill = null;
///
/// Fill
///
public ExcelDrawingFill Fill
{
get
{
if (_fill == null)
{
_fill = new ExcelDrawingFill(NameSpaceManager, TopNode, "xdr:sp/xdr:spPr");
}
return _fill;
}
}
ExcelDrawingBorder _border = null;
///
/// Border
///
public ExcelDrawingBorder Border
{
get
{
if (_border == null)
{
_border = new ExcelDrawingBorder(NameSpaceManager, TopNode, "xdr:sp/xdr:spPr/a:ln");
}
return _border;
}
}
string[] paragraphNodeOrder = new string[] { "pPr", "defRPr", "solidFill", "uFill", "latin", "cs", "r", "rPr", "t" };
const string PARAGRAPH_PATH = "xdr:sp/xdr:txBody/a:p";
ExcelTextFont _font=null;
public ExcelTextFont Font
{
get
{
if (_font == null)
{
XmlNode node = TopNode.SelectSingleNode(PARAGRAPH_PATH, NameSpaceManager);
if(node==null)
{
Text=""; //Creates the node p element
node = TopNode.SelectSingleNode(PARAGRAPH_PATH, NameSpaceManager);
}
_font = new ExcelTextFont(NameSpaceManager, TopNode, "xdr:sp/xdr:txBody/a:p/a:pPr/a:defRPr", paragraphNodeOrder);
}
return _font;
}
}
const string TextPath = "xdr:sp/xdr:txBody/a:p/a:r/a:t";
///
/// Text inside the shape
///
public string Text
{
get
{
return GetXmlNodeString(TextPath);
}
set
{
SetXmlNodeString(TextPath, value);
}
}
string lockTextPath = "xdr:sp/@fLocksText";
///
/// Lock drawing
///
public bool LockText
{
get
{
return GetXmlNodeBool(lockTextPath, true);
}
set
{
SetXmlNodeBool(lockTextPath, value);
}
}
ExcelParagraphCollection _richText = null;
///
/// Richtext collection. Used to format specific parts of the text
///
public ExcelParagraphCollection RichText
{
get
{
if (_richText == null)
{
//XmlNode node=TopNode.SelectSingleNode(PARAGRAPH_PATH, NameSpaceManager);
//if (node == null)
//{
// CreateNode(PARAGRAPH_PATH);
//}
_richText = new ExcelParagraphCollection(NameSpaceManager, TopNode, PARAGRAPH_PATH, paragraphNodeOrder);
}
return _richText;
}
}
const string TextAnchoringPath = "xdr:sp/xdr:txBody/a:bodyPr/@anchor";
///
/// Text Anchoring
///
public eTextAnchoringType TextAnchoring
{
get
{
return GetTextAchoringEnum(GetXmlNodeString(TextAnchoringPath));
}
set
{
SetXmlNodeString(TextAnchoringPath, GetTextAchoringText(value));
}
}
const string TextAnchoringCtlPath = "xdr:sp/xdr:txBody/a:bodyPr/@anchorCtr";
///
/// Specifies the centering of the text box.
///
public bool TextAnchoringControl
{
get
{
return GetXmlNodeBool(TextAnchoringCtlPath);
}
set
{
if (value)
{
SetXmlNodeString(TextAnchoringCtlPath, "1");
}
else
{
SetXmlNodeString(TextAnchoringCtlPath, "0");
}
}
}
const string TEXT_ALIGN_PATH = "xdr:sp/xdr:txBody/a:p/a:pPr/@algn";
///
/// How the text is aligned
///
public eTextAlignment TextAlignment
{
get
{
switch(GetXmlNodeString(TEXT_ALIGN_PATH))
{
case "ctr":
return eTextAlignment.Center;
case "r":
return eTextAlignment.Right;
case "dist":
return eTextAlignment.Distributed;
case "just":
return eTextAlignment.Justified;
case "justLow":
return eTextAlignment.JustifiedLow;
case "thaiDist":
return eTextAlignment.ThaiDistributed;
default:
return eTextAlignment.Left;
}
}
set
{
switch (value)
{
case eTextAlignment.Right:
SetXmlNodeString(TEXT_ALIGN_PATH, "r");
break;
case eTextAlignment.Center:
SetXmlNodeString(TEXT_ALIGN_PATH, "ctr");
break;
case eTextAlignment.Distributed:
SetXmlNodeString(TEXT_ALIGN_PATH, "dist");
break;
case eTextAlignment.Justified:
SetXmlNodeString(TEXT_ALIGN_PATH, "just");
break;
case eTextAlignment.JustifiedLow:
SetXmlNodeString(TEXT_ALIGN_PATH, "justLow");
break;
case eTextAlignment.ThaiDistributed:
SetXmlNodeString(TEXT_ALIGN_PATH, "thaiDist");
break;
default:
DeleteNode(TEXT_ALIGN_PATH);
break;
}
}
}
const string INDENT_ALIGN_PATH = "xdr:sp/xdr:txBody/a:p/a:pPr/@lvl";
///
/// Indentation
///
public int Indent
{
get
{
return GetXmlNodeInt(INDENT_ALIGN_PATH);
}
set
{
if (value < 0 || value > 8)
{
throw(new ArgumentOutOfRangeException("Indent level must be between 0 and 8"));
}
SetXmlNodeString(INDENT_ALIGN_PATH, value.ToString());
}
}
const string TextVerticalPath = "xdr:sp/xdr:txBody/a:bodyPr/@vert";
///
/// Vertical text
///
public eTextVerticalType TextVertical
{
get
{
return GetTextVerticalEnum(GetXmlNodeString(TextVerticalPath));
}
set
{
SetXmlNodeString(TextVerticalPath, GetTextVerticalText(value));
}
}
#endregion
#region "Private Methods"
private string ShapeStartXml()
{
StringBuilder xml = new StringBuilder();
xml.AppendFormat("", _id, Name);
return xml.ToString();
}
#endregion
internal new string Id
{
get { return Name + Text; }
}
}
}