diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java index dca1aed06..b1c6be457 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java @@ -20,11 +20,7 @@ import java.awt.Dimension; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Pattern; import org.apache.poi.POIXMLDocument; @@ -366,18 +362,26 @@ public class XMLSlideShow extends POIXMLDocument { * * @param newIndex 0-based index of the slide */ + @SuppressWarnings("deprecation") public void setSlideOrder(XSLFSlide slide, int newIndex){ int oldIndex = _slides.indexOf(slide); if(oldIndex == -1) throw new IllegalArgumentException("Slide not found"); + if (oldIndex == newIndex) return; // fix the usermodel container _slides.add(newIndex, _slides.remove(oldIndex)); // fix ordering in the low-level xml CTSlideIdList sldIdLst = _presentation.getSldIdLst(); - CTSlideIdListEntry oldEntry = sldIdLst.getSldIdArray(oldIndex); - sldIdLst.insertNewSldId(newIndex).set(oldEntry); - sldIdLst.removeSldId(oldIndex); + CTSlideIdListEntry[] entries = sldIdLst.getSldIdArray(); + CTSlideIdListEntry oldEntry = entries[oldIndex]; + if (oldIndex < newIndex) { + System.arraycopy(entries, oldIndex + 1, entries, oldIndex, newIndex - oldIndex); + } else { + System.arraycopy(entries, newIndex, entries, newIndex + 1, oldIndex - newIndex); + } + entries[newIndex] = oldEntry; + sldIdLst.setSldIdArray(entries); } public XSLFSlide removeSlide(int index){ diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java index bee365143..7d18541d9 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java @@ -233,4 +233,44 @@ public class TestXSLFBugs { } return text.toString(); } + + @Test + public void bug57250() throws Exception { + XMLSlideShow ss = new XMLSlideShow(); + for (String s : new String[]{"Slide1","Slide2"}) { + ss.createSlide().createTextBox().setText(s); + } + validateSlides(ss, false, "Slide1","Slide2"); + + XSLFSlide slide = ss.createSlide(); + slide.createTextBox().setText("New slide"); + validateSlides(ss, true, "Slide1","Slide2","New slide"); + + // Move backward + ss.setSlideOrder(slide, 0); + validateSlides(ss, true, "New slide","Slide1","Slide2"); + + // Move forward + ss.setSlideOrder(slide, 1); + validateSlides(ss, true, "Slide1","New slide","Slide2"); + + // Move to end + ss.setSlideOrder(slide, 0); + ss.setSlideOrder(slide, 2); + validateSlides(ss, true, "Slide1","Slide2","New slide"); + } + + private void validateSlides(XMLSlideShow ss, boolean saveAndReload, String... slideTexts) { + if (saveAndReload) { + ss = XSLFTestDataSamples.writeOutAndReadBack(ss); + } + + assertEquals(slideTexts.length, ss.getSlides().length); + + for (int i = 0; i < slideTexts.length; i++) { + XSLFSlide slide = ss.getSlides()[i]; + assertContains(getSlideText(slide), slideTexts[i]); + } + } + }