diff --git a/OpenXmlFormats/Drawing/ShapeGeometry.cs b/OpenXmlFormats/Drawing/ShapeGeometry.cs index c2827c8db..e2aca451a 100644 --- a/OpenXmlFormats/Drawing/ShapeGeometry.cs +++ b/OpenXmlFormats/Drawing/ShapeGeometry.cs @@ -711,7 +711,7 @@ public enum ST_TextShapeType [Serializable] - [DebuggerStepThrough] + //[DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -772,33 +772,56 @@ public string fmla [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] public class CT_Path2DCubicBezierTo { - private CT_AdjPoint2D[] ptField; + private List pts = null; + public static CT_Path2DCubicBezierTo Parse(XmlNode node, XmlNamespaceManager namespaceManager) + { + CT_Path2DCubicBezierTo obj = new CT_Path2DCubicBezierTo(); + foreach(XmlNode childNode in node.ChildNodes) { + if(childNode.LocalName == "pt") { + obj.pts.Add(CT_AdjPoint2D.Parse(childNode, namespaceManager)); + } + } + return obj; + } - [XmlElement("pt", Order = 0)] - public CT_AdjPoint2D[] pt + internal void Write(StreamWriter sw, string nodeName) { + + sw.Write("", nodeName); + foreach(var cub in pts) { + cub.Write(sw, "pt"); + } + sw.Write("", nodeName); + } + + public CT_Path2DCubicBezierTo() { + pts = new List(); + } + + [XmlElement("pt", Order = 0)] + public List pt { get { - return this.ptField; + return this.pts; } set { - this.ptField = value; + this.pts = value; } } } [Serializable] - [DebuggerStepThrough] + //[DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -826,8 +849,8 @@ internal void Write(StreamWriter sw, string nodeName) sw.Write(string.Format(""); - sw.Write(string.Format("", nodeName)); + sw.Write("/>"); + } [XmlAttribute] @@ -860,7 +883,7 @@ public string y [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -886,7 +909,7 @@ public CT_AdjPoint2D[] pt [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -948,7 +971,7 @@ internal void Write(StreamWriter sw, string nodeName) [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1045,7 +1068,7 @@ public string b [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1166,7 +1189,7 @@ public string maxY [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1287,7 +1310,7 @@ public string maxAng [Serializable] - [DebuggerStepThrough] + //[DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1353,7 +1376,7 @@ public string ang [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1380,7 +1403,7 @@ public object[] Items [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1433,7 +1456,7 @@ internal void Write(StreamWriter sw, string nodeName) [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1494,19 +1517,41 @@ public uint idx [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] public class CT_Path2DMoveTo { - private CT_AdjPoint2D ptField; + private CT_AdjPoint2D ptField = null; public CT_Path2DMoveTo() { this.ptField = new CT_AdjPoint2D(); } - [XmlElement(Order = 0)] + + public static CT_Path2DMoveTo Parse(XmlNode node, XmlNamespaceManager namespaceManager) + { + CT_Path2DMoveTo obj = new CT_Path2DMoveTo(); + foreach(XmlNode childNode in node.ChildNodes) { + if(childNode.LocalName == "pt") { + obj.ptField = CT_AdjPoint2D.Parse(childNode, namespaceManager); + } + } + return obj; + } + + internal void Write(StreamWriter sw, string nodeName) { + + sw.Write("", nodeName); + + if(this.ptField != null) { + this.ptField.Write(sw, "pt"); + } + sw.Write("", nodeName); + } + + [XmlElement(Order = 0)] public CT_AdjPoint2D pt { get @@ -1522,7 +1567,7 @@ public CT_AdjPoint2D pt [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1552,7 +1597,7 @@ public CT_AdjPoint2D pt [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1626,7 +1671,7 @@ public string swAng [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1661,7 +1706,7 @@ public enum ST_PathFillMode [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1681,7 +1726,12 @@ public class CT_Path2D private bool strokeField; private bool extrusionOkField; - public static CT_Path2D Parse(XmlNode node, XmlNamespaceManager namespaceManager) + + private CT_Path2DMoveTo moveToFeild = null; + + private List cubicBezTo = null; + + public static CT_Path2D Parse(XmlNode node, XmlNamespaceManager namespaceManager) { if (node == null) return null; @@ -1690,14 +1740,18 @@ public static CT_Path2D Parse(XmlNode node, XmlNamespaceManager namespaceManager ctObj.h = XmlHelper.ReadLong(node.Attributes["h"]); if (node.Attributes["fill"] != null) ctObj.fill = (ST_PathFillMode)Enum.Parse(typeof(ST_PathFillMode), node.Attributes["fill"].Value); - ctObj.stroke = XmlHelper.ReadBool(node.Attributes["stroke"]); + ctObj.stroke = XmlHelper.ReadBool(node.Attributes["stroke"], true); ctObj.extrusionOk = XmlHelper.ReadBool(node.Attributes["extrusionOk"]); - //foreach(XmlNode childNode in node.ChildNodes) - //{ + foreach(XmlNode childNode in node.ChildNodes) + { // if(childNode.LocalName == "ItemsElementName") // ctObj.ItemsElementName = ItemsChoiceType[].Parse(childNode, namespaceManager); - //} - return ctObj; + if(childNode.LocalName == "moveTo") + ctObj.moveToFeild = CT_Path2DMoveTo.Parse(childNode, namespaceManager); + if(childNode.LocalName == "cubicBezTo") + ctObj.cubicBezTo.Add( CT_Path2DCubicBezierTo.Parse(childNode, namespaceManager)); + } + return ctObj; } @@ -1711,9 +1765,16 @@ internal void Write(StreamWriter sw, string nodeName) XmlHelper.WriteAttribute(sw, "stroke", this.stroke); XmlHelper.WriteAttribute(sw, "extrusionOk", this.extrusionOk); sw.Write(">"); - //if (this.ItemsElementName != null) - // this.ItemsElementName.Write(sw, "ItemsElementName"); - sw.Write(string.Format("", nodeName)); + //if (this.ItemsElementName != null) + // this.ItemsElementName.Write(sw, "ItemsElementName"); + if(this.moveToFeild != null) + moveToFeild.Write(sw, "moveTo"); + if(cubicBezTo.Count > 0) { + foreach(CT_Path2DCubicBezierTo cub in cubicBezTo) { + cub.Write(sw, "cubicBezTo"); + } + } + sw.Write(string.Format("", nodeName)); } public CT_Path2D() @@ -1723,7 +1784,9 @@ public CT_Path2D() this.fillField = ST_PathFillMode.norm; this.strokeField = true; this.extrusionOkField = true; - } + + this.cubicBezTo = new List(); + } //[XmlElement("arcTo", typeof(CT_Path2DArcTo))] @@ -1863,7 +1926,7 @@ public enum ItemsChoiceType [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -1917,7 +1980,7 @@ internal void Write(StreamWriter sw, string nodeName) [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -2000,7 +2063,7 @@ public ST_ShapeType prst [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] @@ -2074,7 +2137,7 @@ public ST_TextShapeType prst [Serializable] - [System.Diagnostics.DebuggerStepThrough] + //[System.Diagnostics.DebuggerStepThrough] [System.ComponentModel.DesignerCategory("code")] [XmlType(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main")] [XmlRoot(Namespace = "http://schemas.openxmlformats.org/drawingml/2006/main", IsNullable = true)] diff --git a/OpenXmlFormats/Drawing/SpreadsheetDrawing.cs b/OpenXmlFormats/Drawing/SpreadsheetDrawing.cs index 2ff68226c..7beeec7b5 100644 --- a/OpenXmlFormats/Drawing/SpreadsheetDrawing.cs +++ b/OpenXmlFormats/Drawing/SpreadsheetDrawing.cs @@ -1259,8 +1259,8 @@ public static CT_AnchorClientData Parse(XmlNode node, XmlNamespaceManager namesp if (node == null) return null; CT_AnchorClientData ctObj = new CT_AnchorClientData(); - ctObj.fLocksWithSheet = XmlHelper.ReadBool(node.Attributes["fLocksWithSheet"]); - ctObj.fPrintsWithSheet = XmlHelper.ReadBool(node.Attributes["fPrintsWithSheet"]); + ctObj.fLocksWithSheet = XmlHelper.ReadBool(node.Attributes["fLocksWithSheet"], true); + ctObj.fPrintsWithSheet = XmlHelper.ReadBool(node.Attributes["fPrintsWithSheet"], true); return ctObj; } @@ -1269,12 +1269,12 @@ public static CT_AnchorClientData Parse(XmlNode node, XmlNamespaceManager namesp internal void Write(StreamWriter sw, string nodeName) { sw.Write(string.Format(""); } - bool _fLocksWithSheet; - bool _fPrintsWithSheet; + bool _fLocksWithSheet = true; + bool _fPrintsWithSheet = true; [XmlAttribute] public bool fLocksWithSheet diff --git a/OpenXmlFormats/Drawing/Text.cs b/OpenXmlFormats/Drawing/Text.cs index fb4138a5d..640764117 100644 --- a/OpenXmlFormats/Drawing/Text.cs +++ b/OpenXmlFormats/Drawing/Text.cs @@ -513,10 +513,10 @@ public static CT_TextBodyProperties Parse(XmlNode node, XmlNamespaceManager name ctObj.wrapFieldSpecified = node.Attributes["wrap"] != null; if (node.Attributes["wrap"] != null) ctObj.wrapField = (ST_TextWrappingType)Enum.Parse(typeof(ST_TextWrappingType), node.Attributes["wrap"].Value); - ctObj.lIns = XmlHelper.ReadInt(node.Attributes["lIns"]); - ctObj.tIns = XmlHelper.ReadInt(node.Attributes["tIns"]); - ctObj.rIns = XmlHelper.ReadInt(node.Attributes["rIns"]); - ctObj.bIns = XmlHelper.ReadInt(node.Attributes["bIns"]); + ctObj.lIns = XmlHelper.ReadInt(node.Attributes["lIns"], 91440); + ctObj.tIns = XmlHelper.ReadInt(node.Attributes["tIns"], 45720); + ctObj.rIns = XmlHelper.ReadInt(node.Attributes["rIns"], 91440); + ctObj.bIns = XmlHelper.ReadInt(node.Attributes["bIns"], 45720); ctObj.numCol = XmlHelper.ReadInt(node.Attributes["numCol"]); ctObj.spcCol = XmlHelper.ReadInt(node.Attributes["spcCol"]); ctObj.rtlCol = XmlHelper.ReadBool(node.Attributes["rtlCol"]); @@ -565,12 +565,12 @@ internal void Write(StreamWriter sw, string nodeName) XmlHelper.WriteAttribute(sw, "horzOverflow", this.horzOverflowField.ToString()); if(this.vertFieldSpecified) XmlHelper.WriteAttribute(sw, "vert", this.vert.ToString()); - if(this.wrapFieldSpecified && this.wrap!= ST_TextWrappingType.none) + if(this.wrapFieldSpecified && this.wrap == ST_TextWrappingType.none) XmlHelper.WriteAttribute(sw, "wrap", this.wrap.ToString()); - XmlHelper.WriteAttribute(sw, "lIns", this.lIns); - XmlHelper.WriteAttribute(sw, "tIns", this.tIns); - XmlHelper.WriteAttribute(sw, "rIns", this.rIns); - XmlHelper.WriteAttribute(sw, "bIns", this.bIns); + XmlHelper.WriteAttribute(sw, "lIns", this.lIns, 91440); + XmlHelper.WriteAttribute(sw, "tIns", this.tIns, 45720); + XmlHelper.WriteAttribute(sw, "rIns", this.rIns, 91440); + XmlHelper.WriteAttribute(sw, "bIns", this.bIns, 45720); XmlHelper.WriteAttribute(sw, "numCol", this.numCol); XmlHelper.WriteAttribute(sw, "spcCol", this.spcCol); XmlHelper.WriteAttribute(sw, "rtlCol", this.rtlCol); @@ -887,7 +887,7 @@ public int lIns set { this.lInsField = value; - this.lInsFieldSpecified = true; + this.lInsFieldSpecified = value == 91440 ? false : true; } } @@ -916,7 +916,7 @@ public int tIns set { this.tInsField = value; - this.tInsFieldSpecified = true; + this.tInsFieldSpecified = value == 45720 ? false : true; } } @@ -945,7 +945,7 @@ public int rIns set { this.rInsField = value; - this.rInsFieldSpecified = true; + this.rInsFieldSpecified = value == 91440 ? false : true; } } @@ -974,7 +974,7 @@ public int bIns set { this.bInsField = value; - this.bInsFieldSpecified = true; + this.bInsFieldSpecified = value == 45720 ? false : true; } } diff --git a/OpenXmlFormats/Drawing/spreadsheetShape.cs b/OpenXmlFormats/Drawing/spreadsheetShape.cs index 232e54b68..32a8ca5d4 100644 --- a/OpenXmlFormats/Drawing/spreadsheetShape.cs +++ b/OpenXmlFormats/Drawing/spreadsheetShape.cs @@ -595,14 +595,17 @@ public class CT_GroupShape { CT_GroupShapeProperties grpSpPrField; CT_GroupShapeNonVisual nvGrpSpPrField; - CT_Connector connectorField = null; + List connectors = null; List pictures = null; List shapes = null; + List groups = null; public CT_GroupShape() { + this.connectors = new List(); this.pictures = new List(); this.shapes = new List(); + this.groups = new List(); } public void Set(CT_GroupShape groupShape) @@ -623,7 +626,8 @@ public CT_GroupShapeNonVisual AddNewNvGrpSpPr() } public CT_Connector AddNewCxnSp() { - connectorField = new CT_Connector(); + var connectorField = new CT_Connector(); + connectors.Add(connectorField); return connectorField; } public CT_Shape AddNewSp() @@ -638,6 +642,12 @@ public CT_Picture AddNewPic() pictures.Add(pic); return pic; } + public CT_GroupShape AddNewGroup() + { + var group = new CT_GroupShape(); + groups.Add(group); + return group; + } public CT_GroupShapeNonVisual nvGrpSpPr { @@ -650,6 +660,39 @@ public CT_GroupShapeProperties grpSpPr set { grpSpPrField = value; } } + public void GetShapes(List aShapes) // a:Argument + { + aShapes.Add(this); + if(connectors != null) + { + foreach(var c in connectors) + { + aShapes.Add(c); + } + } + if(pictures != null) + { + foreach(var p in pictures) + { + aShapes.Add(p); + } + } + if(shapes != null) + { + foreach(var s in shapes) + { + aShapes.Add(s); + } + } + if(groups != null) + { + foreach(var shp in groups) + { + shp.GetShapes(aShapes); + } + } + } + public static CT_GroupShape Parse(XmlNode node, XmlNamespaceManager namespaceManager) { if (node == null) @@ -671,6 +714,16 @@ public static CT_GroupShape Parse(XmlNode node, XmlNamespaceManager namespaceMan var shape = CT_Shape.Parse(childNode, namespaceManager); ctObj.shapes.Add(shape); } + else if (childNode.LocalName == "cxnSp") + { + var connector = CT_Connector.Parse(childNode, namespaceManager); + ctObj.connectors.Add(connector); + } + else if (childNode.LocalName == "grpSp") + { + var group = CT_GroupShape.Parse(childNode, namespaceManager); + ctObj.groups.Add(group); + } } return ctObj; } @@ -699,6 +752,20 @@ internal void Write(StreamWriter sw, string nodeName) pic.Write(sw, "pic"); } } + if (this.connectors.Count > 0) + { + foreach(var con in this.connectors) + { + con.Write(sw, "cxnSp"); + } + } + if (this.groups.Count > 0) + { + foreach(var group in this.groups) + { + group.Write(sw, "grpSp"); + } + } sw.Write(string.Format("", nodeName)); } diff --git a/OpenXmlFormats/Spreadsheet/Sheet.cs b/OpenXmlFormats/Spreadsheet/Sheet.cs index 8e4b8f0b8..2d9fcb026 100644 --- a/OpenXmlFormats/Spreadsheet/Sheet.cs +++ b/OpenXmlFormats/Spreadsheet/Sheet.cs @@ -2599,7 +2599,7 @@ public static CT_SheetFormatPr Parse(XmlNode node, XmlNamespaceManager namespace if (node == null) return null; CT_SheetFormatPr ctObj = new CT_SheetFormatPr(); - ctObj.baseColWidth = XmlHelper.ReadUInt(node.Attributes["baseColWidth"]); + ctObj.baseColWidth = XmlHelper.ReadUInt(node.Attributes["baseColWidth"],8); ctObj.defaultColWidth = XmlHelper.ReadDouble(node.Attributes["defaultColWidth"]); ctObj.defaultRowHeight = XmlHelper.ReadDouble(node.Attributes["defaultRowHeight"]); ctObj.customHeight = XmlHelper.ReadBool(node.Attributes["customHeight"]); diff --git a/main/SS/UserModel/LineStyle.cs b/main/SS/UserModel/LineStyle.cs index 82c5891be..024950c4e 100644 --- a/main/SS/UserModel/LineStyle.cs +++ b/main/SS/UserModel/LineStyle.cs @@ -19,4 +19,24 @@ public enum LineStyle:int LongDashDotGel = 9, // long dash short dash LongDashDotDotGel = 10, // long dash short dash short dash } + + // End Line Cap + public enum LineEndingCapType : int + { + None, + Round, // Rounded ends. Semi-circle protrudes by half line width. + Square, // Square protrudes by half line width. + Flat, // Line ends at end point. + } + + // Compound Line Type + public enum CompoundLineType : int + { + None, + SingleLine, // Single line: one normal width + DoubleLines, // Double lines of equal width + ThickThin, // Double lines: one thick, one thin + ThinThick, // Double lines: one thin, one thick + TripleLines // Three lines: thin, thick, thin + } } \ No newline at end of file diff --git a/main/SS/UserModel/Shape.cs b/main/SS/UserModel/Shape.cs index b1750b378..a7a0891a4 100644 --- a/main/SS/UserModel/Shape.cs +++ b/main/SS/UserModel/Shape.cs @@ -8,6 +8,9 @@ public interface IShape { IShape Parent { get; } + uint ID { get; } + string Name { get; set; } + void SetLineStyleColor(int lineStyleColor); void SetLineStyleColor(int red, int green, int blue); void SetFillColor(int red, int green, int blue); @@ -17,6 +20,8 @@ public interface IShape int FillColor { get; set; } double LineWidth { get; set; } LineStyle LineStyle { get; set; } + LineEndingCapType LineEndingCapType{ get; set; } + CompoundLineType CompoundLineType { get; set; } bool IsNoFill { get; set; } int CountOfAllChildren { get; } } diff --git a/ooxml/XSSF/UserModel/XSSFChildAnchor.cs b/ooxml/XSSF/UserModel/XSSFChildAnchor.cs index 36b280ce4..97e75aab3 100644 --- a/ooxml/XSSF/UserModel/XSSFChildAnchor.cs +++ b/ooxml/XSSF/UserModel/XSSFChildAnchor.cs @@ -30,12 +30,12 @@ public XSSFChildAnchor(int x, int y, int cx, int cy) CT_Point2D off = t2d.AddNewOff(); CT_PositiveSize2D ext = t2d.AddNewExt(); - off.x = (x); - off.y = (y); - ext.cx = (Math.Abs(cx - x)); - ext.cy = (Math.Abs(cy - y)); - if (x > cx) t2d.flipH = (true); - if (y > cy) t2d.flipV = (true); + off.x = Math.Min(x, cx); + off.y = Math.Min(y, cy); + ext.cx = Math.Abs(cx - x); + ext.cy = Math.Abs(cy - y); + if (x > cx) t2d.flipH = true; + if (y > cy) t2d.flipV = true; } public XSSFChildAnchor(CT_Transform2D t2d) diff --git a/ooxml/XSSF/UserModel/XSSFChildGroupAnchor.cs b/ooxml/XSSF/UserModel/XSSFChildGroupAnchor.cs new file mode 100644 index 000000000..4b0a2a4cc --- /dev/null +++ b/ooxml/XSSF/UserModel/XSSFChildGroupAnchor.cs @@ -0,0 +1,109 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NPOI.OpenXmlFormats.Dml; + +namespace NPOI.XSSF.UserModel { + public class XSSFChildGroupAnchor : XSSFAnchor + { + private CT_GroupTransform2D gt2d; + public XSSFChildGroupAnchor(int x, int y, int cx, int cy) + { + gt2d = new CT_GroupTransform2D(); + CT_Point2D off = gt2d.AddNewOff(); + CT_PositiveSize2D ext = gt2d.AddNewExt(); + CT_Point2D chOff = gt2d.AddNewChOff(); + CT_PositiveSize2D chExt = gt2d.AddNewChExt(); + + off.x = Math.Min(x, cx); + off.y = Math.Min(y, cy); + ext.cx = Math.Abs(cx - x); + ext.cy = Math.Abs(cy - y); + if (x > cx) gt2d.flipH = true; + if (y > cy) gt2d.flipV = true; + + chOff.x = off.x; + chOff.y = off.y; + chExt.cx = ext.cx; + chExt.cy = ext.cy; + } + + public XSSFChildGroupAnchor(CT_GroupTransform2D gt2d) + { + this.gt2d = gt2d; + } + + + public CT_GroupTransform2D GetCTTransform2D() + { + return gt2d; + } + + public override int Dx1 + { + get + { + return (int)gt2d.off.x; + + } + set + { + gt2d.off.y = (value); + } + } + + public override int Dy1 + { + get + { + return (int)gt2d.off.y; + } + set + { + gt2d.off.y = (value); + } + } + + public override int Dy2 + { + get + { + return (int)(Dy1 + gt2d.ext.cy); + } + set + { + gt2d.ext.cy = (value - Dy1); + } + } + + public override int Dx2 + { + get + { + return (int)(Dx1 + gt2d.ext.cx); + } + set + { + gt2d.ext.cx = (value - Dx1); + } + } + } +} diff --git a/ooxml/XSSF/UserModel/XSSFClientAnchor.cs b/ooxml/XSSF/UserModel/XSSFClientAnchor.cs index 6f6a21c8d..599c42369 100644 --- a/ooxml/XSSF/UserModel/XSSFClientAnchor.cs +++ b/ooxml/XSSF/UserModel/XSSFClientAnchor.cs @@ -41,6 +41,23 @@ public class XSSFClientAnchor : XSSFAnchor, IClientAnchor */ private CT_Marker cell2; + public int left + { + get; + } + public int top + { + get; + } + public int width + { + get; + } + public int height + { + get; + } + /** * Creates a new client anchor and defaults all the anchor positions to 0. */ @@ -97,9 +114,22 @@ internal XSSFClientAnchor(CT_Marker cell1, CT_Marker cell2) this.cell2 = cell2; } - - + /** + * Create XSSFClientAnchor from existing xml beans + * + * @param cell1 starting anchor point + * @param cell2 ending anchor point + */ + internal XSSFClientAnchor(CT_Marker cell1, CT_Marker cell2, int left, int top, int right, int bottom) + { + this.cell1 = cell1; + this.cell2 = cell2; + this.left = left; + this.top = top; + this.width = Math.Abs(right- left); + this.height = Math.Abs(bottom - top); + } public override bool Equals(Object o) { diff --git a/ooxml/XSSF/UserModel/XSSFConnector.cs b/ooxml/XSSF/UserModel/XSSFConnector.cs index 65077c1a5..7dc40b9dc 100644 --- a/ooxml/XSSF/UserModel/XSSFConnector.cs +++ b/ooxml/XSSF/UserModel/XSSFConnector.cs @@ -118,6 +118,17 @@ public ST_ShapeType ShapeType ctShape.spPr.prstGeom.prst = value; } } + + public override uint ID + { + get => ctShape.nvCxnSpPr.cNvPr.id; + } + + public override string Name + { + get => ctShape.nvCxnSpPr.cNvPr.name; + set => ctShape.nvCxnSpPr.cNvPr.name = value; + } protected internal override NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties GetShapeProperties() { return ctShape.spPr; diff --git a/ooxml/XSSF/UserModel/XSSFDrawing.cs b/ooxml/XSSF/UserModel/XSSFDrawing.cs index b0912c1dd..d634ff7cb 100644 --- a/ooxml/XSSF/UserModel/XSSFDrawing.cs +++ b/ooxml/XSSF/UserModel/XSSFDrawing.cs @@ -127,6 +127,10 @@ public XSSFTextBox CreateTextbox(IClientAnchor anchor) CT_Shape ctShape = ctAnchor.AddNewSp(); ctShape.Set(XSSFSimpleShape.Prototype()); ctShape.nvSpPr.cNvPr.id=(uint)shapeId; + ctShape.spPr.xfrm.off.x = ((XSSFClientAnchor)(anchor)).left; + ctShape.spPr.xfrm.off.y = ((XSSFClientAnchor)(anchor)).top; + ctShape.spPr.xfrm.ext.cx = ((XSSFClientAnchor)(anchor)).width; + ctShape.spPr.xfrm.ext.cy = ((XSSFClientAnchor)(anchor)).height; XSSFTextBox shape = new XSSFTextBox(this, ctShape); shape.anchor = (XSSFClientAnchor)anchor; return shape; @@ -152,6 +156,10 @@ public IPicture CreatePicture(XSSFClientAnchor anchor, int pictureIndex) ctShape.Set(XSSFPicture.Prototype()); ctShape.nvPicPr.cNvPr.id = (uint)shapeId; + ctShape.spPr.xfrm.off.x = anchor.left; + ctShape.spPr.xfrm.off.y = anchor.top; + ctShape.spPr.xfrm.ext.cx = anchor.width; + ctShape.spPr.xfrm.ext.cy = anchor.height; ctShape.nvPicPr.cNvPr.name = "Picture " + shapeId; XSSFPicture shape = new XSSFPicture(this, ctShape); @@ -267,8 +275,14 @@ public XSSFSimpleShape CreateSimpleShape(XSSFClientAnchor anchor) CT_Shape ctShape = ctAnchor.AddNewSp(); ctShape.Set(XSSFSimpleShape.Prototype()); ctShape.nvSpPr.cNvPr.id=(uint)(shapeId); + ctShape.spPr.xfrm.off.x = anchor.left; + ctShape.spPr.xfrm.off.y = anchor.top; + ctShape.spPr.xfrm.ext.cx = anchor.width; + ctShape.spPr.xfrm.ext.cy = anchor.height; XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape); shape.anchor = anchor; + shape.cellanchor = ctAnchor; + return shape; } @@ -282,12 +296,20 @@ public XSSFSimpleShape CreateSimpleShape(XSSFClientAnchor anchor) */ public XSSFConnector CreateConnector(XSSFClientAnchor anchor) { + long shapeId = newShapeId(); CT_TwoCellAnchor ctAnchor = CreateTwoCellAnchor(anchor); CT_Connector ctShape = ctAnchor.AddNewCxnSp(); ctShape.Set(XSSFConnector.Prototype()); + ctShape.nvCxnSpPr.cNvPr.id = (uint)(shapeId); + ctShape.spPr.xfrm.off.x = anchor.left; + ctShape.spPr.xfrm.off.y = anchor.top; + ctShape.spPr.xfrm.ext.cx = anchor.width; + ctShape.spPr.xfrm.ext.cy = anchor.height; XSSFConnector shape = new XSSFConnector(this, ctShape); shape.anchor = anchor; + shape.cellanchor = ctAnchor; + return shape; } @@ -301,12 +323,24 @@ public XSSFConnector CreateConnector(XSSFClientAnchor anchor) */ public XSSFShapeGroup CreateGroup(XSSFClientAnchor anchor) { + long shapeId = newShapeId(); CT_TwoCellAnchor ctAnchor = CreateTwoCellAnchor(anchor); CT_GroupShape ctGroup = ctAnchor.AddNewGrpSp(); ctGroup.Set(XSSFShapeGroup.Prototype()); + ctGroup.nvGrpSpPr.cNvPr.id = (uint)(shapeId); + ctGroup.grpSpPr.xfrm.off.x = anchor.left; + ctGroup.grpSpPr.xfrm.off.y = anchor.top; + ctGroup.grpSpPr.xfrm.ext.cx = anchor.width; + ctGroup.grpSpPr.xfrm.ext.cy = anchor.height; + ctGroup.grpSpPr.xfrm.chOff.x = ctGroup.grpSpPr.xfrm.off.x; + ctGroup.grpSpPr.xfrm.chOff.y = ctGroup.grpSpPr.xfrm.off.y; + ctGroup.grpSpPr.xfrm.chExt.cx =ctGroup.grpSpPr.xfrm.ext.cx; + ctGroup.grpSpPr.xfrm.chExt.cy =ctGroup.grpSpPr.xfrm.ext.cy; XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup); shape.anchor = anchor; + shape.cellanchor = ctAnchor; + return shape; } @@ -367,6 +401,8 @@ private XSSFGraphicFrame CreateGraphicFrame(XSSFClientAnchor anchor) graphicFrame.Anchor = anchor; graphicFrame.Id = frameId; graphicFrame.Name = "Diagramm" + frameId; + graphicFrame.cellanchor = ctAnchor; + return graphicFrame; } @@ -452,7 +488,39 @@ public List GetShapes() } else if (anchor.groupShape != null) { - shape = new XSSFShapeGroup(this, anchor.groupShape); + List lstCtShapes = new List(); + anchor.groupShape.GetShapes(lstCtShapes); + + foreach(var s in lstCtShapes) + { + XSSFShape gShape = null; + if(s is CT_Connector) + { + gShape = new XSSFConnector(this, (CT_Connector)s); + } + else if(s is CT_Picture) + { + gShape = new XSSFPicture(this, (CT_Picture)s); + } + else if(s is CT_Shape) + { + gShape = new XSSFSimpleShape(this, (CT_Shape)s); + } + else if(s is CT_GroupShape) + { + gShape = new XSSFShapeGroup(this, (CT_GroupShape)s); + } + else if(s is CT_GraphicalObjectFrame) + { + gShape = new XSSFGraphicFrame(this, (CT_GraphicalObjectFrame)s); + } + if(gShape != null) + { + gShape.anchor = GetAnchorFromIEGAnchor(anchor); + gShape.cellanchor = anchor; + lst.Add(gShape); + } + } } else if (anchor.graphicFrame != null) { @@ -465,6 +533,7 @@ public List GetShapes() if (shape != null) { shape.anchor = GetAnchorFromIEGAnchor(anchor); + shape.cellanchor = anchor; lst.Add(shape); } } @@ -493,6 +562,7 @@ public List GetShapes() //} return lst; } + private XSSFAnchor GetAnchorFromIEGAnchor(IEG_Anchor ctAnchor) { CT_Marker ctFrom=null, ctTo=null; diff --git a/ooxml/XSSF/UserModel/XSSFGraphicFrame.cs b/ooxml/XSSF/UserModel/XSSFGraphicFrame.cs index 872a1cd3f..94e36e54b 100644 --- a/ooxml/XSSF/UserModel/XSSFGraphicFrame.cs +++ b/ooxml/XSSF/UserModel/XSSFGraphicFrame.cs @@ -97,11 +97,23 @@ public void SetMacro(String macro) graphicFrame.macro = (macro); } + /** + * Returns the frame id. + * @return id of the frame + */ + public override uint ID + { + get + { + return GetNonVisualProperties().id; + } + } + /** * Returns the frame name. * @return name of the frame */ - public String Name + public override String Name { get { diff --git a/ooxml/XSSF/UserModel/XSSFPicture.cs b/ooxml/XSSF/UserModel/XSSFPicture.cs index 0902b6095..3c226eb40 100644 --- a/ooxml/XSSF/UserModel/XSSFPicture.cs +++ b/ooxml/XSSF/UserModel/XSSFPicture.cs @@ -118,6 +118,29 @@ internal static CT_Picture Prototype() return prototype; } + /** + * Returns the picture id. + * @return id of the picture + */ + public override uint ID { + get { + return ctPicture.nvPicPr.cNvPr.id; + } + } + + /** + * Returns the picture name. + * @return name of the picture + */ + public override String Name { + get { + return ctPicture.nvPicPr.cNvPr.name; + } + set { + ctPicture.nvPicPr.cNvPr.name = value; + } + } + /** * Link this shape with the picture data * diff --git a/ooxml/XSSF/UserModel/XSSFShape.cs b/ooxml/XSSF/UserModel/XSSFShape.cs index bd63414c0..4b6180947 100644 --- a/ooxml/XSSF/UserModel/XSSFShape.cs +++ b/ooxml/XSSF/UserModel/XSSFShape.cs @@ -39,6 +39,7 @@ public abstract class XSSFShape:IShape */ protected XSSFDrawing drawing; + protected IEG_Anchor IEGanchor; /** * The parent shape, always not-null for shapes in groups */ @@ -78,6 +79,27 @@ public XSSFAnchor GetAnchor() return anchor; } + public IEG_Anchor cellanchor + { + get + { + if(IEGanchor == null) { + return parent.cellanchor; + } + return IEGanchor; + } + set + { + if(parent == null) + { + IEGanchor = value; + } + else + { + parent.cellanchor = value; + } + } + } /** * Returns xml bean with shape properties. * @@ -85,6 +107,17 @@ public XSSFAnchor GetAnchor() */ protected internal abstract NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties GetShapeProperties(); + public abstract uint ID + { + get; + } + + public abstract string Name + { + get; + set; + } + /** * Whether this shape is not Filled with a color * @@ -148,7 +181,9 @@ public int FillColor } set { - throw new System.NotImplementedException(); + SetFillColor(value >> 16 & 0xff + , value >> 8 & 0xff + , value & 0xff); } } @@ -161,16 +196,29 @@ public virtual LineStyle LineStyle set { NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties props = GetShapeProperties(); - CT_LineProperties ln = props.IsSetLn() ? props.ln : props.AddNewLn(); - CT_PresetLineDashProperties dashStyle = new CT_PresetLineDashProperties(); - dashStyle.val = (ST_PresetLineDashVal)(value + 1); - ln.prstDash = dashStyle; + + if(value == LineStyle.None) { + props.ln = null; + } else { + + CT_LineProperties ln = props.IsSetLn() ? props.ln : props.AddNewLn(); + CT_PresetLineDashProperties dashStyle = new CT_PresetLineDashProperties(); + dashStyle.val = (ST_PresetLineDashVal)value; + ln.prstDash = dashStyle; + props.ln = ln; + } } } public virtual int LineStyleColor { get { throw new System.NotImplementedException(); } + set + { + SetLineStyleColor(value >> 16 & 0xff + , value >> 8 & 0xff + , value & 0xff); + } } public virtual double LineWidth @@ -199,6 +247,44 @@ public void SetLineStyleColor(int lineStyleColor) { throw new System.NotImplementedException(); } + + public virtual LineEndingCapType LineEndingCapType + { + get + { + NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties props = GetShapeProperties(); + return props.IsSetLn() ? (LineEndingCapType)props.ln.cap : LineEndingCapType.None; + } + set + { + if(value == LineEndingCapType.None) + { + throw new System.ArgumentException(); + } + NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties props = GetShapeProperties(); + CT_LineProperties ln = props.IsSetLn() ? props.ln : props.AddNewLn(); + ln.cap = (ST_LineCap) value; + } + } + + public virtual CompoundLineType CompoundLineType + { + get + { + NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties props = GetShapeProperties(); + return props.IsSetLn() ? (CompoundLineType)props.ln.cmpd : CompoundLineType.None; + } + set + { + if(value == CompoundLineType.None) + { + throw new System.ArgumentException(); + } + NPOI.OpenXmlFormats.Dml.Spreadsheet.CT_ShapeProperties props = GetShapeProperties(); + CT_LineProperties ln = props.IsSetLn() ? props.ln : props.AddNewLn(); + ln.cmpd = (ST_CompoundLine)value; + } + } } } diff --git a/ooxml/XSSF/UserModel/XSSFShapeGroup.cs b/ooxml/XSSF/UserModel/XSSFShapeGroup.cs index c6f510c36..0f0cee419 100644 --- a/ooxml/XSSF/UserModel/XSSFShapeGroup.cs +++ b/ooxml/XSSF/UserModel/XSSFShapeGroup.cs @@ -81,6 +81,34 @@ internal static CT_GroupShape Prototype() return prototype; } + /** + * Returns the shape group id. + * @return id of the shape group + */ + public override uint ID + { + get + { + return ctGroup.nvGrpSpPr.cNvPr.id; + } + } + + /** + * Returns the shape group name. + * @return name of the shape group + */ + public override String Name + { + get + { + return ctGroup.nvGrpSpPr.cNvPr.name; + } + set + { + ctGroup.nvGrpSpPr.cNvPr.name = value; + } + } + /** * Constructs a textbox. * @@ -92,6 +120,10 @@ public XSSFTextBox CreateTextbox(XSSFChildAnchor anchor) { CT_Shape ctShape = ctGroup.AddNewSp(); ctShape.Set(XSSFSimpleShape.Prototype()); + ctShape.spPr.xfrm.off.x = anchor.Dx1; + ctShape.spPr.xfrm.off.y = anchor.Dy1; + ctShape.spPr.xfrm.ext.cx = anchor.Dx2; + ctShape.spPr.xfrm.ext.cy = anchor.Dy2; XSSFTextBox shape = new XSSFTextBox(GetDrawing(), ctShape); shape.parent = this; @@ -112,6 +144,10 @@ public XSSFSimpleShape CreateSimpleShape(XSSFChildAnchor anchor) { CT_Shape ctShape = ctGroup.AddNewSp(); ctShape.Set(XSSFSimpleShape.Prototype()); + ctShape.spPr.xfrm.off.x = anchor.Dx1; + ctShape.spPr.xfrm.off.y = anchor.Dy1; + ctShape.spPr.xfrm.ext.cx = anchor.Dx2; + ctShape.spPr.xfrm.ext.cy = anchor.Dy2; XSSFSimpleShape shape = new XSSFSimpleShape(GetDrawing(), ctShape); shape.parent = (this); @@ -132,6 +168,10 @@ public XSSFConnector CreateConnector(XSSFChildAnchor anchor) { CT_Connector ctShape = ctGroup.AddNewCxnSp(); ctShape.Set(XSSFConnector.Prototype()); + ctShape.spPr.xfrm.off.x = anchor.Dx1; + ctShape.spPr.xfrm.off.y = anchor.Dy1; + ctShape.spPr.xfrm.ext.cx = anchor.Dx2; + ctShape.spPr.xfrm.ext.cy = anchor.Dy2; XSSFConnector shape = new XSSFConnector(GetDrawing(), ctShape); shape.parent = this; @@ -154,6 +194,10 @@ public XSSFPicture CreatePicture(XSSFClientAnchor anchor, int pictureIndex) CT_Picture ctShape = ctGroup.AddNewPic(); ctShape.Set(XSSFPicture.Prototype()); + ctShape.spPr.xfrm.off.x = anchor.Dx1; + ctShape.spPr.xfrm.off.y = anchor.Dy1; + ctShape.spPr.xfrm.ext.cx = anchor.Dx2; + ctShape.spPr.xfrm.ext.cy = anchor.Dy2; XSSFPicture shape = new XSSFPicture(GetDrawing(), ctShape); shape.parent = this; @@ -162,6 +206,20 @@ public XSSFPicture CreatePicture(XSSFClientAnchor anchor, int pictureIndex) return shape; } + public XSSFShapeGroup CreateGroup(XSSFChildGroupAnchor anchor) + { + CT_GroupShape ctShape = ctGroup.AddNewGroup(); + ctShape.Set(XSSFShapeGroup.Prototype()); + + XSSFShapeGroup group = new XSSFShapeGroup(GetDrawing(), ctShape) + { + parent = this, + anchor = anchor + }; + group.GetCTGroupShape().grpSpPr.xfrm = anchor.GetCTTransform2D(); + + return group; + } public CT_GroupShape GetCTGroupShape() { diff --git a/ooxml/XSSF/UserModel/XSSFSimpleShape.cs b/ooxml/XSSF/UserModel/XSSFSimpleShape.cs index 35450dc57..82a981f60 100644 --- a/ooxml/XSSF/UserModel/XSSFSimpleShape.cs +++ b/ooxml/XSSF/UserModel/XSSFSimpleShape.cs @@ -112,6 +112,11 @@ protected internal static CT_Shape Prototype() CT_SolidColorFillProperties scfpr = endPr.AddNewSolidFill(); scfpr.AddNewSrgbClr().val = (/*setter*/new byte[] { 0, 0, 0 }); + bodypr.lIns = 91440; //default value + bodypr.tIns = 45720; //default value + bodypr.rIns = 91440; //default value + bodypr.bIns = 45720; //default value + body.AddNewLstStyle(); prototype = shape; @@ -125,6 +130,31 @@ public CT_Shape GetCTShape() return ctShape; } + /** + * Returns the simple shape id. + * @return id of the simple shape + */ + public override uint ID { + get + { + return ctShape.nvSpPr.cNvPr.id; + } + } + + /** + * Returns the simple shape name. + * @return name of the simple shape + */ + public override String Name { + get + { + return ctShape.nvSpPr.cNvPr.name; + } + set + { + ctShape.nvSpPr.cNvPr.name = value; + } + } public IEnumerator GetEnumerator() { @@ -441,7 +471,21 @@ public void SetText(XSSFRichTextString str) CT_RegularTextRun r = p.AddNewR(); CT_TextCharacterProperties rPr = r.AddNewRPr(); rPr.lang = (/*setter*/"en-US"); - + if(ltPr.vertAlign != null) + { + switch(ltPr.vertAlign.val) + { + case ST_VerticalAlignRun.subscript: + rPr.baseline = -25000; + break; + case ST_VerticalAlignRun.superscript: + rPr.baseline = 30000; + break; + default: + rPr.baseline = 0; + break; + } + } ApplyAttributes(ltPr, rPr); r.t = (/*setter*/lt.t); @@ -708,7 +752,7 @@ public double BottomInset CT_TextBodyProperties bodyPr = ctShape.txBody.bodyPr; if (bodyPr != null) { - if (value == -1) + if (value == -1 || value == 3.6) { if (bodyPr.IsSetBIns()) bodyPr.UnsetBIns(); } @@ -736,15 +780,16 @@ public double LeftInset return Units.ToPoints(bodyPr.lIns); } } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; + // If this attribute is omitted, then a value of 0.1 inches is implied + return 7.2; + ; } set { CT_TextBodyProperties bodyPr = ctShape.txBody.bodyPr; if (bodyPr != null) { - if (value == -1) + if (value == -1 || value == 7.2) { if (bodyPr.IsSetLIns()) bodyPr.UnsetLIns(); } @@ -772,15 +817,15 @@ public double RightInset return Units.ToPoints(bodyPr.rIns); } } - // If this attribute is omitted, then a value of 0.05 inches is implied - return 3.6; + // If this attribute is omitted, then a value of 0.1 inches is implied + return 7.2; } set { CT_TextBodyProperties bodyPr = ctShape.txBody.bodyPr; if (bodyPr != null) { - if (value == -1) + if (value == -1 || value == 7.2) { if (bodyPr.IsSetRIns()) bodyPr.UnsetRIns(); } @@ -815,7 +860,7 @@ public double TopInset CT_TextBodyProperties bodyPr = ctShape.txBody.bodyPr; if (bodyPr != null) { - if (value == -1) + if (value == -1 || value == 3.6) { if (bodyPr.IsSetTIns()) bodyPr.UnsetTIns(); } diff --git a/openxml4Net/Util/XmlHelper.cs b/openxml4Net/Util/XmlHelper.cs index c18f12cc8..a2ca3ac4d 100644 --- a/openxml4Net/Util/XmlHelper.cs +++ b/openxml4Net/Util/XmlHelper.cs @@ -63,10 +63,16 @@ public static T GetEnumValueFromString(string value) throw new ArgumentException("No XmlEnumAttribute code exists for type " + typeof(T).ToString() + " corresponding to value of " + value); } - public static int ReadInt(XmlAttribute attr) + public static int ReadInt(XmlAttribute attr, int? defaultValue = null) { - if (attr == null) + if(attr == null) + { + if(defaultValue != null) + { + return (int)defaultValue; + } return 0; + } int i; if (int.TryParse(attr.Value, out i)) { @@ -335,6 +341,13 @@ public static void WriteAttribute(StreamWriter sw, string attributeName, int val WriteAttribute(sw, attributeName, value.ToString(CultureInfo.InvariantCulture)); } + public static void WriteAttribute(StreamWriter sw, string attributeName, int value, int defaultValue) + { + if(value == defaultValue) + return; + + WriteAttribute(sw, attributeName, value.ToString(CultureInfo.InvariantCulture)); + } public static void WriteAttribute(StreamWriter sw, string attributeName, int value) { WriteAttribute(sw, attributeName, value, false); diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFShape.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFShape.cs new file mode 100644 index 000000000..e71ab7cfa --- /dev/null +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFShape.cs @@ -0,0 +1,365 @@ +using NPOI.OpenXmlFormats.Dml.Spreadsheet; +using NPOI.SS.UserModel; +using NPOI.Util; +using NPOI.XSSF; +using NPOI.XSSF.UserModel; +using NUnit.Framework; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace TestCases.XSSF.UserModel +{ + [TestFixture] + internal class TestXSSFShapes + { + [Test] + public void TestShapeLineEndingCapType() + { + + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,0,0, 1,1,2,2); + + XSSFConnector cxn = drawing.CreateConnector(anchor); + cxn.Name = "sp1"; + cxn.LineEndingCapType = NPOI.SS.UserModel.LineEndingCapType.Round; + + XSSFWorkbook rbwb = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + + XSSFSheet rb_sht = (XSSFSheet)rbwb.GetSheetAt(0); + XSSFDrawing dr = (XSSFDrawing)rb_sht.GetDrawingPatriarch(); + List lstShp = dr.GetShapes(); + foreach(var sp in lstShp) + { + if(sp.Name == "sp1") + { + Assert.AreEqual(NPOI.SS.UserModel.LineEndingCapType.Round, sp.LineEndingCapType); + return; + } + } + Assert.True(false); + } + [Test] + public void TestShapeCompoundLineType() + { + + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,0,0, 1,1,2,2); + + XSSFConnector cxn = drawing.CreateConnector(anchor); + cxn.Name = "sp2"; + cxn.CompoundLineType = NPOI.SS.UserModel.CompoundLineType.DoubleLines; + + XSSFWorkbook rbwb = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + + XSSFSheet rb_sht = (XSSFSheet)rbwb.GetSheetAt(0); + XSSFDrawing dr = (XSSFDrawing)rb_sht.GetDrawingPatriarch(); + List lstShp = dr.GetShapes(); + foreach(var sp in lstShp) + { + if(sp.Name == "sp2") + { + Assert.AreEqual(NPOI.SS.UserModel.CompoundLineType.DoubleLines, sp.CompoundLineType); + return; + } + } + Assert.True(false); + } + + [Test] + public void TestGetShapes() + { + XSSFWorkbook wb = XSSFTestDataSamples.OpenSampleWorkbook("TestGetShapes.xlsx"); + XSSFSheet sheet = (XSSFSheet)wb.GetSheet("Sheet0"); + + XSSFDrawing drawing = sheet.GetDrawingPatriarch(); + + List lstShp = drawing.GetShapes(); + foreach(var sp in lstShp) + { + Debug.WriteLine($"name:[{sp.Name}]"); + switch(sp.Name) + { + case "first": + case "second": + case "third": + case "L01": + case "L02": + case "L03": + break; + default: + Assert.Fail($"name is invalid [{sp.Name}]"); + break; + } + } + } + + [Test] + public void TestShapeTextWrap() + { + XSSFWorkbook wb = XSSFTestDataSamples.OpenSampleWorkbook("TestShapeTextWrap.xlsx"); + XSSFSheet sheet = (XSSFSheet)wb.GetSheet("Sheet1"); + XSSFDrawing drawing = sheet.GetDrawingPatriarch(); + + List lstShp = drawing.GetShapes(); + foreach(var sp in lstShp) + { + if(sp.Name == "shape1") + { + Assert.AreEqual(true, ((XSSFSimpleShape)sp).WordWrap); + XSSFTestDataSamples.WriteOut(wb, "TestShapeTextWrap-1-"); + ((XSSFSimpleShape)sp).WordWrap = false; + XSSFWorkbook rbwb = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + Assert.AreEqual(false, ((XSSFSimpleShape)sp).WordWrap); + XSSFTestDataSamples.WriteOut(wb, "TestShapeTextWrap-2-"); + } + } + } + + [Test] + public void TestShapeInset() + { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sht0 = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sht0.CreateDrawingPatriarch(); + + //----- create + var ca0 = sht0.CreateClientAnchor(Units.ToEMU(100), Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200)); + var sp0 = drawing.CreateSimpleShape(ca0); + sp0.LineStyle = LineStyle.Solid; + sp0.LineStyleColor = 0xff00000; + Assert.AreEqual(7.2, sp0.LeftInset); + Assert.AreEqual(false, sp0.GetCTShape().txBody.bodyPr.IsSetLIns()); + Assert.AreEqual(3.6, sp0.TopInset); + Assert.AreEqual(false, sp0.GetCTShape().txBody.bodyPr.IsSetTIns()); + Assert.AreEqual(7.2, sp0.RightInset); + Assert.AreEqual(false, sp0.GetCTShape().txBody.bodyPr.IsSetRIns()); + Assert.AreEqual(3.6, sp0.BottomInset); + Assert.AreEqual(false, sp0.GetCTShape().txBody.bodyPr.IsSetBIns()); + XSSFTestDataSamples.WriteOut(wb, "TestShapeTextWrap-1-"); + + //----- zero + sp0.LeftInset = 0; + sp0.TopInset = 0; + sp0.RightInset = 0; + sp0.BottomInset = 0; + XSSFWorkbook rbwb1 = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + var sht1 = rbwb1.GetSheet("sheet0"); + var dw1 = ((XSSFSheet)sht1).GetDrawingPatriarch(); + XSSFSimpleShape sp1 = (XSSFSimpleShape)dw1.GetShapes()[0]; + Assert.AreEqual(0, sp1.LeftInset); + Assert.AreEqual(true, sp1.GetCTShape().txBody.bodyPr.IsSetLIns()); + Assert.AreEqual(0, sp1.TopInset); + Assert.AreEqual(true, sp1.GetCTShape().txBody.bodyPr.IsSetTIns()); + Assert.AreEqual(0, sp1.RightInset); + Assert.AreEqual(true, sp1.GetCTShape().txBody.bodyPr.IsSetRIns()); + Assert.AreEqual(0, sp1.BottomInset); + Assert.AreEqual(true, sp1.GetCTShape().txBody.bodyPr.IsSetBIns()); + XSSFTestDataSamples.WriteOut(rbwb1, "TestShapeTextWrap-2-"); + + //----- others + sp1.LeftInset = 3.6; + sp1.TopInset = 1.8; + sp1.RightInset = 3.6; + sp1.BottomInset = 1.8; + XSSFWorkbook rbwb2 = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(rbwb1); + var sht2 = rbwb2.GetSheet("sheet0"); + var dw2 = ((XSSFSheet)sht2).GetDrawingPatriarch(); + XSSFSimpleShape sp2 = (XSSFSimpleShape)dw2.GetShapes()[0]; + Assert.AreEqual(3.6, sp2.LeftInset); + Assert.AreEqual(true, sp2.GetCTShape().txBody.bodyPr.IsSetLIns()); + Assert.AreEqual(1.8, sp2.TopInset); + Assert.AreEqual(true, sp2.GetCTShape().txBody.bodyPr.IsSetTIns()); + Assert.AreEqual(3.6, sp2.RightInset); + Assert.AreEqual(true, sp2.GetCTShape().txBody.bodyPr.IsSetRIns()); + Assert.AreEqual(1.8, sp2.BottomInset); + Assert.AreEqual(true, sp2.GetCTShape().txBody.bodyPr.IsSetBIns()); + XSSFTestDataSamples.WriteOut(rbwb2, "TestShapeTextWrap-3-"); + } + + [Test] + public void TestLockWithSheet() + { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + // simple shape + XSSFClientAnchor ca0; + ca0 = sheet.CreateClientAnchor(Units.ToEMU(100), Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200)); + XSSFSimpleShape shp0 = drawing.CreateSimpleShape(ca0); + shp0.Name = "S00"; + shp0.cellanchor.clientData.fLocksWithSheet = true; + + // connector shape + XSSFClientAnchor ca1; + ca1 = sheet.CreateClientAnchor(Units.ToEMU(250), Units.ToEMU(250), Units.ToEMU(350), Units.ToEMU(350)); + XSSFConnector shp1 = drawing.CreateConnector(ca1); + shp1.Name = "L00"; + shp1.cellanchor.clientData.fLocksWithSheet = true; + + XSSFTestDataSamples.WriteOut(wb, "TestLockWithSheet1-"); + + XSSFWorkbook rbwb = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + + XSSFSheet rb_sht = (XSSFSheet)rbwb.GetSheetAt(0); + XSSFDrawing dr = (XSSFDrawing)rb_sht.GetDrawingPatriarch(); + List lstShp = dr.GetShapes(); + foreach(var sp in lstShp) + { + switch(sp.Name) + { + case "S00": + case "L00": + Assert.AreEqual(sp.cellanchor.clientData.fLocksWithSheet, true, "shape name:[{0}]", new object[] { sp.Name }); + break; + default: + break; + } + } + + shp0.cellanchor.clientData.fLocksWithSheet = false; + shp1.cellanchor.clientData.fLocksWithSheet = false; + + XSSFTestDataSamples.WriteOut(wb, "TestLockWithSheet2-"); + + XSSFWorkbook rbwb1 = (XSSFWorkbook)XSSFITestDataProvider.instance.WriteOutAndReadBack(wb); + XSSFSheet rb_sht1 = (XSSFSheet)rbwb1.GetSheetAt(0); + XSSFDrawing dr1 = (XSSFDrawing)rb_sht1.GetDrawingPatriarch(); + List lstShp1 = dr1.GetShapes(); + + foreach(var sp in lstShp1) + { + switch(sp.Name) + { + case "S00": + case "L00": + Assert.AreEqual(sp.cellanchor.clientData.fLocksWithSheet, false, "shape name:[{0}]", new object[] { sp.Name }); + break; + default: + break; + } + } + } + + [Test] + public void TestGroupLockWithSheet() + { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + //----- first group + XSSFClientAnchor ganchor1; + ganchor1 = sheet.CreateClientAnchor(Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200), Units.ToEMU(100)); + ganchor1.AnchorType = AnchorType.DontMoveAndResize; + XSSFShapeGroup grp1= drawing.CreateGroup( ganchor1 ); + grp1.Name = "first"; + + // connector shape + XSSFChildAnchor ca1; + ca1 = new XSSFChildAnchor(Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200), Units.ToEMU(100)); + XSSFConnector shp1 = grp1.CreateConnector( ca1 ); + shp1.Name = "L01"; + shp1.cellanchor.clientData.fLocksWithSheet = true; + + //----- second group + XSSFChildGroupAnchor ganchor2; + ganchor2 = new XSSFChildGroupAnchor(Units.ToEMU(110), Units.ToEMU(110), Units.ToEMU(190), Units.ToEMU(190)); + XSSFShapeGroup grp2 = grp1.CreateGroup( ganchor2 ); + grp2.Name = "second"; + + // connector shape + XSSFChildAnchor ca2; + ca2 = new XSSFChildAnchor(Units.ToEMU(110), Units.ToEMU(110), Units.ToEMU(190), Units.ToEMU(190)); + XSSFConnector shp2 = grp2.CreateConnector(ca2); + shp2.Name = "L02"; + shp2.cellanchor.clientData.fLocksWithSheet = true; + + //----- third group + XSSFChildGroupAnchor ganchor3; + ganchor3 = new XSSFChildGroupAnchor(Units.ToEMU(120), Units.ToEMU(120), Units.ToEMU(180), Units.ToEMU(180)); + XSSFShapeGroup grp3 = grp2.CreateGroup( ganchor3 ); + grp3.Name = "third"; + + // connector shape + XSSFChildAnchor ca3; + ca3 = new XSSFChildAnchor(Units.ToEMU(120), Units.ToEMU(150), Units.ToEMU(180), Units.ToEMU(150)); + XSSFConnector shp3 = grp3.CreateConnector(ca3); + shp3.Name = "L03"; + shp3.cellanchor.clientData.fLocksWithSheet = false; + + Assert.AreEqual(shp1.cellanchor.clientData.fLocksWithSheet, false); + + XSSFTestDataSamples.WriteOut(wb, "TestGroupLockWithSheet"); + } + + [Test] + public void TestRecursiveGroup() + { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + //----- first group + XSSFClientAnchor ganchor1; + ganchor1 = sheet.CreateClientAnchor(Units.ToEMU(100), Units.ToEMU(400), Units.ToEMU(400), Units.ToEMU(100)); + ganchor1.AnchorType = AnchorType.DontMoveAndResize; + XSSFShapeGroup grp1= drawing.CreateGroup( ganchor1 ); + grp1.Name = "G00"; + + // simple shape + XSSFChildAnchor ca1; + ca1 = new XSSFChildAnchor(Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200), Units.ToEMU(100)); + XSSFSimpleShape shp1 = grp1.CreateSimpleShape( ca1 ); + shp1.Name = "S00"; + + // connector shape + XSSFChildAnchor ca2; + ca2 = new XSSFChildAnchor(Units.ToEMU(100), Units.ToEMU(200), Units.ToEMU(200), Units.ToEMU(100)); + XSSFConnector shp2 = grp1.CreateConnector( ca2 ); + shp2.Name = "L00"; + shp2.cellanchor.clientData.fLocksWithSheet = true; + + int x = 300; + int y = 300; + int cx = 310; + int cy = 310; + XSSFShapeGroup grp = grp1; + for(var ct = 1; ct < 5; ct++) + { + //----- second group + XSSFChildGroupAnchor ganchor; + ganchor = new XSSFChildGroupAnchor(Units.ToEMU(x), Units.ToEMU(y), Units.ToEMU(cx), Units.ToEMU(cy)); + grp = grp.CreateGroup( ganchor ); + grp.Name = $"G{ct}"; + + // simple shape + XSSFChildAnchor ca; + ca = new XSSFChildAnchor(Units.ToEMU(x), Units.ToEMU(x), Units.ToEMU(cx), Units.ToEMU(cy)); + XSSFSimpleShape Sshp = grp.CreateSimpleShape( ca ); + Sshp.Name = $"S{ct:00}"; + Sshp.LineStyle = LineStyle.Solid; + Sshp.LineStyleColor = 0x00FF00; + + // connector shape + ca = new XSSFChildAnchor(Units.ToEMU(x), Units.ToEMU(y), Units.ToEMU(cx), Units.ToEMU(cy)); + XSSFConnector Cshp = grp.CreateConnector( ca ); + Cshp.Name = $"L{ct:00}"; + Cshp.cellanchor.clientData.fLocksWithSheet = true; + + x += 25; + y += 25; + cx += 25; + cy += 25; + } + XSSFTestDataSamples.WriteOut(wb, "TestRecursiveGroup"); + } + } +} diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFShapeName.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFShapeName.cs new file mode 100644 index 000000000..a2a19574b --- /dev/null +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFShapeName.cs @@ -0,0 +1,50 @@ +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using NUnit.Framework; +using System.Text; + +namespace TestCases.XSSF.UserModel +{ + [TestFixture] + internal class TestXSSFShapeName + { + [Test] + public void TestNameAndID() + { + int id = 0; + + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)wb.CreateSheet(); + XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + + XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,0,0, 1,1,2,2); + + XSSFConnector cxn = drawing.CreateConnector(anchor); + cxn.Name = "cxn1"; + Assert.AreEqual("cxn1", cxn.Name); + Assert.AreEqual(++id, cxn.ID); + + //XSSFGraphicFrame gf = drawing.CreateGraphicFrame(anchor); + //gf.Name = "graphic frame 1"; + //Assert.AreEqual("graphic frame 1", gf.Name); + //Assert.AreEqual(++id, gf.ID); + + XSSFShapeGroup sg = drawing.CreateGroup(anchor); + sg.Name = "shape group 1"; + Assert.AreEqual("shape group 1", sg.Name); + Assert.AreEqual(++id, sg.ID); + + byte[] jpegData = Encoding.UTF8.GetBytes("test jpeg data"); + int jpegIdx = wb.AddPicture(jpegData, PictureType.JPEG); + XSSFPicture shape = (XSSFPicture)drawing.CreatePicture(anchor, jpegIdx); + shape.Name = "name test pic 1"; + Assert.AreEqual("name test pic 1", shape.Name, "ID={0}", shape.ID); + Assert.AreEqual(++id, shape.ID); + + XSSFSimpleShape ss = drawing.CreateSimpleShape(anchor); + ss.Name = "simple shape 1"; + Assert.AreEqual("simple shape 1", ss.Name); + Assert.AreEqual(++id, ss.ID); + } + } +} diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs index dc86bbc74..f5303a948 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs @@ -21,6 +21,7 @@ limitations under the License. using NPOI.SS; using NPOI.SS.UserModel; using NPOI.SS.Util; +using NPOI.Util; using NPOI.XSSF; using NPOI.XSSF.Model; using NPOI.XSSF.Streaming; @@ -31,6 +32,7 @@ limitations under the License. using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Xml.Linq; using TestCases.HSSF; using TestCases.SS.UserModel; @@ -2072,6 +2074,45 @@ private void AddComments(ICreationHelper helper, ISheet sheet) cell.CellComment = comment; } } - + [Test] + public void TestCoordinate() + { + XSSFWorkbook wb = XSSFTestDataSamples.OpenSampleWorkbook("coordinate.xlsm"); + XSSFSheet sheet = (XSSFSheet)wb.GetSheet("Sheet1"); + + XSSFDrawing drawing = sheet.GetDrawingPatriarch(); + + List shapes = drawing.GetShapes(); + XSSFClientAnchor anchor; + + foreach(var shape in shapes) { + XSSFClientAnchor sa = (XSSFClientAnchor)shape.anchor; + switch(shape.Name) { + case "cxn1": + anchor = sheet.CreateClientAnchor(Units.ToEMU(50), Units.ToEMU(75), Units.ToEMU(125), Units.ToEMU(150)); + break; + case "cxn2": + anchor = sheet.CreateClientAnchor(Units.ToEMU(75), Units.ToEMU(75), Units.ToEMU(150), Units.ToEMU(150)); + break; + case "cxn3": + anchor = sheet.CreateClientAnchor(Units.ToEMU(150), Units.ToEMU(75), Units.ToEMU(225), Units.ToEMU(150)); + break; + case "cxn4": + anchor = sheet.CreateClientAnchor(Units.ToEMU(225), Units.ToEMU(75), Units.ToEMU(300), Units.ToEMU(150)); + break; + default: + Assert.True(false, "Unexpected shape {0}", new object[] { shape.Name }); + return; + } + Assert.IsTrue(sa.From.col == anchor.From.col, /**/"From.col [{0}]({1}={2})", new object[] { shape.Name, sa.From.col, anchor.From.col }); + Assert.IsTrue(sa.From.colOff== anchor.From.colOff, /**/"From.colOff[{0}]({1}={2})", new object[] { shape.Name, sa.From.colOff, anchor.From.colOff }); + Assert.IsTrue(sa.From.row == anchor.From.row, /**/"From.row [{0}]({1}={2})", new object[] { shape.Name, sa.From.row, anchor.From.row }); + Assert.IsTrue(sa.From.rowOff == anchor.From.rowOff, /**/"From.rowOff[{0}]({1}={2})", new object[] { shape.Name, sa.From.rowOff, anchor.From.rowOff }); + Assert.IsTrue(sa.To.col == anchor.To.col, /**/"To.col [{0}]({1}={2})", new object[] { shape.Name, sa.To.col, anchor.To.col }); + Assert.IsTrue(sa.To.colOff == anchor.To.colOff, /**/"To.colOff [{0}]({1}={2})", new object[] { shape.Name, sa.To.colOff, anchor.To.colOff }); + Assert.IsTrue(sa.To.row == anchor.To.row, /**/"To.row [{0}]({1}={2})", new object[] { shape.Name, sa.To.row, anchor.To.row }); + Assert.IsTrue(sa.To.rowOff == anchor.To.rowOff, /**/"To.rowOff [{0}]({1}={2})", new object[] { shape.Name, sa.To.rowOff, anchor.To.rowOff }); + } + } } } \ No newline at end of file diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFSimpleShape.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFSimpleShape.cs index 47dcbfaf1..63718388c 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFSimpleShape.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFSimpleShape.cs @@ -121,21 +121,21 @@ public void TestXSSFTextParagraph() shape.BottomInset = (/*setter*/-1); Assert.AreEqual(3.6, shape.BottomInset, 0.01); - Assert.AreEqual(3.6, shape.LeftInset, 0.01); + Assert.AreEqual(7.2, shape.LeftInset, 0.01); shape.LeftInset = (/*setter*/12.31); Assert.AreEqual(12.31, shape.LeftInset, 0.01); shape.LeftInset = (/*setter*/-1); - Assert.AreEqual(3.6, shape.LeftInset, 0.01); + Assert.AreEqual(7.2, shape.LeftInset, 0.01); shape.LeftInset = (/*setter*/-1); - Assert.AreEqual(3.6, shape.LeftInset, 0.01); + Assert.AreEqual(7.2, shape.LeftInset, 0.01); - Assert.AreEqual(3.6, shape.RightInset, 0.01); + Assert.AreEqual(7.2, shape.RightInset, 0.01); shape.RightInset = (/*setter*/13.31); Assert.AreEqual(13.31, shape.RightInset, 0.01); shape.RightInset = (/*setter*/-1); - Assert.AreEqual(3.6, shape.RightInset, 0.01); + Assert.AreEqual(7.2, shape.RightInset, 0.01); shape.RightInset = (/*setter*/-1); - Assert.AreEqual(3.6, shape.RightInset, 0.01); + Assert.AreEqual(7.2, shape.RightInset, 0.01); Assert.AreEqual(3.6, shape.TopInset, 0.01); shape.TopInset = (/*setter*/23.31); diff --git a/testcases/test-data/spreadsheet/TestGetShapes.xlsx b/testcases/test-data/spreadsheet/TestGetShapes.xlsx new file mode 100644 index 000000000..b0bb66dae Binary files /dev/null and b/testcases/test-data/spreadsheet/TestGetShapes.xlsx differ diff --git a/testcases/test-data/spreadsheet/TestShapeTextWrap.xlsx b/testcases/test-data/spreadsheet/TestShapeTextWrap.xlsx new file mode 100644 index 000000000..15deeec6c Binary files /dev/null and b/testcases/test-data/spreadsheet/TestShapeTextWrap.xlsx differ diff --git a/testcases/test-data/spreadsheet/coordinate.xlsm b/testcases/test-data/spreadsheet/coordinate.xlsm new file mode 100644 index 000000000..1b30decfa Binary files /dev/null and b/testcases/test-data/spreadsheet/coordinate.xlsm differ