Methods Summary |
---|
public int | addPicture(byte[] data, int format)Adds a picture to this presentation and returns the associated index.
byte[] uid = PictureData.getChecksum(data);
EscherContainerRecord bstore;
int offset = 0;
EscherContainerRecord dggContainer = _documentRecord.getPPDrawingGroup().getDggContainer();
bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
if (bstore == null){
bstore = new EscherContainerRecord();
bstore.setRecordId( EscherContainerRecord.BSTORE_CONTAINER);
List child = dggContainer.getChildRecords();
for ( int i = 0; i < child.size(); i++ ) {
EscherRecord rec = (EscherRecord)child.get(i);
if (rec.getRecordId() == EscherOptRecord.RECORD_ID){
child.add(i, bstore);
i++;
}
}
dggContainer.setChildRecords(child);
} else {
List lst = bstore.getChildRecords();
for ( int i = 0; i < lst.size(); i++ ) {
EscherBSERecord bse = (EscherBSERecord) lst.get(i);
if (Arrays.equals(bse.getUid(), uid)){
return i + 1;
}
offset += bse.getSize();
}
}
PictureData pict = PictureData.create(format);
pict.setData(data);
pict.setOffset(offset);
EscherBSERecord bse = new EscherBSERecord();
bse.setRecordId(EscherBSERecord.RECORD_ID);
bse.setOptions( (short) ( 0x0002 | ( format << 4 ) ) );
bse.setSize(pict.getRawData().length + 8);
bse.setUid(uid);
bse.setBlipTypeMacOS((byte)format);
bse.setBlipTypeWin32((byte)format);
if (format == Picture.EMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
else if (format == Picture.WMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
else if (format == Picture.PICT) bse.setBlipTypeWin32((byte)Picture.WMF);
bse.setRef(1);
bse.setOffset(offset);
bstore.addChildRecord(bse);
int count = bstore.getChildRecords().size();
bstore.setOptions((short)( (count << 4) | 0xF ));
_hslfSlideShow.addPicture(pict);
return count;
|
public int | addPicture(java.io.File pict, int format)Adds a picture to this presentation and returns the associated index.
int length = (int)pict.length();
byte[] data = new byte[length];
try {
FileInputStream is = new FileInputStream(pict);
is.read(data);
is.close();
} catch (IOException e){
throw new HSLFException(e);
}
return addPicture(data, format);
|
private void | buildSlidesAndNotes()Build up model level Slide and Notes objects, from the underlying
records.
// Ensure we really found a Document record earlier
// If we didn't, then the file is probably corrupt
if(_documentRecord == null) {
throw new CorruptPowerPointFileException("The PowerPoint file didn't contain a Document Record in its PersistPtr blocks. It is probably corrupt.");
}
// Fetch the SlideListWithTexts in the most up-to-date Document Record
//
// As far as we understand it:
// * The first SlideListWithText will contain a SlideAtomsSet
// for each of the master slides
// * The second SlideListWithText will contain a SlideAtomsSet
// for each of the slides, in their current order
// These SlideAtomsSets will normally contain text
// * The third SlideListWithText (if present), will contain a
// SlideAtomsSet for each Notes
// These SlideAtomsSets will not normally contain text
//
// Having indentified the masters, slides and notes + their orders,
// we have to go and find their matching records
// We always use the latest versions of these records, and use the
// SlideAtom/NotesAtom to match them with the StyleAtomSet
SlideListWithText masterSLWT = _documentRecord.getMasterSlideListWithText();
SlideListWithText slidesSLWT = _documentRecord.getSlideSlideListWithText();
SlideListWithText notesSLWT = _documentRecord.getNotesSlideListWithText();
// Find master slides
// These can be MainMaster records, but oddly they can also be
// Slides or Notes, and possibly even other odd stuff....
// About the only thing you can say is that the master details are in
// the first SLWT.
SlideAtomsSet[] masterSets = new SlideAtomsSet[0];
if (masterSLWT != null){
masterSets = masterSLWT.getSlideAtomsSets();
ArrayList mmr = new ArrayList();
ArrayList tmr = new ArrayList();
for(int i=0; i<masterSets.length; i++) {
Record r = getCoreRecordForSAS(masterSets[i]);
SlideAtomsSet sas = masterSets[i];
int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
if(r instanceof org.apache.poi.hslf.record.Slide) {
TitleMaster master = new TitleMaster((org.apache.poi.hslf.record.Slide)r, sheetNo);
master.setSlideShow(this);
tmr.add(master);
} else if(r instanceof org.apache.poi.hslf.record.MainMaster) {
SlideMaster master = new SlideMaster((org.apache.poi.hslf.record.MainMaster)r, sheetNo);
master.setSlideShow(this);
mmr.add(master);
}
}
_masters = new SlideMaster[mmr.size()];
mmr.toArray(_masters);
_titleMasters = new TitleMaster[tmr.size()];
tmr.toArray(_titleMasters);
}
// Having sorted out the masters, that leaves the notes and slides
// Start by finding the notes records to go with the entries in
// notesSLWT
org.apache.poi.hslf.record.Notes[] notesRecords;
SlideAtomsSet[] notesSets = new SlideAtomsSet[0];
Hashtable slideIdToNotes = new Hashtable();
if(notesSLWT == null) {
// None
notesRecords = new org.apache.poi.hslf.record.Notes[0];
} else {
// Match up the records and the SlideAtomSets
notesSets = notesSLWT.getSlideAtomsSets();
ArrayList notesRecordsL = new ArrayList();
for(int i=0; i<notesSets.length; i++) {
// Get the right core record
Record r = getCoreRecordForSAS(notesSets[i]);
// Ensure it really is a notes record
if(r instanceof org.apache.poi.hslf.record.Notes) {
org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes)r;
notesRecordsL.add( notesRecord );
// Record the match between slide id and these notes
SlidePersistAtom spa = notesSets[i].getSlidePersistAtom();
Integer slideId = new Integer(spa.getSlideIdentifier());
slideIdToNotes.put(slideId, new Integer(i));
} else {
logger.log(POILogger.ERROR, "A Notes SlideAtomSet at " + i + " said its record was at refID " + notesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
}
}
notesRecords = new org.apache.poi.hslf.record.Notes[notesRecordsL.size()];
notesRecords = (org.apache.poi.hslf.record.Notes[])
notesRecordsL.toArray(notesRecords);
}
// Now, do the same thing for our slides
org.apache.poi.hslf.record.Slide[] slidesRecords;
SlideAtomsSet[] slidesSets = new SlideAtomsSet[0];
if(slidesSLWT == null) {
// None
slidesRecords = new org.apache.poi.hslf.record.Slide[0];
} else {
// Match up the records and the SlideAtomSets
slidesSets = slidesSLWT.getSlideAtomsSets();
slidesRecords = new org.apache.poi.hslf.record.Slide[slidesSets.length];
for(int i=0; i<slidesSets.length; i++) {
// Get the right core record
Record r = getCoreRecordForSAS(slidesSets[i]);
// Ensure it really is a slide record
if(r instanceof org.apache.poi.hslf.record.Slide) {
slidesRecords[i] = (org.apache.poi.hslf.record.Slide)r;
} else {
logger.log(POILogger.ERROR, "A Slide SlideAtomSet at " + i + " said its record was at refID " + slidesSets[i].getSlidePersistAtom().getRefID() + ", but that was actually a " + r);
}
}
}
// Finally, generate model objects for everything
// Notes first
_notes = new Notes[notesRecords.length];
for(int i=0; i<_notes.length; i++) {
_notes[i] = new Notes(notesRecords[i]);
_notes[i].setSlideShow(this);
}
// Then slides
_slides = new Slide[slidesRecords.length];
for(int i=0; i<_slides.length; i++) {
SlideAtomsSet sas = slidesSets[i];
int slideIdentifier = sas.getSlidePersistAtom().getSlideIdentifier();
// Do we have a notes for this?
Notes notes = null;
//Slide.SlideAtom.notesId references the corresponding notes slide. 0 if slide has no notes.
int noteId = slidesRecords[i].getSlideAtom().getNotesID();
if (noteId != 0){
Integer notesPos = (Integer)slideIdToNotes.get(new Integer(noteId));
if (notesPos != null) notes = _notes[notesPos.intValue()];
else logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId);
}
// Now, build our slide
_slides[i] = new Slide(slidesRecords[i], notes, sas, slideIdentifier, (i+1));
_slides[i].setSlideShow(this);
}
|
public org.apache.poi.hslf.model.Slide | createSlide()Create a blank Slide .
SlideListWithText slist = null;
// We need to add the records to the SLWT that deals
// with Slides.
// Add it, if it doesn't exist
slist = _documentRecord.getSlideSlideListWithText();
if(slist == null) {
// Need to add a new one
slist = new SlideListWithText();
_documentRecord.addSlideListWithText(slist);
}
// Grab the SlidePersistAtom with the highest Slide Number.
// (Will stay as null if no SlidePersistAtom exists yet in
// the slide, or only master slide's ones do)
SlidePersistAtom prev = null;
SlideAtomsSet[] sas = slist.getSlideAtomsSets();
for(int j=0; j<sas.length; j++) {
SlidePersistAtom spa = sas[j].getSlidePersistAtom();
if(spa.getSlideIdentifier() < 0) {
// This is for a master slide
// Odd, since we only deal with the Slide SLWT
} else {
// Must be for a real slide
if(prev == null) { prev = spa; }
if(prev.getSlideIdentifier() < spa.getSlideIdentifier()) {
prev = spa;
}
}
}
// Set up a new SlidePersistAtom for this slide
SlidePersistAtom sp = new SlidePersistAtom();
// Reference is the 1-based index of the slide container in
// the PersistPtr root.
// It always starts with 3 (1 is Document, 2 is MainMaster, 3 is
// the first slide), but quicksaves etc can leave gaps
_highestSheetId++;
sp.setRefID(_highestSheetId);
// First slideId is always 256
sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1));
// Add this new SlidePersistAtom to the SlideListWithText
slist.addSlidePersistAtom(sp);
// Create a new Slide
Slide slide = new Slide(sp.getSlideIdentifier(), sp.getRefID(), _slides.length+1);
// Add in to the list of Slides
Slide[] s = new Slide[_slides.length+1];
System.arraycopy(_slides, 0, s, 0, _slides.length);
s[_slides.length] = slide;
_slides = s;
logger.log(POILogger.INFO, "Added slide " + _slides.length + " with ref " + sp.getRefID() + " and identifier " + sp.getSlideIdentifier());
// Add the core records for this new Slide to the record tree
org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
slideRecord.setSheetId(sp.getRefID());
int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
_records = _hslfSlideShow.getRecords();
// Add the new Slide into the PersistPtr stuff
int offset = 0;
int slideOffset = 0;
PersistPtrHolder ptr = null;
UserEditAtom usr = null;
for (int i = 0; i < _records.length; i++) {
Record record = _records[i];
ByteArrayOutputStream out = new ByteArrayOutputStream();
record.writeOut(out);
// Grab interesting records as they come past
if(_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID){
ptr = (PersistPtrHolder)_records[i];
}
if(_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) {
usr = (UserEditAtom)_records[i];
}
if(i == slideRecordPos) {
slideOffset = offset;
}
offset += out.size();
}
// Add the new slide into the last PersistPtr
// (Also need to tell it where it is)
slideRecord.setLastOnDiskOffset(slideOffset);
ptr.addSlideLookup(sp.getRefID(), slideOffset);
logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
// Last view is now of the slide
usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
// All done and added
slide.setSlideShow(this);
return slide;
|
private void | findMostRecentCoreRecords()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 record of them.
Do this by walking from the oldest PersistPtr to the newest,
overwriting any references found along the way with newer ones
// To start with, find the most recent in the byte offset domain
Hashtable mostRecentByBytes = new Hashtable();
for(int i=0; i<_records.length; i++) {
if(_records[i] instanceof PersistPtrHolder) {
PersistPtrHolder pph = (PersistPtrHolder)_records[i];
// If we've already seen any of the "slide" IDs for this
// PersistPtr, remove their old positions
int[] ids = pph.getKnownSlideIDs();
for(int j=0; j<ids.length; j++) {
Integer id = new Integer(ids[j]);
if( mostRecentByBytes.containsKey(id)) {
mostRecentByBytes.remove(id);
}
}
// Now, update the byte level locations with their latest values
Hashtable thisSetOfLocations = pph.getSlideLocationsLookup();
for(int j=0; j<ids.length; j++) {
Integer id = new Integer(ids[j]);
mostRecentByBytes.put(id, thisSetOfLocations.get(id));
}
}
}
// We now know how many unique special records we have, so init
// the array
_mostRecentCoreRecords = new Record[mostRecentByBytes.size()];
// We'll also want to be able to turn the slide IDs into a position
// in this array
_sheetIdToCoreRecordsLookup = new Hashtable();
int[] allIDs = new int[_mostRecentCoreRecords.length];
Enumeration ids = mostRecentByBytes.keys();
for(int i=0; i<allIDs.length; i++) {
Integer id = (Integer)ids.nextElement();
allIDs[i] = id.intValue();
}
Arrays.sort(allIDs);
for(int i=0; i<allIDs.length; i++) {
_sheetIdToCoreRecordsLookup.put(new Integer(allIDs[i]), new Integer(i));
}
// Capture the ID of the highest sheet
_highestSheetId = allIDs[(allIDs.length-1)];
// Now convert the byte offsets back into record offsets
for(int i=0; i<_records.length; i++) {
if(_records[i] instanceof PositionDependentRecord) {
PositionDependentRecord pdr = (PositionDependentRecord)_records[i];
Integer recordAt = new Integer(pdr.getLastOnDiskOffset());
// Is it one we care about?
for(int j=0; j<allIDs.length; j++) {
Integer thisID = new Integer(allIDs[j]);
Integer thatRecordAt = (Integer)mostRecentByBytes.get(thisID);
if(thatRecordAt.equals(recordAt)) {
// Bingo. Now, where do we store it?
Integer storeAtI =
(Integer)_sheetIdToCoreRecordsLookup.get(thisID);
int storeAt = storeAtI.intValue();
// Tell it its Sheet ID, if it cares
if(pdr instanceof PositionDependentRecordContainer) {
PositionDependentRecordContainer pdrc =
(PositionDependentRecordContainer)_records[i];
pdrc.setSheetId(thisID.intValue());
}
// Finally, save the record
_mostRecentCoreRecords[storeAt] = _records[i];
}
}
}
}
// Now look for the interesting records in there
for(int i=0; i<_mostRecentCoreRecords.length; i++) {
// Check there really is a record at this number
if(_mostRecentCoreRecords[i] != null) {
// Find the Document, and interesting things in it
if(_mostRecentCoreRecords[i].getRecordType() == RecordTypes.Document.typeID) {
_documentRecord = (Document)_mostRecentCoreRecords[i];
_fonts = _documentRecord.getEnvironment().getFontCollection();
}
} else {
// No record at this number
// Odd, but not normally a problem
}
}
|
private org.apache.poi.hslf.record.Record | getCoreRecordForRefID(int refID)For a given refID (the internal, 0 based numbering scheme), return the
core record
Integer coreRecordId = (Integer)
_sheetIdToCoreRecordsLookup.get(new Integer(refID));
if(coreRecordId != null) {
Record r = _mostRecentCoreRecords[coreRecordId.intValue()];
return r;
} else {
logger.log(POILogger.ERROR, "We tried to look up a reference to a core record, but there was no core ID for reference ID " + refID);
return null;
}
|
private org.apache.poi.hslf.record.Record | getCoreRecordForSAS(SlideAtomsSet sas)For a given SlideAtomsSet, return the core record, based on the refID from the
SlidePersistAtom
SlidePersistAtom spa = sas.getSlidePersistAtom();
int refID = spa.getRefID();
return getCoreRecordForRefID(refID);
|
public org.apache.poi.hslf.record.Document | getDocumentRecord()Helper method for usermodel and model: Get the document record return _documentRecord;
|
protected org.apache.poi.hslf.record.FontCollection | getFontCollection()Helper method for usermodel: Get the font collection return _fonts;
|
public org.apache.poi.hslf.record.Record[] | getMostRecentCoreRecords()Returns an array of the most recent version of all the interesting
records return _mostRecentCoreRecords;
|
public org.apache.poi.hslf.model.Notes[] | getNotes()Returns an array of all the normal Notes found in the slideshow return _notes;
|
public java.awt.Dimension | getPageSize()Return the current page size
DocumentAtom docatom = _documentRecord.getDocumentAtom();
int pgx = (int)docatom.getSlideSizeX()*Shape.POINT_DPI/Shape.MASTER_DPI;
int pgy = (int)docatom.getSlideSizeY()*Shape.POINT_DPI/Shape.MASTER_DPI;
return new Dimension(pgx, pgy);
|
public org.apache.poi.hslf.usermodel.PictureData[] | getPictureData()Returns the data of all the pictures attached to the SlideShow
return _hslfSlideShow.getPictures();
|
public org.apache.poi.hslf.model.Slide[] | getSlides()Returns an array of all the normal Slides found in the slideshow return _slides;
|
public org.apache.poi.hslf.model.SlideMaster[] | getSlidesMasters()Returns an array of all the normal Slide Masters found in the slideshow return _masters;
|
public org.apache.poi.hslf.model.TitleMaster[] | getTitleMasters()Returns an array of all the normal Title Masters found in the slideshow return _titleMasters;
|
private void | handleParentAwareRecords(org.apache.poi.hslf.record.Record baseRecord)Find the records that are parent-aware, and tell them
who their parent is
// 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);
}
}
}
|
public void | reorderSlide(int oldSlideNumer, int newSlideNumber)Re-orders a slide, to a new position.
// Ensure these numbers are valid
if(oldSlideNumer < 1 || newSlideNumber < 1) {
throw new IllegalArgumentException("Old and new slide numbers must be greater than 0");
}
if(oldSlideNumer > _slides.length || newSlideNumber > _slides.length) {
throw new IllegalArgumentException("Old and new slide numbers must not exceed the number of slides (" + _slides.length + ")");
}
// Shift the SlideAtomsSet
SlideListWithText slwt = _documentRecord.getSlideSlideListWithText();
slwt.repositionSlideAtomsSet(
slwt.getSlideAtomsSets()[(oldSlideNumer-1)],
(newSlideNumber-1)
);
// Re-order the slides
ArrayUtil.arrayMoveWithin(_slides, (oldSlideNumer-1), (newSlideNumber-1), 1);
// Tell the appropriate slides their new numbers
for(int i=0; i<_slides.length; i++) {
_slides[i].setSlideNumber( (i+1) );
}
|
public void | setPageSize(java.awt.Dimension pgsize)Change the current page size
DocumentAtom docatom = _documentRecord.getDocumentAtom();
docatom.setSlideSizeX(pgsize.width*Shape.MASTER_DPI/Shape.POINT_DPI);
docatom.setSlideSizeY(pgsize.height*Shape.MASTER_DPI/Shape.POINT_DPI);
|
public void | write(java.io.OutputStream out)Writes out the slideshow file the is represented by an instance of
this class
_hslfSlideShow.write(out);
|