Big change in how we tie slides, notes, and their text together. Now make use of the RefID and SlideIndentifier values to pull everything together

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@389286 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2006-03-27 21:35:37 +00:00
parent 061f6f3f7e
commit 9329c11565
7 changed files with 195 additions and 139 deletions

View File

@ -163,7 +163,7 @@ public class PowerPointExtractor
for(int i=0; i<_slides.length; i++) { for(int i=0; i<_slides.length; i++) {
Notes notes = _slides[i].getNotesSheet(); Notes notes = _slides[i].getNotesSheet();
if(notes == null) { continue; } if(notes == null) { continue; }
Integer id = new Integer(notes.getSheetNumber()); Integer id = new Integer(notes._getSheetNumber());
if(seenNotes.contains(id)) { continue; } if(seenNotes.contains(id)) { continue; }
seenNotes.add(id); seenNotes.add(id);

View File

@ -31,7 +31,7 @@ import org.apache.poi.hslf.record.PPDrawing;
public class Notes extends Sheet public class Notes extends Sheet
{ {
private int _sheetNo; private int _refSheetNo;
private int _slideNo; private int _slideNo;
private org.apache.poi.hslf.record.Notes _notes; private org.apache.poi.hslf.record.Notes _notes;
private TextRun[] _runs; private TextRun[] _runs;
@ -46,7 +46,7 @@ public class Notes extends Sheet
_notes = notes; _notes = notes;
// Grab our internal sheet ID // Grab our internal sheet ID
_sheetNo = notes.getSheetId(); _refSheetNo = notes.getSheetId();
// Grab the number of the slide we're for, via the NotesAtom // Grab the number of the slide we're for, via the NotesAtom
_slideNo = _notes.getNotesAtom().getSlideID(); _slideNo = _notes.getNotesAtom().getSlideID();
@ -66,13 +66,14 @@ public class Notes extends Sheet
public TextRun[] getTextRuns() { return _runs; } public TextRun[] getTextRuns() { return _runs; }
/** /**
* Returns the (internal, RefId based) sheet number (RefId) * Returns the (internal, RefID based) sheet number, as used
* to in PersistPtr stuff.
*/ */
public int getSheetNumber() { return _sheetNo; } public int _getSheetRefId() { return _refSheetNo; }
/** /**
* Returns the (internal, identifer based) number of the slide we're attached to * Returns the (internal, SlideIdentifer based) number of the
* slide we're attached to
*/ */
public int getSlideInternalNumber() { return _slideNo; } public int _getSheetNumber() { return _slideNo; }
protected PPDrawing getPPDrawing() { return _notes.getPPDrawing(); }} protected PPDrawing getPPDrawing() { return _notes.getPPDrawing(); }}

View File

@ -45,9 +45,15 @@ public abstract class Sheet
/** /**
* Returns the (internal, RefID based) sheet number, as used * Returns the (internal, RefID based) sheet number, as used
* to in PersistPtr stuff.
*/
public abstract int _getSheetRefId();
/**
* Returns the (internal, SlideIdentifier based) sheet number, as used
* to reference this sheet from other records. * to reference this sheet from other records.
*/ */
public abstract int getSheetNumber(); public abstract int _getSheetNumber();
/** /**
* Fetch the PPDrawing from the underlying record * Fetch the PPDrawing from the underlying record

View File

@ -35,7 +35,7 @@ import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
public class Slide extends Sheet public class Slide extends Sheet
{ {
private int _refSheetNo;
private int _sheetNo; private int _sheetNo;
private int _slideNo; private int _slideNo;
private org.apache.poi.hslf.record.Slide _slide; private org.apache.poi.hslf.record.Slide _slide;
@ -53,11 +53,12 @@ public class Slide extends Sheet
* @param notes the Notes sheet attached to us * @param notes the Notes sheet attached to us
* @param atomSet the SlideAtomsSet to get the text from * @param atomSet the SlideAtomsSet to get the text from
*/ */
public Slide(org.apache.poi.hslf.record.Slide slide, Notes notes, SlideAtomsSet atomSet, int slideNumber) { public Slide(org.apache.poi.hslf.record.Slide slide, Notes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
_slide = slide; _slide = slide;
_notes = notes; _notes = notes;
_atomSet = atomSet; _atomSet = atomSet;
_sheetNo = slide.getSheetId(); _refSheetNo = slide.getSheetId();
_sheetNo = slideIdentifier;
_slideNo = slideNumber; _slideNo = slideNumber;
// Grab the TextRuns from the PPDrawing // Grab the TextRuns from the PPDrawing
@ -91,8 +92,9 @@ public class Slide extends Sheet
* @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder * @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder
* @param slideNumber The user facing number of the sheet * @param slideNumber The user facing number of the sheet
*/ */
public Slide(int sheetNumber, int slideNumber){ public Slide(int sheetNumber, int sheetRefId, int slideNumber){
_slide = new org.apache.poi.hslf.record.Slide(); _slide = new org.apache.poi.hslf.record.Slide();
_refSheetNo = sheetRefId;
_sheetNo = sheetNumber; _sheetNo = sheetNumber;
_slideNo = slideNumber; _slideNo = slideNumber;
} }
@ -112,7 +114,7 @@ public class Slide extends Sheet
sa.setNotesID(0); sa.setNotesID(0);
} else { } else {
// Set to the value from the notes' sheet id // Set to the value from the notes' sheet id
sa.setNotesID(notes.getSheetNumber()); sa.setNotesID(notes._getSheetNumber());
} }
} }
@ -125,10 +127,15 @@ public class Slide extends Sheet
public TextRun[] getTextRuns() { return _runs; } public TextRun[] getTextRuns() { return _runs; }
/** /**
* Returns the (internal, RefId based) sheet number * Returns the (internal, RefID based) sheet number, as used
* to in PersistPtr stuff.
*/
public int _getSheetRefId() { return _refSheetNo; }
/**
* Returns the (internal, SlideIdentifier based) sheet number
* @see getSlideNumber() * @see getSlideNumber()
*/ */
public int getSheetNumber() { return _sheetNo; } public int _getSheetNumber() { return _sheetNo; }
/** /**
* Returns the (public facing) page number of this slide * Returns the (public facing) page number of this slide

View File

@ -130,7 +130,8 @@ public class TextRun
} }
} }
if(pLenRemain < 0) { if(pLenRemain < 0) {
throw new IllegalStateException("Paragraph style ran out before character style did!"); System.err.println("Paragraph style ran out before character style did! Short by " + (0-pLenRemain) + " characters.");
System.err.println("Calling RichTextRun functions is likely to break things - see Bug #38544");
} }
} }
} }

View File

@ -76,9 +76,12 @@ public class SlideListWithText extends RecordContainer
endPos += 1; endPos += 1;
} }
// Now, if not empty, create a SlideAtomsSets
int clen = endPos - i - 1; int clen = endPos - i - 1;
if(clen == 0) { continue; } boolean emptySet = false;
if(clen == 0) { emptySet = true; }
// Create a SlideAtomsSets, not caring if they're empty
//if(emptySet) { continue; }
Record[] spaChildren = new Record[clen]; Record[] spaChildren = new Record[clen];
System.arraycopy(_children,i+1,spaChildren,0,clen); System.arraycopy(_children,i+1,spaChildren,0,clen);
SlideAtomsSet set = new SlideAtomsSet((SlidePersistAtom)_children[i],spaChildren); SlideAtomsSet set = new SlideAtomsSet((SlidePersistAtom)_children[i],spaChildren);

View File

@ -69,6 +69,11 @@ public class SlideShow
// Pointers to the most recent versions of the core records // Pointers to the most recent versions of the core records
// (Document, Notes, Slide etc) // (Document, Notes, Slide etc)
private Record[] _mostRecentCoreRecords; private Record[] _mostRecentCoreRecords;
// Lookup between the PersitPtr "sheet" IDs, and the position
// in the mostRecentCoreRecords array
private Hashtable _sheetIdToCoreRecordsLookup;
// Used when adding new core records
private int _highestSheetId;
// Records that are interesting // Records that are interesting
private Document _documentRecord; private Document _documentRecord;
@ -181,8 +186,9 @@ public class SlideShow
// the array // the array
_mostRecentCoreRecords = new Record[mostRecentByBytes.size()]; _mostRecentCoreRecords = new Record[mostRecentByBytes.size()];
// Also, work out where we're going to put them in the array // We'll also want to be able to turn the slide IDs into a position
Hashtable slideIDtoRecordLookup = new Hashtable(); // in this array
_sheetIdToCoreRecordsLookup = new Hashtable();
int[] allIDs = new int[_mostRecentCoreRecords.length]; int[] allIDs = new int[_mostRecentCoreRecords.length];
Enumeration ids = mostRecentByBytes.keys(); Enumeration ids = mostRecentByBytes.keys();
for(int i=0; i<allIDs.length; i++) { for(int i=0; i<allIDs.length; i++) {
@ -191,8 +197,10 @@ public class SlideShow
} }
Arrays.sort(allIDs); Arrays.sort(allIDs);
for(int i=0; i<allIDs.length; i++) { for(int i=0; i<allIDs.length; i++) {
slideIDtoRecordLookup.put(new Integer(allIDs[i]), new Integer(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 // Now convert the byte offsets back into record offsets
for(int i=0; i<_records.length; i++) { for(int i=0; i<_records.length; i++) {
@ -208,11 +216,10 @@ public class SlideShow
if(thatRecordAt.equals(recordAt)) { if(thatRecordAt.equals(recordAt)) {
// Bingo. Now, where do we store it? // Bingo. Now, where do we store it?
Integer storeAtI = Integer storeAtI =
(Integer)slideIDtoRecordLookup.get(thisID); (Integer)_sheetIdToCoreRecordsLookup.get(thisID);
int storeAt = storeAtI.intValue(); int storeAt = storeAtI.intValue();
// Tell it its Sheet ID, if it cares // Tell it its Sheet ID, if it cares
// TODO: Check that this is the right ID to feed in
if(pdr instanceof PositionDependentRecordContainer) { if(pdr instanceof PositionDependentRecordContainer) {
PositionDependentRecordContainer pdrc = PositionDependentRecordContainer pdrc =
(PositionDependentRecordContainer)_records[i]; (PositionDependentRecordContainer)_records[i];
@ -228,11 +235,16 @@ public class SlideShow
// Now look for the interesting records in there // Now look for the interesting records in there
for(int i=0; i<_mostRecentCoreRecords.length; i++) { 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 // Find the Document, and interesting things in it
if(_mostRecentCoreRecords[i].getRecordType() == RecordTypes.Document.typeID) { if(_mostRecentCoreRecords[i].getRecordType() == RecordTypes.Document.typeID) {
_documentRecord = (Document)_mostRecentCoreRecords[i]; _documentRecord = (Document)_mostRecentCoreRecords[i];
_fonts = _documentRecord.getEnvironment().getFontCollection(); _fonts = _documentRecord.getEnvironment().getFontCollection();
} }
} else {
System.err.println("No core record found with ID " + (i+1) + " based on PersistPtr lookup");
}
} }
} }
@ -247,18 +259,6 @@ public class SlideShow
Vector notesV = new Vector(10); Vector notesV = new Vector(10);
// For holding the Meta Sheet Records // For holding the Meta Sheet Records
Vector metaSheetsV = new Vector(10); Vector metaSheetsV = new Vector(10);
// For holding SlideListWithText Records
Vector slwtV = new Vector(10);
// Look for Notes, Slides and Documents
for(int i=0; i<_mostRecentCoreRecords.length; i++) {
if(_mostRecentCoreRecords[i] instanceof org.apache.poi.hslf.record.Notes) {
notesV.add(_mostRecentCoreRecords[i]);
}
if(_mostRecentCoreRecords[i] instanceof org.apache.poi.hslf.record.Slide) {
slidesV.add(_mostRecentCoreRecords[i]);
}
}
// Ensure we really found a Document record earlier // Ensure we really found a Document record earlier
// If we didn't, then the file is probably corrupt // If we didn't, then the file is probably corrupt
@ -269,82 +269,138 @@ public class SlideShow
// Fetch the SlideListWithTexts in the most up-to-date Document Record // Fetch the SlideListWithTexts in the most up-to-date Document Record
// //
// Need to get the SlideAtomsSets for all of these. Then, query the // Then, use this to find the Slide records, and also the Notes record
// SlidePersistAtom, and group stuff together between SLWT blocks // for each Slide (if it has one)
// based on the refID/slideID
// //
// If a notes sheet exists, can normally match the Notes sheet ID // The following matching algorithm is based on looking at the output
// to the slide ID in the SlidePersistAtom. Since there isn't always, // of org.apache.poi.hslf.dev.SlideIdListing on a number of files:
// and we can't find the ID in the slide, just order on the slide ID,
// and hand off to the Slides in turn.
// (Based on output from dev.SLWTTextListing and dev.SlideAndNotesAtomListing)
// //
// We're trusting that the ordering of slides from the persistence // 1) Get the SlideAtomSets from the SlideListWithTexts of the most
// layer will match the ordering found here. However, we should // up-to-date Document
// really find a PPT file with random sheets inserted to check with // 2) Get the SlidePersistAtoms from all of these
// // 3) Get the RefId, which corresponds to a "sheet ID" from the
// There shouldn't be any text duplication - only using the most // PersistPtr Stuff
// record Document record's SLWTs should see to that // 4) Grab the record at that ID, and see if it's a slide or a notes
// 5) Build a mapping between the SlideIdentifier ID and the RefId
// for both slides and notes
// 6) Loop over all the slides
// 7) Look each slide's SlideAtom to see if it has associated Notes -
// if it does, the ID will be SlideIdentifier for those notes
// (Note: might not be the same as the SlideIdentifier of the Slide)
// 8) Generate the model representations, giving them the matching
// slide atom sets, IDs etc
SlideListWithText[] slwts = _documentRecord.getSlideListWithTexts(); SlideListWithText[] slwts = _documentRecord.getSlideListWithTexts();
// To hold the lookup from SlideIdentifier IDs to RefIDs
Hashtable slideSlideIdToRefid = new Hashtable();
Hashtable notesSlideIdToRefid = new Hashtable();
// To hold the lookup from SlideIdentifier IDs to SlideAtomsSets
Hashtable slideSlideIdToSlideAtomsSet = new Hashtable();
Hashtable notesSlideIdToSlideAtomsSet = new Hashtable();
// Loop over all the SlideListWithTexts, getting their
// SlideAtomSets
for(int i=0; i<slwts.length; i++) { for(int i=0; i<slwts.length; i++) {
slwtV.add(slwts[i]); SlideAtomsSet[] sas = slwts[i].getSlideAtomsSets();
} for(int j=0; j<sas.length; j++) {
// What does this SlidePersistAtom point to?
SlidePersistAtom spa = sas[j].getSlidePersistAtom();
Integer slideIdentifier = new Integer( spa.getSlideIdentifier() );
Integer slideRefId = new Integer( spa.getRefID() );
// For now, grab out all the sets of Atoms in the SlideListWithText's // Grab the record it points to
// Only store those which aren't empty Integer coreRecordId = (Integer)
// Also, get the list of IDs while we're at it _sheetIdToCoreRecordsLookup.get(slideRefId);
HashSet uniqueSlideIDs = new HashSet(); Record r = _mostRecentCoreRecords[coreRecordId.intValue()];
Vector setsV = new Vector();
for(int i=0; i<slwtV.size(); i++) {
SlideListWithText slwt = (SlideListWithText)slwtV.get(i);
SlideAtomsSet[] thisSets = slwt.getSlideAtomsSets();
for(int j=0; j<thisSets.length; j++) {
SlideAtomsSet thisSet = thisSets[j];
setsV.add(thisSet);
int id = thisSet.getSlidePersistAtom().getSlideIdentifier(); // Add the IDs to the appropriate lookups
Integer idI = new Integer(id); if(r instanceof org.apache.poi.hslf.record.Slide) {
if(! uniqueSlideIDs.contains(idI) ) { slideSlideIdToRefid.put( slideIdentifier, slideRefId );
uniqueSlideIDs.add(idI); // Save the SlideAtomsSet
slideSlideIdToSlideAtomsSet.put( slideIdentifier, sas[j] );
} else if(r instanceof org.apache.poi.hslf.record.Notes) {
notesSlideIdToRefid.put( slideIdentifier, slideRefId );
// Save the SlideAtomsSet
notesSlideIdToSlideAtomsSet.put( slideIdentifier, sas[j] );
} else if(r.getRecordType() == RecordTypes.MainMaster.typeID) {
// Skip for now, we don't do Master slides yet
} else { } else {
System.err.println("** WARNING - Found two SlideAtomsSets for a given slide (" + id + ") - only using the first one **"); throw new IllegalStateException("SlidePersistAtom had a RefId that pointed to something other than a Slide or a Notes, was a " + r + " with type " + r.getRecordType());
} }
} }
} }
// Now, create a model representation of a slide for each
// Now, order the SlideAtomSets by their slide's ID // slide + slideatomset we found
int[] slideIDs = new int[uniqueSlideIDs.size()]; // Do it in order of the SlideIdentifiers
int[] slideIDs = new int[slideSlideIdToRefid.size()];
int pos = 0; int pos = 0;
for(Iterator getIDs = uniqueSlideIDs.iterator(); getIDs.hasNext(); pos++) { Enumeration e = slideSlideIdToRefid.keys();
Integer id = (Integer)getIDs.next(); while(e.hasMoreElements()) {
Integer id = (Integer)e.nextElement();
slideIDs[pos] = id.intValue(); slideIDs[pos] = id.intValue();
pos++;
} }
// Sort // Sort
Arrays.sort(slideIDs); Arrays.sort(slideIDs);
// Group
SlideAtomsSet[] slideAtomSets = new SlideAtomsSet[slideIDs.length]; // Create
for(int i=0; i<setsV.size(); i++) { for(int i=0; i<slideIDs.length; i++) {
SlideAtomsSet thisSet = (SlideAtomsSet)setsV.get(i); // Build up the list of all the IDs we might want to use
int id = thisSet.getSlidePersistAtom().getSlideIdentifier(); int slideIdentifier = slideIDs[i];
int arrayPos = -1; Integer slideIdentifierI = new Integer(slideIdentifier);
for(int j=0; j<slideIDs.length; j++) { int slideNumber = (i+1);
if(slideIDs[j] == id) { arrayPos = j; } Integer slideRefI = (Integer)slideSlideIdToRefid.get(slideIdentifierI);
} Integer slideCoreRecNumI = (Integer)_sheetIdToCoreRecordsLookup.get(slideRefI);
slideAtomSets[arrayPos] = thisSet; int slideCoreRecNum = slideCoreRecNumI.intValue();
// Fetch the Slide record
org.apache.poi.hslf.record.Slide s = (org.apache.poi.hslf.record.Slide)
_mostRecentCoreRecords[slideCoreRecNum];
// Do we have a notes for this slide?
org.apache.poi.hslf.record.Notes n = null;
if(s.getSlideAtom().getNotesID() > 0) {
// Get the SlideIdentifier of the Notes
// (Note - might not be the same as the SlideIdentifier of the Slide)
int notesSlideIdentifier = s.getSlideAtom().getNotesID();
Integer notesSlideIdentifierI = new Integer(notesSlideIdentifier);
// Grab the notes record
Integer notesRefI = (Integer)notesSlideIdToRefid.get(notesSlideIdentifierI);
Integer notesCoreRecNum = (Integer)_sheetIdToCoreRecordsLookup.get(notesRefI);
n = (org.apache.poi.hslf.record.Notes)
_mostRecentCoreRecords[notesCoreRecNum.intValue()];
} }
// Grab the matching SlideAtomSet
SlideAtomsSet sas = (SlideAtomsSet)
slideSlideIdToSlideAtomsSet.get(slideIdentifierI);
// Build the notes model, if there's notes
Notes notes = null;
if(n != null) {
// TODO: Use this
SlideAtomsSet nsas = (SlideAtomsSet)
notesSlideIdToSlideAtomsSet.get(slideIdentifierI);
// ******************* Do the real model layer creation **************** // Create the model view of the notes
notes = new Notes(n);
notesV.add(notes);
}
// Build the slide model
Slide slide = new Slide(s, notes, sas, slideIdentifier, slideNumber);
slidesV.add(slide);
}
// Create our Notes // ******************* Finish up ****************
// (Need to create first, as passed to the Slides)
// Finish setting up the notes
_notes = new Notes[notesV.size()]; _notes = new Notes[notesV.size()];
for(int i=0; i<_notes.length; i++) { for(int i=0; i<_notes.length; i++) {
_notes[i] = new Notes((org.apache.poi.hslf.record.Notes)notesV.get(i)); _notes[i] = (Notes)notesV.get(i);
// Now supply ourselves to all the rich text runs // Now supply ourselves to all the rich text runs
// of this note's TextRuns // of this note's TextRuns
@ -361,31 +417,7 @@ public class SlideShow
// Create our Slides // Create our Slides
_slides = new Slide[slidesV.size()]; _slides = new Slide[slidesV.size()];
for(int i=0; i<_slides.length; i++) { for(int i=0; i<_slides.length; i++) {
// Grab the slide Record _slides[i] = (Slide)slidesV.get(i);
org.apache.poi.hslf.record.Slide slideRecord = (org.apache.poi.hslf.record.Slide)slidesV.get(i);
// Decide if we've got a SlideAtomSet to use
// TODO: Use the internal IDs to match instead
SlideAtomsSet atomSet = null;
if(i < slideAtomSets.length) {
atomSet = slideAtomSets[i];
}
// Do they have a Notes?
Notes thisNotes = null;
// Find their SlideAtom, and use this to check for a Notes
SlideAtom sa = slideRecord.getSlideAtom();
int notesID = sa.getNotesID();
if(notesID != 0) {
for(int k=0; k<_notes.length; k++) {
if(_notes[k].getSlideInternalNumber() == notesID) {
thisNotes = _notes[k];
}
}
}
// Create the Slide model layer
_slides[i] = new Slide(slideRecord,thisNotes,atomSet, (i+1));
// Now supply ourselves to all the rich text runs // Now supply ourselves to all the rich text runs
// of this slide's TextRuns // of this slide's TextRuns
@ -492,27 +524,33 @@ public class SlideShow
// Grab the SlidePersistAtom with the highest Slide Number. // Grab the SlidePersistAtom with the highest Slide Number.
// (Will stay as null if no SlidePersistAtom exists yet in // (Will stay as null if no SlidePersistAtom exists yet in
// the slide) // the slide, or only master slide's ones do)
SlidePersistAtom prev = null; SlidePersistAtom prev = null;
for(int i=0; i<slwts.length; i++) { for(int i=0; i<slwts.length; i++) {
SlideAtomsSet[] sas = slwts[i].getSlideAtomsSets(); SlideAtomsSet[] sas = slwts[i].getSlideAtomsSets();
for(int j=0; j<sas.length; j++) { for(int j=0; j<sas.length; j++) {
SlidePersistAtom spa = sas[j].getSlidePersistAtom(); SlidePersistAtom spa = sas[j].getSlidePersistAtom();
if(spa.getSlideIdentifier() < 0) {
// This is for a master slide
} else {
// Must be for a real slide
if(prev == null) { prev = spa; } if(prev == null) { prev = spa; }
if(prev.getSlideIdentifier() < spa.getSlideIdentifier()) { if(prev.getSlideIdentifier() < spa.getSlideIdentifier()) {
prev = spa; prev = spa;
} }
} }
} }
}
// Set up a new SlidePersistAtom for this slide // Set up a new SlidePersistAtom for this slide
SlidePersistAtom sp = new SlidePersistAtom(); SlidePersistAtom sp = new SlidePersistAtom();
// Refernce is the 1-based index of the slide container in // Reference is the 1-based index of the slide container in
// the document root. // the PersistPtr root.
// It always starts with 3 (1 is Document, 2 is MainMaster, 3 is // It always starts with 3 (1 is Document, 2 is MainMaster, 3 is
// the first slide) // the first slide), but quicksaves etc can leave gaps
sp.setRefID(prev == null ? 3 : (prev.getRefID() + 1)); _highestSheetId++;
sp.setRefID(_highestSheetId);
// First slideId is always 256 // First slideId is always 256
sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1)); sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1));
@ -521,7 +559,7 @@ public class SlideShow
// Create a new Slide // Create a new Slide
Slide slide = new Slide(sp.getRefID(), _slides.length+1); Slide slide = new Slide(sp.getSlideIdentifier(), sp.getRefID(), _slides.length+1);
// Add in to the list of Slides // Add in to the list of Slides
Slide[] s = new Slide[_slides.length+1]; Slide[] s = new Slide[_slides.length+1];
System.arraycopy(_slides, 0, s, 0, _slides.length); System.arraycopy(_slides, 0, s, 0, _slides.length);