diff --git a/main/SS/Util/CellReference.cs b/main/SS/Util/CellReference.cs index 02258afbe..b557c06bc 100644 --- a/main/SS/Util/CellReference.cs +++ b/main/SS/Util/CellReference.cs @@ -544,15 +544,12 @@ public static bool CellReferenceIsWithinRange(ReadOnlySpan colStr, ReadOnl return IsRowWithinRange(rowStr, ssVersion); } - /** - * @deprecated 3.15 beta 2. Use {@link #isColumnWithinRange}. - */ - [Obsolete("deprecated 3.15 beta 2. Use {@link #isColumnWithinRange}.")] - public static bool IsColumnWithnRange(String colStr, SpreadsheetVersion ssVersion) - { - return IsColumnWithinRange(colStr, ssVersion); - } - + /// + /// Determines whether rowStr is a valid row number for a given SpreadsheetVersion. + /// + /// the numeric portion of an A1-style cell reference (1-based index) + /// the spreadsheet version + /// public static bool IsRowWithinRange(String rowStr, SpreadsheetVersion ssVersion) => IsRowWithinRange(rowStr.AsSpan(), ssVersion); @@ -560,13 +557,18 @@ public static bool IsRowWithinRange(ReadOnlySpan rowStr, SpreadsheetVersio { CellReferenceParser.TryParsePositiveInt32Fast(rowStr, out var rowNum); rowNum -= 1; - return 0 <= rowNum && rowNum <= ssVersion.LastRowIndex; + return IsRowWithinRange(rowNum, ssVersion); } - [Obsolete("deprecated 3.15 beta 2. Use {@link #isRowWithinRange}")] - public static bool isRowWithnRange(String rowStr, SpreadsheetVersion ssVersion) + /// + /// Determines whether row is a valid row number for a given SpreadsheetVersion. + /// + /// the row number (0-based index) + /// the spreadsheet version + /// + public static bool IsRowWithinRange(int rowNum, SpreadsheetVersion ssVersion) { - return IsRowWithinRange(rowStr, ssVersion); + return 0 <= rowNum && rowNum <= ssVersion.LastRowIndex; } public static bool IsColumnWithinRange(String colStr, SpreadsheetVersion ssVersion) diff --git a/ooxml/XSSF/Streaming/SXSSFSheet.cs b/ooxml/XSSF/Streaming/SXSSFSheet.cs index 0cf3b56c1..44a8b786d 100644 --- a/ooxml/XSSF/Streaming/SXSSFSheet.cs +++ b/ooxml/XSSF/Streaming/SXSSFSheet.cs @@ -27,6 +27,7 @@ limitations under the License. using NPOI.SS.Util; using NPOI.Util; using NPOI.XSSF.UserModel; +using NPOI.OpenXmlFormats.Spreadsheet; namespace NPOI.XSSF.Streaming { @@ -1477,6 +1478,203 @@ public void AutoSizeRow(int row, bool useMergedCells) throw new NotImplementedException(); } + /// + /// Enable sheet protection + /// + public void EnableLocking() + { + SafeGetProtectionField().sheet = true; + } + + /// + /// Disable sheet protection + /// + public void DisableLocking() + { + SafeGetProtectionField().sheet = false; + } + + /// + /// Enable or disable Autofilters locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockAutoFilter(bool enabled) + { + SafeGetProtectionField().autoFilter = enabled; + } + + /// + /// Enable or disable Deleting columns locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockDeleteColumns(bool enabled) + { + SafeGetProtectionField().deleteColumns = enabled; + } + + /// + /// Enable or disable Deleting rows locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockDeleteRows(bool enabled) + { + SafeGetProtectionField().deleteRows = enabled; + } + + /// + /// Enable or disable Formatting cells locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockFormatCells(bool enabled) + { + SafeGetProtectionField().formatCells = enabled; + } + + /// + /// Enable or disable Formatting columns locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockFormatColumns(bool enabled) + { + SafeGetProtectionField().formatColumns = enabled; + } + + /// + /// Enable or disable Formatting rows locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockFormatRows(bool enabled) + { + SafeGetProtectionField().formatRows = enabled; + } + + /// + /// Enable or disable Inserting columns locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockInsertColumns(bool enabled) + { + SafeGetProtectionField().insertColumns = enabled; + } + + /// + /// Enable or disable Inserting hyperlinks locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockInsertHyperlinks(bool enabled) + { + SafeGetProtectionField().insertHyperlinks = enabled; + } + + /// + /// Enable or disable Inserting rows locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockInsertRows(bool enabled) + { + SafeGetProtectionField().insertRows = enabled; + } + + /// + /// Enable or disable Pivot Tables locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockPivotTables(bool enabled) + { + SafeGetProtectionField().pivotTables = enabled; + } + + /// + /// Enable or disable Sort locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockSort(bool enabled) + { + SafeGetProtectionField().sort = enabled; + } + + /// + /// Enable or disable Objects locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockObjects(bool enabled) + { + SafeGetProtectionField().objects = enabled; + } + + /// + /// Enable or disable Scenarios locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockScenarios(bool enabled) + { + SafeGetProtectionField().scenarios = enabled; + } + + /// + /// Enable or disable Selection of locked cells locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockSelectLockedCells(bool enabled) + { + SafeGetProtectionField().selectLockedCells = enabled; + } + + /// + /// Enable or disable Selection of unlocked cells locking. + /// This does not modify sheet protection status. + /// To enforce this un-/locking, call or + /// + public void LockSelectUnlockedCells(bool enabled) + { + SafeGetProtectionField().selectUnlockedCells = enabled; + } + + private CT_SheetProtection SafeGetProtectionField() + { + CT_Worksheet ct = _sh.GetCTWorksheet(); + if (!IsSheetProtectionEnabled()) + { + return ct.AddNewSheetProtection(); + } + return ct.sheetProtection; + } + + /* package */ + internal bool IsSheetProtectionEnabled() + { + CT_Worksheet ct = _sh.GetCTWorksheet(); + return (ct.IsSetSheetProtection()); + } + + /// + /// Set background color of the sheet tab + /// + /// the indexed color to Set, must be a constant from + public void SetTabColor(int colorIndex) + { + CT_Worksheet ct = _sh.GetCTWorksheet(); + CT_SheetPr pr = ct.sheetPr; + if (pr == null) pr = ct.AddNewSheetPr(); + CT_Color color = new CT_Color(); + color.indexed = (uint)colorIndex; + pr.tabColor = color; + } + IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable) _sh).GetEnumerator(); diff --git a/ooxml/XSSF/UserModel/XSSFName.cs b/ooxml/XSSF/UserModel/XSSFName.cs index 23c006b44..797cc0ff2 100644 --- a/ooxml/XSSF/UserModel/XSSFName.cs +++ b/ooxml/XSSF/UserModel/XSSFName.cs @@ -422,9 +422,16 @@ thus we are stuck with Character.isLetter (for now). { string col = Regex.Replace(name, "\\d", ""); string row = Regex.Replace(name, "[A-Za-z]", ""); - if (CellReference.CellReferenceIsWithinRange(col, row, SpreadsheetVersion.EXCEL97)) + try { - throw new ArgumentException("Invalid name: '" + name + "': cannot be $A$1-style cell reference"); + if (CellReference.CellReferenceIsWithinRange(col, row, SpreadsheetVersion.EXCEL2007)) + { + throw new ArgumentException("Invalid name: '" + name + "': cannot be $A$1-style cell reference"); + } + } + catch (FormatException) { + // row was not parseable as an Integer, such as a BigInt + // therefore name passes the not-a-cell-reference criteria } } diff --git a/testcases/main/HSSF/UserModel/TestEscherGraphics.cs b/testcases/main/HSSF/UserModel/TestEscherGraphics.cs index 9b7132df5..89ecb455d 100644 --- a/testcases/main/HSSF/UserModel/TestEscherGraphics.cs +++ b/testcases/main/HSSF/UserModel/TestEscherGraphics.cs @@ -25,6 +25,7 @@ namespace TestCases.HSSF.UserModel using NUnit.Framework;using NUnit.Framework.Legacy; + using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; @@ -54,7 +55,7 @@ public void SetUp() System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US"); workbook = new HSSFWorkbook(); - NPOI.SS.UserModel.ISheet sheet = workbook.CreateSheet("Test"); + ISheet sheet = workbook.CreateSheet("Test"); patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch(); escherGroupA = patriarch.CreateGroup(new HSSFClientAnchor(0, 0, 1022, 255, (short)0, 0, (short)0, 0)); escherGroupB = patriarch.CreateGroup(new HSSFClientAnchor(20, 30, 500, 200, (short)0, 0, (short)0, 0)); @@ -63,41 +64,46 @@ public void SetUp() } - /* TODO-Fonts: [Test] public void TestGetFont() { - System.Drawing.Font f = graphics.Font; - if (f.ToString().IndexOf("dialog") == -1 && f.ToString().IndexOf("Dialog") == -1) + Font f = graphics.Font; + if (!f.ToString().Contains("dialog") && !f.ToString().Contains("Dialog")) { //ClassicAssert.AreEqual("java.awt.Font[family=Arial,name=Arial,style=plain,size=10]", f.ToString()); - ClassicAssert.AreEqual("[Font: Name=Arial, Size=10, Units=3, GdiCharSet=1, GdiVerticalFont=False]", f.ToString()); + //ClassicAssert.AreEqual("[Font: Name=Arial, Size=10, Units=3, GdiCharSet=1, GdiVerticalFont=False]", f.ToString()); + ClassicAssert.AreEqual("Arial", f.Family.Name); + ClassicAssert.AreEqual("Arial", f.Name); + ClassicAssert.AreEqual(10, f.Size); + ClassicAssert.AreEqual(FontStyle.Regular, f.FontMetrics.Description.Style); } } - */ - - //[Test] - //public void TestGetFontMetrics() - //{ - // Font f = graphics.Font; - // if (f.ToString().IndexOf("dialog") != -1 || f.ToString().IndexOf("Dialog") != -1) - // return; - - // ClassicAssert.AreEqual(7, TextRenderer.MeasureText("X", f).Width); - // ClassicAssert.AreEqual("Arial", f.FontFamily.Name); - // ClassicAssert.AreEqual(10, f.Size); - // //ClassicAssert.AreEqual("java.awt.Font[family=Arial,name=Arial,style=plain,size=10]", fontMetrics.GetFont().ToString()); - //} - - /* TODO-Fonts: + + [Test] + public void TestGetFontMetrics() + { + Font f = graphics.Font; + if (f.ToString().Contains("dialog") || f.ToString().Contains("Dialog")) + return; + + ClassicAssert.AreEqual(7, TextMeasurer.MeasureSize("X", new TextOptions(f)).Width); + ClassicAssert.AreEqual("Arial", f.Family.Name); + ClassicAssert.AreEqual(10, f.Size); + ClassicAssert.AreEqual(FontStyle.Regular, f.FontMetrics.Description.Style); + //ClassicAssert.AreEqual("java.awt.Font[family=Arial,name=Arial,style=plain,size=10]", fontMetrics.GetFont().ToString()); + } + [Test] public void TestSetFont() { - System.Drawing.Font f = new System.Drawing.Font("Helvetica", 12,FontStyle.Regular); + FontCollection fonts = new FontCollection(); + var fi = POIDataSamples.GetSpreadSheetInstance().GetFileInfo("Helvetica.ttf"); + SixLabors.Fonts.FontFamily font1 = fonts.Add(fi.FullName); + Font f = new Font(font1, 12, FontStyle.Regular); graphics.SetFont(f); ClassicAssert.AreEqual(f, graphics.Font); } -*/ + [Test] public void TestSetColor() { diff --git a/testcases/main/SS/Util/TestCellReference.cs b/testcases/main/SS/Util/TestCellReference.cs index 254259a2b..ced9d7d18 100644 --- a/testcases/main/SS/Util/TestCellReference.cs +++ b/testcases/main/SS/Util/TestCellReference.cs @@ -339,8 +339,27 @@ public void IsRowWithinRange() ClassicAssert.IsTrue(CellReference.IsRowWithinRange("1", ss), "first row"); ClassicAssert.IsTrue(CellReference.IsRowWithinRange("1048576", ss), "last row"); ClassicAssert.IsFalse(CellReference.IsRowWithinRange("1048577", ss), "1 beyond last row"); + + ClassicAssert.IsFalse(CellReference.IsRowWithinRange(-1, ss), "1 before first row"); + ClassicAssert.IsTrue(CellReference.IsRowWithinRange(0, ss), "first row"); + ClassicAssert.IsTrue(CellReference.IsRowWithinRange(1048575, ss), "last row"); + ClassicAssert.IsFalse(CellReference.IsRowWithinRange(1048576, ss), "1 beyond last row"); + } + + [Test] //(expected= NumberFormatException.class) + public void IsRowWithinRangeNonInteger_BigNumber() + { + String rowNum = "4000000000"; + CellReference.IsRowWithinRange(rowNum, SpreadsheetVersion.EXCEL2007); } + [Test] //(expected= NumberFormatException.class) + public void IsRowWithinRangeNonInteger_Alpha() + { + String rowNum = "NotANumber"; + CellReference.IsRowWithinRange(rowNum, SpreadsheetVersion.EXCEL2007); + } + [Test] public void IsColWithinRange() { diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFName.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFName.cs index cc268410a..08fcefdc2 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFName.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFName.cs @@ -16,11 +16,14 @@ limitations under the License. ==================================================================== */ using TestCases.SS.UserModel; -using NUnit.Framework;using NUnit.Framework.Legacy; +using NUnit.Framework; +using NUnit.Framework.Legacy; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF; using NPOI.XSSF.UserModel; +using System; +using NPOI.Util; namespace TestCases.XSSF.UserModel { @@ -131,6 +134,33 @@ public void TestSetNameName() wb.Close(); } + //github-55 + [Test] + public void TestSetNameNameCellAddress() + { + XSSFWorkbook wb = new XSSFWorkbook(); + wb.CreateSheet("First Sheet"); + XSSFName name = wb.CreateName() as XSSFName; + + // Cell addresses/references are not allowed + foreach (string ref1 in Arrays.AsList("A1", "$A$1", "A1:B2")) + { + try + { + name.NameName = ref1; + Assert.Fail("cell addresses are not allowed: " + ref1); + } + catch (ArgumentException e) + { + // expected + } + } + + // Name that looks similar to a cell reference but is outside the cell reference row and column limits + name.NameName = ("A0"); + name.NameName = ("F04030020010"); + name.NameName = ("XFDXFD10"); + } } } diff --git a/testcases/test-data/spreadsheet/Helvetica.ttf b/testcases/test-data/spreadsheet/Helvetica.ttf new file mode 100644 index 000000000..7aec6f3f3 Binary files /dev/null and b/testcases/test-data/spreadsheet/Helvetica.ttf differ