This is an automated email from the ASF dual-hosted git repository.

fanningpj pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 4b3c688d51 Add methods to manage first slide number(firstSlideNum) 
(#968)
4b3c688d51 is described below

commit 4b3c688d51d03b8706d97d0589cc8985d661dd94
Author: hyun1024 <[email protected]>
AuthorDate: Sat Dec 13 21:06:04 2025 +0900

    Add methods to manage first slide number(firstSlideNum) (#968)
    
    * Add methods to manage first slide number(firstSlideNum)
    
    Adds methods to manage the custom starting slide number in XSLF 
(PowerPoint) presentations. This property is stored as the 'firstSlideNum' 
attribute in ppt/presentation.xml.
    
    The following methods are added to XMLSlideShow:
    - getFirstSlideNumber(): Retrieves the current starting slide number 
(default is 1).
    - setFirstSlideNumber(int num): Sets the custom starting slide number.
    - unsetFirstSlideNumber(): Removes the 'firstSlideNum' attribute, reverting 
to the default (1).
    
    Constraints:
    The 'set' method enforces the bounds [0, 9999] as defined by Microsoft's 
implementation specifications (MS-OI29500, Part 1, Section 19.2.1.26) to ensure 
the creation of valid PowerPoint files.
    
    Also includes TestXSLFSlideShow updates to cover the new functionality, 
persistence, and validation checks.
    
    * Review: Apply review feedback to firstSlideNumber feature
    
    - Add @since 6.0.0 Javadoc tag to getFirstSlideNumber(), 
setFirstSlideNumber(), and unsetFirstSlideNumber() methods in XMLSlideShow.
    - Refactor TestXSLFSlideShow to use explicit static JUnit imports (e.g., 
assertEquals, assertThrows) instead of wildcard imports, adhering to project 
coding style guidelines.
    
    * whitespace
    
    ---------
    
    Co-authored-by: PJ Fanning <[email protected]>
---
 .../apache/poi/xslf/usermodel/XMLSlideShow.java    |  47 ++++++++++
 .../poi/xslf/usermodel/TestXSLFSlideShow.java      | 102 ++++++++++++++++++++-
 2 files changed, 145 insertions(+), 4 deletions(-)

diff --git 
a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java 
b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
index 63cea1a76c..44585f8b77 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
@@ -748,4 +748,51 @@ public class XMLSlideShow extends POIXMLDocument
         RelationPart rp = target.addRelation(null, XSLFRelation.IMAGES, 
pictureData);
         return rp.getRelationship().getId();
     }
+
+    /**
+     * Returns the number that shall be displayed on the first slide of the 
presentation.
+     * Subsequent slides will be numbered sequentially from this number.
+     * The default value is 1 if the property is not set in the presentation 
file.
+     *
+     * @return The starting number for the first slide (default is 1).
+     * @since 6.0.0
+     */
+    public int getFirstSlideNumber() {
+        // CTPresentation.getFirstSlideNum() returns the default value of 1
+        // if the 'firstSlideNum' attribute is not set, as per OOXML standard.
+        return getCTPresentation().getFirstSlideNum();
+    }
+
+    /**
+     * Sets the custom number that shall be displayed on the first slide of 
the presentation.
+     * Subsequent slides will be numbered sequentially from this number.
+     *
+     * The value is restricted to the range [0, 9999] as defined in the 
Microsoft Office
+     * Implementation Information for ISO/IEC 29500 (MS-OI29500), specifically 
in
+     * Part 1, Section 19.2.1.26, presentation (Presentation), which restricts 
the
+     * XML Schema int datatype.
+     *
+     * @param num The starting number for the first slide (must be between 0 
and 9999).
+     * @throws IllegalArgumentException if the provided number is outside the 
allowed range [0, 9999].
+     * @since 6.0.0
+     */
+    public void setFirstSlideNumber(int num) {
+        // We enforce the PowerPoint application constraint (0 <= num <= 9999)
+        // to ensure that a valid file, as rendered by PowerPoint, is created.
+        if (num < 0 || num > 9999) {
+            throw new IllegalArgumentException(
+                    "First slide number must be between 0 and 9999 
(inclusive), as required by MS-OI29500 (Part 1, Section 19.2.1.26).");
+        }
+        // Sets the attribute on the underlying CTPresentation object.
+        getCTPresentation().setFirstSlideNum(num);
+    }
+
+    /**
+     * Unsets the custom first slide number, reverting the numbering to the 
default (1).
+     * This removes the 'firstSlideNum' attribute from presentation.xml.
+     * @since 6.0.0
+     */
+    public void unsetFirstSlideNumber() {
+        getCTPresentation().unsetFirstSlideNum();
+    }
 }
diff --git 
a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java 
b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java
index 45e2aa31c2..312c804a3f 100644
--- 
a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java
+++ 
b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java
@@ -16,10 +16,6 @@
 ==================================================================== */
 package org.apache.poi.xslf.usermodel;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertSame;
-
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.io.ByteArrayInputStream;
@@ -34,6 +30,12 @@ import org.apache.poi.sl.usermodel.Placeholder;
 import org.apache.poi.xslf.XSLFTestDataSamples;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 class TestXSLFSlideShow {
     @Test
     void testCreateSlide() throws IOException {
@@ -327,4 +329,96 @@ class TestXSLFSlideShow {
             }
         }
     }
+
+    /**
+     * Test getting the first slide number, which defaults to 1.
+     * The first slide number is stored in the presentation.xml part.
+     */
+    @Test
+    void testGetFirstSlideNumberDefault() throws IOException {
+        try (XMLSlideShow ppt = new XMLSlideShow()) {
+            // Default value when attribute is not present should be 1 (as per 
OOXML standard and CTPresentation logic)
+            assertEquals(1, ppt.getFirstSlideNumber());
+        }
+    }
+
+    /**
+     * Test setting, getting, and persisting the custom first slide number.
+     */
+    @Test
+    void testSetAndPersistFirstSlideNumber() throws IOException {
+        final int customStartNum = 5;
+        final int zeroStartNum = 0;
+        final int maxStartNum = 9999;
+
+        try (XMLSlideShow ppt = new XMLSlideShow()) {
+            // 1. Set to a custom positive number (e.g., 5)
+            ppt.setFirstSlideNumber(customStartNum);
+            assertEquals(customStartNum, ppt.getFirstSlideNumber());
+
+            // Check persistence by writing out and reading back
+            try (XMLSlideShow ppt2 = 
XSLFTestDataSamples.writeOutAndReadBack(ppt)) {
+                assertEquals(customStartNum, ppt2.getFirstSlideNumber(),
+                        "The custom first slide number should persist after 
save/load.");
+            }
+
+            // 2. Set to minimum valid number (0)
+            ppt.setFirstSlideNumber(zeroStartNum);
+            assertEquals(zeroStartNum, ppt.getFirstSlideNumber());
+
+            // 3. Set to maximum valid number (9999)
+            ppt.setFirstSlideNumber(maxStartNum);
+            assertEquals(maxStartNum, ppt.getFirstSlideNumber());
+        }
+    }
+
+    /**
+     * Test unsetting the first slide number, which should revert it to the 
default (1).
+     */
+    @Test
+    void testUnsetFirstSlideNumber() throws IOException {
+        try (XMLSlideShow ppt = new XMLSlideShow()) {
+            // 1. Set a custom number
+            ppt.setFirstSlideNumber(50);
+            assertEquals(50, ppt.getFirstSlideNumber());
+
+            // 2. Unset it
+            ppt.unsetFirstSlideNumber();
+
+            // It should return the default value (1) after unsetting
+            assertEquals(1, ppt.getFirstSlideNumber(),
+                    "Unsetting the first slide number should revert it to the 
default of 1.");
+
+            // Check persistence after unsetting
+            try (XMLSlideShow ppt2 = 
XSLFTestDataSamples.writeOutAndReadBack(ppt)) {
+                assertEquals(1, ppt2.getFirstSlideNumber(),
+                        "The first slide number should remain the default (1) 
after unset and save/load.");
+                // Ensure the attribute is actually removed from the 
CTPresentation object
+                // Note: We access the internal object to confirm removal, 
which is acceptable in test code.
+                assertFalse(ppt2.getCTPresentation().isSetFirstSlideNum(),
+                        "The 'firstSlideNum' attribute should be unset 
(removed) in the XML.");
+            }
+        }
+    }
+
+    /**
+     * Test that setting an invalid first slide number (outside [0, 9999]) 
throws an exception.
+     */
+    @Test
+    void testSetFirstSlideNumberValidation() throws IOException {
+        try (XMLSlideShow ppt = new XMLSlideShow()) {
+            // Test case: Negative number
+            assertThrows(IllegalArgumentException.class, () ->
+                            ppt.setFirstSlideNumber(-1),
+                    "Negative number should throw IllegalArgumentException.");
+
+            // Test case: Number greater than 9999
+            assertThrows(IllegalArgumentException.class, () ->
+                            ppt.setFirstSlideNumber(10000),
+                    "Number greater than 9999 should throw 
IllegalArgumentException.");
+
+            // Ensure the value hasn't changed from the default after failed 
attempts
+            assertEquals(1, ppt.getFirstSlideNumber());
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to