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
This commit is contained in:
Yegor Kozlov 2010-04-03 14:44:39 +00:00
parent 512a6f2bb5
commit 639bf94c6f
7 changed files with 83 additions and 29 deletions

View File

@ -34,6 +34,7 @@
<changes> <changes>
<release version="3.7-SNAPSHOT" date="2010-??-??"> <release version="3.7-SNAPSHOT" date="2010-??-??">
<action dev="POI-DEVELOPERS" type="fix">48916 - Propagate parent to parent-aware records decoded from Escher</action>
<action dev="POI-DEVELOPERS" type="fix">48485 - Add extra paper size constans to PrintSetup, such as A3, B4 and B5</action> <action dev="POI-DEVELOPERS" type="fix">48485 - Add extra paper size constans to PrintSetup, such as A3, B4 and B5</action>
<action dev="POI-DEVELOPERS" type="fix">Make poifs.filesystem.DirectoryNode preserve the original ordering of its files, which HSMF needs to be able to correctly match up chunks</action> <action dev="POI-DEVELOPERS" type="fix">Make poifs.filesystem.DirectoryNode preserve the original ordering of its files, which HSMF needs to be able to correctly match up chunks</action>
<action dev="POI-DEVELOPERS" type="add">Support evaluation of indirect defined names in INDIRECT</action> <action dev="POI-DEVELOPERS" type="add">Support evaluation of indirect defined names in INDIRECT</action>

View File

@ -126,6 +126,9 @@ public abstract class Sheet {
EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers(); EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers();
for (int i = 0; i < wrappers.length; i++) { for (int i = 0; i < wrappers.length; i++) {
int s1 = runsV.size(); int s1 = runsV.size();
// propagate parents to parent-aware records
RecordContainer.handleParentAwareRecords(wrappers[i]);
findTextRuns(wrappers[i].getChildRecords(), runsV); findTextRuns(wrappers[i].getChildRecords(), runsV);
int s2 = runsV.size(); int s2 = runsV.size();
if (s2 != s1){ if (s2 != s1){

View File

@ -140,4 +140,8 @@ public final class SlideMaster extends MasterSheet {
_runs = tmp; _runs = tmp;
} }
} }
public TxMasterStyleAtom[] getTxMasterStyleAtoms(){
return _txmaster;
}
} }

View File

@ -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){ public void draw(Graphics2D graphics){

View File

@ -341,4 +341,23 @@ public abstract class RecordContainer extends Record
out.write(toWrite); 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);
}
}
}
} }

View File

@ -91,13 +91,15 @@ public final class SlideShow {
* @param hslfSlideShow the HSLFSlideShow to base on * @param hslfSlideShow the HSLFSlideShow to base on
*/ */
public SlideShow(HSLFSlideShow hslfSlideShow) { public SlideShow(HSLFSlideShow hslfSlideShow) {
// Get useful things from our base slideshow // Get useful things from our base slideshow
_hslfSlideShow = hslfSlideShow; _hslfSlideShow = hslfSlideShow;
_records = _hslfSlideShow.getRecords(); _records = _hslfSlideShow.getRecords();
// Handle Parent-aware Reocrds // Handle Parent-aware Records
for (int i = 0; i < _records.length; i++) { for (Record record : _records) {
handleParentAwareRecords(_records[i]); if(record instanceof RecordContainer){
RecordContainer.handleParentAwareRecords((RecordContainer)record);
}
} }
// Find the versions of the core records we'll want to use // Find the versions of the core records we'll want to use
@ -121,30 +123,6 @@ public final class SlideShow {
this(new HSLFSlideShow(inputStream)); 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" * 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 * version of all the core records (Document, Notes, Slide etc), and save a

View File

@ -18,11 +18,15 @@
package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; 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.TextBytesAtom;
import org.apache.poi.hslf.record.TextCharsAtom; import org.apache.poi.hslf.record.TextCharsAtom;
import org.apache.poi.hslf.record.TextHeaderAtom; import org.apache.poi.hslf.record.TextHeaderAtom;
@ -490,4 +494,41 @@ public final class TestTextRun extends TestCase {
assertNotNull(runs); assertNotNull(runs);
assertEquals(4, runs.length); 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);
}
}
}
}
} }