diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index e81bf101a..764cb7375 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 47261 - Fixed SlideShow#removeSlide to remove references to Notes 47375 - Fixed HSSFHyperlink to correctly set inter-sheet and file links 47384 - Fixed ExternalNameRecord to handle unicode names 47372 - Fixed locale-sensitive unit tests to pass when running on non-US locale diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Document.java b/src/scratchpad/src/org/apache/poi/hslf/record/Document.java index 069d877a0..a9510ae55 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Document.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Document.java @@ -21,6 +21,7 @@ import org.apache.poi.util.POILogger; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; /** * Master container for Document. There is one of these for every @@ -189,6 +190,16 @@ public final class Document extends PositionDependentRecordContainer slwts = nl; } + public void removeSlideListWithText(SlideListWithText slwt) { + ArrayList lst = new ArrayList(); + for(SlideListWithText s : slwts) { + if(s != slwt) lst.add(s); + else { + removeChild(slwt); + } + } + slwts = lst.toArray(new SlideListWithText[lst.size()]); + } /** * We are of type 1000 diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java index 9450e6986..749e9edcc 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java @@ -24,6 +24,7 @@ import org.apache.poi.hslf.util.MutableByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.ByteArrayOutputStream; +import java.util.ArrayList; /** * Abstract class which all container records will extend. Providers @@ -135,7 +136,24 @@ public abstract class RecordContainer extends Record return null; } - /* =============================================================== + /** + * Remove a child record from this record container + * + * @param ch the child to remove + * @return the removed record + */ + public Record removeChild(Record ch) { + Record rm = null; + ArrayList lst = new ArrayList(); + for(Record r : _children) { + if(r != ch) lst.add(r); + else rm = r; + } + _children = lst.toArray(new Record[lst.size()]); + return rm; + } + + /* =============================================================== * External Move Methods * =============================================================== */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java index 15650d0ad..cf8d89050 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -601,10 +601,39 @@ public final class SlideShow { removedSlide = _slides[i]; } } - slwt.setSlideAtomsSets( sa.toArray(new SlideAtomsSet[sa.size()]) ); - slwt.setChildRecord(records.toArray(new Record[records.size()])); + if(sa.size() == 0){ + _documentRecord.removeSlideListWithText(slwt); + } else { + slwt.setSlideAtomsSets( sa.toArray(new SlideAtomsSet[sa.size()]) ); + slwt.setChildRecord(records.toArray(new Record[records.size()])); + } _slides = sl.toArray(new Slide[sl.size()]); + //if the removed slide had notes - remove references to them too + if(removedSlide != null){ + int notesId = removedSlide.getSlideRecord().getSlideAtom().getNotesID(); + if(notesId != 0){ + SlideListWithText nslwt = _documentRecord.getNotesSlideListWithText(); + records = new ArrayList(); + ArrayList na = new ArrayList(); + for (SlideAtomsSet ns : nslwt.getSlideAtomsSets()){ + if(ns.getSlidePersistAtom().getSlideIdentifier() != notesId) { + na.add(ns); + records.add(ns.getSlidePersistAtom()); + if(ns.getSlideRecords() != null) records.addAll(Arrays.asList(ns.getSlideRecords())); + } + } + if(na.size() == 0){ + _documentRecord.removeSlideListWithText(nslwt); + } else { + slwt.setSlideAtomsSets( na.toArray(new SlideAtomsSet[na.size()]) ); + slwt.setChildRecord(records.toArray(new Record[records.size()])); + } + + } + + } + return removedSlide; } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/47261.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/47261.ppt new file mode 100755 index 000000000..be472de7c Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hslf/data/47261.ppt differ diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordContainer.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordContainer.java index 89e638720..74684e7e7 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordContainer.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordContainer.java @@ -136,7 +136,14 @@ public final class TestRecordContainer extends TestCase { assertEquals(before, ncr[1]); } - protected void setUp() throws Exception { + public void testRemove() { + Record[] ch = recordContainer.getChildRecords(); + Record removeRecord = recordContainer.removeChild(ch[0]); + assertSame(ch[0], removeRecord); + assertEquals(ch.length-1, recordContainer.getChildRecords().length); + } + + protected void setUp() throws Exception { super.setUp(); // Find a real RecordContainer record diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java index 52a1da7ce..4ffeb8789 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestAddingSlides.java @@ -20,12 +20,15 @@ package org.apache.poi.hslf.usermodel; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.File; import junit.framework.TestCase; import org.apache.poi.hslf.*; import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.UserEditAtom; +import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.model.*; /** @@ -269,4 +272,24 @@ public final class TestAddingSlides extends TestCase { assertEquals(1, s3.length); } + + public void test47261() throws Exception { + File src = new File(System.getProperty("HSLF.testdata.path"), "47261.ppt"); + SlideShow ppt = new SlideShow(new FileInputStream(src)); + Slide[] slides = ppt.getSlides(); + Document doc = ppt.getDocumentRecord(); + assertNotNull(doc.getSlideSlideListWithText()); + assertEquals(1, ppt.getSlides().length); + int notesId = slides[0].getSlideRecord().getSlideAtom().getNotesID(); + assertTrue(notesId > 0); + assertNotNull(doc.getNotesSlideListWithText()); + //the SLWT container for notes has one entry which will deleted + assertEquals(1, doc.getNotesSlideListWithText().getSlideAtomsSets().length); + + ppt.removeSlide(0); + assertEquals(0, ppt.getSlides().length); + assertNull(doc.getSlideSlideListWithText()); + assertNull(doc.getNotesSlideListWithText()); + + } }