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 ca6e02d69b..fa9c72bb80 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java @@ -20,6 +20,7 @@ package org.apache.poi.hslf.model; +import java.util.Iterator; import java.util.LinkedList; import java.util.Vector; @@ -252,9 +253,81 @@ public class TextRun // Update methods follow + + /** + * Adds the supplied text onto the end of the TextRun, + * creating a new RichTextRun (returned) for it to + * sit in. + */ + public RichTextRun appendText(String s) { + // We will need a StyleTextProp atom + ensureStyleAtomPresent(); + + // First up, append the text + int oldSize = getRawText().length(); + storeText( + getRawText() + s + ); + + // If either of the previous styles overran + // the text by one, we need to shuffle that + // extra character onto the new ones + Iterator it = _styleAtom.getParagraphStyles().iterator(); + int pLen = 0; + while(it.hasNext()) { + TextPropCollection tpc = (TextPropCollection)it.next(); + pLen += tpc.getCharactersCovered(); + } + it = _styleAtom.getCharacterStyles().iterator(); + int cLen = 0; + while(it.hasNext()) { + TextPropCollection tpc = (TextPropCollection)it.next(); + cLen += tpc.getCharactersCovered(); + } + int pOverRun = pLen - oldSize; + int cOverRun = cLen - oldSize; + + if(pOverRun > 0) { + TextPropCollection tpc = (TextPropCollection) + _styleAtom.getParagraphStyles().getLast(); + tpc.updateTextSize( + tpc.getCharactersCovered() - pOverRun + ); + } + if(cOverRun > 0) { + TextPropCollection tpc = (TextPropCollection) + _styleAtom.getCharacterStyles().getLast(); + tpc.updateTextSize( + tpc.getCharactersCovered() - cOverRun + ); + } + + // Next, add the styles for its + // paragraph and characters + TextPropCollection newPTP = + _styleAtom.addParagraphTextPropCollection(s.length()+pOverRun); + TextPropCollection newCTP = + _styleAtom.addCharacterTextPropCollection(s.length()+cOverRun); + + // Now, create the new RichTextRun + RichTextRun nr = new RichTextRun( + this, oldSize, s.length(), + newPTP, newCTP, false, false + ); + + // Add the new RichTextRun onto our list + RichTextRun[] newRuns = new RichTextRun[_rtRuns.length+1]; + System.arraycopy(_rtRuns, 0, newRuns, 0, _rtRuns.length); + newRuns[newRuns.length-1] = nr; + _rtRuns = newRuns; + + // And return the new run to the caller + return nr; + } /** - * Saves the given string to the records. Doesn't touch the stylings. + * Saves the given string to the records. Doesn't + * touch the stylings. */ private void storeText(String s) { // Remove a single trailing \n, as there is an implicit one at the diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java index 7561a5fe56..0fecdab97b 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java @@ -16,16 +16,22 @@ */ package org.apache.poi.hslf.usermodel; -import java.io.*; -import java.awt.*; - -import org.apache.poi.hslf.HSLFSlideShow; -import org.apache.poi.hslf.model.*; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.SlideListWithText; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import junit.framework.TestCase; +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.model.Slide; +import org.apache.poi.hslf.model.SlideMaster; +import org.apache.poi.hslf.model.TextBox; +import org.apache.poi.hslf.model.TextRun; +import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.record.SlideListWithText; + /** * Test that the friendly getters and setters on RichTextRun * behave as expected. @@ -549,4 +555,75 @@ if(false) { assertEquals(0, rt.getBulletOffset()); assertEquals('\u263A', rt.getBulletChar()); } + + public void testAddText() throws Exception { + FileInputStream is = new FileInputStream(new File(System.getProperty("HSLF.testdata.path"), "bullets.ppt")); + SlideShow ppt = new SlideShow(is); + is.close(); + assertTrue("No Exceptions while reading file", true); + + RichTextRun rt; + TextRun[] txt; + Slide[] slides = ppt.getSlides(); + + assertEquals(2, slides.length); + txt = slides[0].getTextRuns(); + assertEquals(2, txt.length); + + assertEquals("Title text", txt[0].getRawText()); + assertEquals(1, txt[0].getRichTextRuns().length); + rt = txt[0].getRichTextRuns()[0]; + assertFalse(rt.isBullet()); + + // Add some new text + txt[0].appendText("Foo! I'm new!"); + assertEquals(2, txt[0].getRichTextRuns().length); + + rt = txt[0].getRichTextRuns()[0]; + assertFalse(rt.isBold()); + assertEquals("Title text", rt.getText()); + rt = txt[0].getRichTextRuns()[1]; + assertFalse(rt.isBold()); + assertEquals("Foo! I'm new!", rt.getText()); + rt.setBold(true); + + // And some more + txt[0].appendText("Me too!"); + assertEquals(3, txt[0].getRichTextRuns().length); + rt = txt[0].getRichTextRuns()[0]; + assertFalse(rt.isBold()); + assertEquals("Title text", rt.getText()); + rt = txt[0].getRichTextRuns()[1]; + assertTrue(rt.isBold()); + assertEquals("Foo! I'm new!", rt.getText()); + rt = txt[0].getRichTextRuns()[2]; + assertFalse(rt.isBold()); + assertEquals("Me too!", rt.getText()); + + // Save and re-open + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray())); + slides = ppt.getSlides(); + + assertEquals(2, slides.length); + + txt = slides[0].getTextRuns(); + assertEquals(2, txt.length); + assertEquals(3, txt[0].getRichTextRuns().length); + rt = txt[0].getRichTextRuns()[0]; + assertFalse(rt.isBold()); + assertEquals("Title text", rt.getText()); + rt = txt[0].getRichTextRuns()[1]; + assertTrue(rt.isBold()); + assertEquals("Foo! I'm new!", rt.getText()); + rt = txt[0].getRichTextRuns()[2]; + assertFalse(rt.isBold()); + assertEquals("Me too!", rt.getText()); + +// FileOutputStream fout = new FileOutputStream("/tmp/foo.ppt"); +// ppt.write(fout); + } }