diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java index 5c32b9d13e..fdc30f6ea0 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java @@ -17,11 +17,20 @@ package org.apache.poi.hslf.model; +import java.util.ArrayList; import java.util.LinkedList; -import java.util.Vector; +import java.util.List; import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.record.RecordContainer; +import org.apache.poi.hslf.record.StyleTextProp9Atom; +import org.apache.poi.hslf.record.StyleTextPropAtom; +import org.apache.poi.hslf.record.TextBytesAtom; +import org.apache.poi.hslf.record.TextCharsAtom; +import org.apache.poi.hslf.record.TextHeaderAtom; +import org.apache.poi.hslf.record.TextRulerAtom; +import org.apache.poi.hslf.record.TextSpecInfoAtom; import org.apache.poi.hslf.usermodel.RichTextRun; import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.util.StringUtil; @@ -54,7 +63,7 @@ public final class TextRun * (there can be misc InteractiveInfo, TxInteractiveInfo and other records) */ protected Record[] _records; - private StyleTextPropAtom styleTextPropAtom; + // private StyleTextPropAtom styleTextPropAtom; private StyleTextProp9Atom styleTextProp9Atom; /** @@ -95,8 +104,8 @@ public final class TextRun String runRawText = getText(); // Figure out the rich text runs - LinkedList pStyles = new LinkedList(); - LinkedList cStyles = new LinkedList(); + LinkedList pStyles = new LinkedList(); + LinkedList cStyles = new LinkedList(); if(_styleAtom != null) { // Get the style atom to grok itself _styleAtom.setParentTextSize(runRawText.length()); @@ -106,7 +115,7 @@ public final class TextRun buildRichTextRuns(pStyles, cStyles, runRawText); } - public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText){ + public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText){ // Handle case of no current style, with a default if(pStyles.size() == 0 || cStyles.size() == 0) { @@ -115,7 +124,7 @@ public final class TextRun } else { // Build up Rich Text Runs, one for each // character/paragraph style pair - Vector rtrs = new Vector(); + List rtrs = new ArrayList(); int pos = 0; @@ -249,8 +258,7 @@ public final class TextRun } // Build the array - _rtRuns = new RichTextRun[rtrs.size()]; - rtrs.copyInto(_rtRuns); + _rtRuns = rtrs.toArray(new RichTextRun[rtrs.size()]); } } @@ -470,13 +478,22 @@ public final class TextRun // no change, stays with no styling // If there is styling: // everthing gets the same style that the first block has + // Update the lengths +1 for since these will be the only runs if(_styleAtom != null) { - LinkedList pStyles = _styleAtom.getParagraphStyles(); + LinkedList pStyles = _styleAtom.getParagraphStyles(); while(pStyles.size() > 1) { pStyles.removeLast(); } - LinkedList cStyles = _styleAtom.getCharacterStyles(); - while(cStyles.size() > 1) { cStyles.removeLast(); } + if (!pStyles.isEmpty()) { + pStyles.getFirst().updateTextSize( s.length()+1 ); + } + LinkedList cStyles = _styleAtom.getCharacterStyles(); + while(cStyles.size() > 1) { cStyles.removeLast(); } + + if (!cStyles.isEmpty()) { + cStyles.getFirst().updateTextSize( s.length()+1 ); + } + _rtRuns[0].setText(s); } else { // Recreate rich text run with no styling diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index f702388793..19b0359a31 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -19,6 +19,7 @@ package org.apache.poi.hslf.usermodel; import java.io.InputStream; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -202,6 +203,7 @@ public final class TestBugs extends TestCase { SlideShow ppt = new SlideShow(hslf); Slide[] slide = ppt.getSlides(); for (int i = 0; i < slide.length; i++) { + @SuppressWarnings("unused") Shape[] shape = slide[i].getShapes(); } assertTrue("No Exceptions while reading file", true); @@ -259,6 +261,7 @@ public final class TestBugs extends TestCase { for (int k = 0; k < comps.length; k++) { Shape comp = comps[k]; if (comp instanceof Picture){ + @SuppressWarnings("unused") PictureData pict = ((Picture)comp).getPictureData(); } } @@ -435,4 +438,32 @@ public final class TestBugs extends TestCase { ppt = HSLFTestDataSamples.writeOutAndReadBack(ppt); assertTrue("No Exceptions while rewriting file", true); } + + /** + * Bug 45776: Fix corrupt file problem using TextRun.setText + */ + public void test45776() throws Exception { + InputStream is = _slTests.openResourceAsStream("45776.ppt"); + SlideShow ppt = new SlideShow(new HSLFSlideShow(is)); + is.close(); + + // get slides + for (Slide slide : ppt.getSlides()) { + for (Shape shape : slide.getShapes()) { + if (!(shape instanceof TextBox)) continue; + TextBox tb = (TextBox) shape; + // work with TextBox + String str = tb.getText(); + + if (!str.contains("$$DATE$$")) continue; + str = str.replace("$$DATE$$", new Date().toString()); + tb.setText(str); + + TextRun tr = tb.getTextRun(); + assertEquals(str.length()+1,tr.getStyleTextPropAtom().getParagraphStyles().getFirst().getCharactersCovered()); + assertEquals(str.length()+1,tr.getStyleTextPropAtom().getCharacterStyles().getFirst().getCharactersCovered()); + } + } + } + } diff --git a/test-data/slideshow/45776.ppt b/test-data/slideshow/45776.ppt new file mode 100644 index 0000000000..637b06ec3d Binary files /dev/null and b/test-data/slideshow/45776.ppt differ