Fix for adding multiple slides

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@388929 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2006-03-26 17:37:04 +00:00
parent 4043f63b47
commit 85b8807855
4 changed files with 72 additions and 30 deletions

View File

@ -71,7 +71,7 @@ public class Document extends PositionDependentRecordContainer
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
// Our first one should be a document atom
if(! (_children[0] instanceof DocumentAtom)) {
throw new IllegalStateException("The first child of a Document must be a DocumentAtom");
@ -102,6 +102,28 @@ public class Document extends PositionDependentRecordContainer
}
}
}
/**
* Adds a new SlideListWithText record, at the appropriate
* point
*/
public void addSlideListWithText(SlideListWithText slwt) {
// The new SlideListWithText should go in
// just before the EndDocumentRecord
Record endDoc = _children[_children.length - 1];
if(endDoc.getRecordType() != RecordTypes.EndDocument.typeID) {
throw new IllegalStateException("The last child record of a Document should be EndDocument, but it was " + endDoc);
}
// Add in the record
addChildBefore(slwt, endDoc);
// Updated our cached list of SlideListWithText records
SlideListWithText[] nl = new SlideListWithText[slwts.length + 1];
System.arraycopy(slwts, 0, nl, 0, slwts.length);
nl[nl.length-1] = slwt;
slwts = nl;
}
/**

View File

@ -90,11 +90,17 @@ public class PersistPtrHolder extends PositionDependentRecordAtom
* For now, won't look for the most optimal on disk representation.
*/
public void addSlideLookup(int slideID, int posOnDisk) {
// PtrData grows by 8 bytes:
// 4 bytes for the new info block
// 4 bytes for the slide offset
byte[] newPtrData = new byte[_ptrData.length + 8];
System.arraycopy(_ptrData,0,newPtrData,0,_ptrData.length);
// Add to the lookup hash
// Add to the slide location lookup hash
_slideLocations.put(new Integer(slideID), new Integer(posOnDisk));
// Add to the ptrData offset lookup hash
_slideOffsetDataLocation.put(new Integer(slideID),
new Integer(_ptrData.length + 4));
// Build the info block
// First 20 bits = offset number = slide ID
@ -111,10 +117,6 @@ public class PersistPtrHolder extends PositionDependentRecordAtom
// Update the atom header
LittleEndian.putInt(_header,4,newPtrData.length);
// Update info (first 4 bytes in ptr data)
int info = (slideID << 20 | 1);
LittleEndian.putInt(_ptrData, 0, info);
}
/**

View File

@ -19,7 +19,6 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hslf.model.Sheet;
import java.io.IOException;
import java.io.OutputStream;
@ -106,7 +105,27 @@ public class SlideListWithText extends RecordContainer
LittleEndian.putUShort(_header, 2, (int)_type);
LittleEndian.putInt(_header, 4, 0);
// We have no children to start with
_children = new Record[0];
slideAtomsSets = new SlideAtomsSet[0];
}
/**
* Add a new SlidePersistAtom, to the end of the current list,
* and update the internal list of SlidePersistAtoms
* @param spa
*/
public void addSlidePersistAtom(SlidePersistAtom spa) {
// Add the new SlidePersistAtom at the end
appendChildRecord(spa);
SlideAtomsSet newSAS = new SlideAtomsSet(spa, new Record[0]);
// Update our SlideAtomsSets with this
SlideAtomsSet[] sas = new SlideAtomsSet[slideAtomsSets.length+1];
System.arraycopy(slideAtomsSets, 0, sas, 0, slideAtomsSets.length);
sas[sas.length-1] = newSAS;
slideAtomsSets = sas;
}
/**

View File

@ -476,24 +476,27 @@ public class SlideShow
} else {
// Need to add a new one
slist = new SlideListWithText();
// Goes in just before the EndDocumentRecord
Record[] docChildren = _documentRecord.getChildRecords();
Record endDoc = docChildren[docChildren.length - 1];
if(endDoc.getRecordType() != RecordTypes.EndDocument.typeID) {
throw new IllegalStateException("The last child record of a Document should be EndDocument, but it was " + endDoc);
}
_documentRecord.addChildBefore(slist, endDoc);
_documentRecord.addSlideListWithText(slist);
slwts = _documentRecord.getSlideListWithTexts();
}
// Grab the last SlidePersistAtom, if there was one
// Grab the SlidePersistAtom with the highest Slide Number.
// (Will stay as null if no SlidePersistAtom exists yet in
// the slide)
SlidePersistAtom prev = null;
SlideAtomsSet[] sas = slist.getSlideAtomsSets();
if(sas != null && sas.length > 0) {
prev = sas[sas.length - 1].getSlidePersistAtom();
for(int i=0; i<slwts.length; i++) {
SlideAtomsSet[] sas = slwts[i].getSlideAtomsSets();
for(int j=0; j<sas.length; j++) {
SlidePersistAtom spa = sas[j].getSlidePersistAtom();
if(prev == null) { prev = spa; }
if(prev.getSlideIdentifier() < spa.getSlideIdentifier()) {
prev = spa;
}
System.err.println("Prev is " + prev.getRefID());
}
}
// Add a new SlidePersistAtom
// Set up a new SlidePersistAtom for this slide
SlidePersistAtom sp = new SlidePersistAtom();
// Refernce is the 1-based index of the slide container in
@ -505,7 +508,8 @@ public class SlideShow
sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1));
// Add this new SlidePersistAtom to the SlideListWithText
slist.appendChildRecord(sp);
slist.addSlidePersistAtom(sp);
// Create a new Slide
Slide slide = new Slide();
@ -515,9 +519,10 @@ public class SlideShow
_slides = s;
System.out.println("Added slide " + _slides.length + " with ref " + sp.getRefID() + " and identifier " + sp.getSlideIdentifier());
// Add in to the core records
// Add the core records for this new Slide to the record tree
org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
_records = _hslfSlideShow.getRecords();
// Add the new Slide into the PersistPtr stuff
int offset = 0;
@ -544,15 +549,9 @@ public class SlideShow
}
// Add the new slide into the last PersistPtr
// (Also need to tell it where it is)
slideRecord.setLastOnDiskOffset(slideOffset);
int id = sp.getRefID();
ptr.getSlideOffsetDataLocationsLookup().put(
new Integer(id),
new Integer((slideRecordPos+1)*4)
);
ptr.getSlideLocationsLookup().put(
new Integer(id), new Integer(slideOffset));
ptr.addSlideLookup(id, slideOffset);
ptr.addSlideLookup(sp.getRefID(), slideOffset);
System.out.println("New slide ended up at " + slideOffset);
// Last view is now of the slide