From c8d66033f0346a255370a404f05f9917d5b313f5 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sat, 3 Apr 2010 14:44:39 +0000 Subject: [PATCH] propagate parent to parent-aware records decoded from Escher, also ensure that TextShape and EscherTextboxWrapper hold the same cached sets of records, see Bugzilla 48916 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@930525 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../src/org/apache/poi/hslf/model/Sheet.java | 3 ++ .../apache/poi/hslf/model/SlideMaster.java | 4 ++ .../org/apache/poi/hslf/model/TextShape.java | 8 ++++ .../poi/hslf/record/RecordContainer.java | 19 +++++++++ .../apache/poi/hslf/usermodel/SlideShow.java | 36 ++++------------ .../apache/poi/hslf/model/TestTextRun.java | 41 +++++++++++++++++++ 7 files changed, 83 insertions(+), 29 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 50bc1cd624..846614c880 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 48916 - Propagate parent to parent-aware records decoded from Escher 48485 - Add extra paper size constans to PrintSetup, such as A3, B4 and B5 Make poifs.filesystem.DirectoryNode preserve the original ordering of its files, which HSMF needs to be able to correctly match up chunks Support evaluation of indirect defined names in INDIRECT diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index f42eb8429c..e524665395 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -126,6 +126,9 @@ public abstract class Sheet { EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers(); for (int i = 0; i < wrappers.length; i++) { int s1 = runsV.size(); + + // propagate parents to parent-aware records + RecordContainer.handleParentAwareRecords(wrappers[i]); findTextRuns(wrappers[i].getChildRecords(), runsV); int s2 = runsV.size(); if (s2 != s1){ diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java index a72e4658b7..5ebbb27fba 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java @@ -140,4 +140,8 @@ public final class SlideMaster extends MasterSheet { _runs = tmp; } } + + public TxMasterStyleAtom[] getTxMasterStyleAtoms(){ + return _txmaster; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java index 5724e270fa..b1ae68f059 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java @@ -527,6 +527,14 @@ public abstract class TextShape extends SimpleShape { } } } + // ensure the same references child records of TextRun + if(_txtrun != null) for (int i = 0; i < child.length; i++) { + for (Record r : _txtrun.getRecords()) { + if (child[i].getRecordType() == r.getRecordType()) { + child[i] = r; + } + } + } } public void draw(Graphics2D graphics){ 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 509c891ce7..be732d44ca 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java @@ -341,4 +341,23 @@ public abstract class RecordContainer extends Record out.write(toWrite); } } + + /** + * Find the records that are parent-aware, and tell them who their parent is + */ + public static void handleParentAwareRecords(RecordContainer br) { + // Loop over child records, looking for interesting ones + for (Record record : br.getChildRecords()) { + // Tell parent aware records of their parent + if (record instanceof ParentAwareRecord) { + ((ParentAwareRecord) record).setParentRecord(br); + } + // Walk on down for the case of container records + if (record instanceof RecordContainer) { + handleParentAwareRecords((RecordContainer)record); + } + } + } + + } 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 8214f0d36c..9418363849 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -91,13 +91,15 @@ public final class SlideShow { * @param hslfSlideShow the HSLFSlideShow to base on */ public SlideShow(HSLFSlideShow hslfSlideShow) { - // Get useful things from our base slideshow - _hslfSlideShow = hslfSlideShow; + // Get useful things from our base slideshow + _hslfSlideShow = hslfSlideShow; _records = _hslfSlideShow.getRecords(); - // Handle Parent-aware Reocrds - for (int i = 0; i < _records.length; i++) { - handleParentAwareRecords(_records[i]); + // Handle Parent-aware Records + for (Record record : _records) { + if(record instanceof RecordContainer){ + RecordContainer.handleParentAwareRecords((RecordContainer)record); + } } // Find the versions of the core records we'll want to use @@ -121,30 +123,6 @@ public final class SlideShow { this(new HSLFSlideShow(inputStream)); } - /** - * Find the records that are parent-aware, and tell them who their parent is - */ - private void handleParentAwareRecords(Record baseRecord) { - // Only need to do something if this is a container record - if (baseRecord instanceof RecordContainer) { - RecordContainer br = (RecordContainer) baseRecord; - Record[] childRecords = br.getChildRecords(); - - // Loop over child records, looking for interesting ones - for (int i = 0; i < childRecords.length; i++) { - Record record = childRecords[i]; - // Tell parent aware records of their parent - if (record instanceof ParentAwareRecord) { - ((ParentAwareRecord) record).setParentRecord(br); - } - // Walk on down for the case of container records - if (record instanceof RecordContainer) { - handleParentAwareRecords(record); - } - } - } - } - /** * Use the PersistPtrHolder entries to figure out what is the "most recent" * version of all the core records (Document, Notes, Slide etc), and save a diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java index be399fefa6..471ee5bb50 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java @@ -18,11 +18,15 @@ package org.apache.poi.hslf.model; +import java.awt.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; import org.apache.poi.hslf.model.textproperties.TextPropCollection; +import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.TextBytesAtom; import org.apache.poi.hslf.record.TextCharsAtom; import org.apache.poi.hslf.record.TextHeaderAtom; @@ -490,4 +494,41 @@ public final class TestTextRun extends TestCase { assertNotNull(runs); assertEquals(4, runs.length); } + + public void test48916() throws IOException { + SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("SampleShow.ppt")); + for(Slide slide : ppt.getSlides()){ + for(Shape sh : slide.getShapes()){ + if(sh instanceof TextShape){ + TextShape tx = (TextShape)sh; + TextRun run = tx.getTextRun(); + //verify that records cached in TextRun and EscherTextboxWrapper are the same + Record[] runChildren = run.getRecords(); + Record[] txboxChildren = tx.getEscherTextboxWrapper().getChildRecords(); + assertEquals(runChildren.length, txboxChildren.length); + for(int i=0; i < txboxChildren.length; i++){ + assertSame(txboxChildren[i], runChildren[i]); + } + //caused NPE prior to fix of Bugzilla #48916 + run.getRichTextRuns()[0].setBold(true); + run.getRichTextRuns()[0].setFontColor(Color.RED); + } + } + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray())); + for(Slide slide : ppt.getSlides()){ + for(Shape sh : slide.getShapes()){ + if(sh instanceof TextShape){ + TextShape tx = (TextShape)sh; + TextRun run = tx.getTextRun(); + RichTextRun rt = run.getRichTextRuns()[0]; + assertTrue(rt.isBold()); + assertEquals(rt.getFontColor(), Color.RED); + } + } + } + + } }