added support for TitleMaster object

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@541622 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2007-05-25 12:04:45 +00:00
parent 581fb11400
commit 3bcdf011d1
18 changed files with 607 additions and 364 deletions

View File

@ -16,6 +16,9 @@
*/ */
package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;
import org.apache.poi.hslf.record.SheetContainer;
import org.apache.poi.hslf.model.textproperties.TextProp;
/** /**
* The superclass of all master sheets - Slide masters, Notes masters, etc. * The superclass of all master sheets - Slide masters, Notes masters, etc.
* *
@ -24,5 +27,14 @@ package org.apache.poi.hslf.model;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public abstract class MasterSheet extends Sheet { public abstract class MasterSheet extends Sheet {
public MasterSheet(SheetContainer container, int sheetNo){
super(container, sheetNo);
}
/**
* Pickup a style attribute from the master.
* This is the "workhorse" which returns the default style attrubutes.
*/
public abstract TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) ;
} }

View File

@ -20,8 +20,6 @@
package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;
import org.apache.poi.hslf.record.PPDrawing;
/** /**
* This class represents a slide's notes in a PowerPoint Document. It * This class represents a slide's notes in a PowerPoint Document. It
* allows access to the text within, and the layout. For now, it only * allows access to the text within, and the layout. For now, it only
@ -32,9 +30,6 @@ import org.apache.poi.hslf.record.PPDrawing;
public class Notes extends Sheet public class Notes extends Sheet
{ {
private int _refSheetNo;
private int _slideNo;
private org.apache.poi.hslf.record.Notes _notes;
private TextRun[] _runs; private TextRun[] _runs;
/** /**
@ -44,18 +39,12 @@ public class Notes extends Sheet
* @param notes the Notes record to read from * @param notes the Notes record to read from
*/ */
public Notes (org.apache.poi.hslf.record.Notes notes) { public Notes (org.apache.poi.hslf.record.Notes notes) {
_notes = notes; super(notes, notes.getNotesAtom().getSlideID());
// Grab our internal sheet ID
_refSheetNo = notes.getSheetId();
// Grab the number of the slide we're for, via the NotesAtom
_slideNo = _notes.getNotesAtom().getSlideID();
// Now, build up TextRuns from pairs of TextHeaderAtom and // Now, build up TextRuns from pairs of TextHeaderAtom and
// one of TextBytesAtom or TextCharsAtom, found inside // one of TextBytesAtom or TextCharsAtom, found inside
// EscherTextboxWrapper's in the PPDrawing // EscherTextboxWrapper's in the PPDrawing
_runs = findTextRuns(_notes.getPPDrawing()); _runs = findTextRuns(getPPDrawing());
// Set the sheet on each TextRun // Set the sheet on each TextRun
for (int i = 0; i < _runs.length; i++) for (int i = 0; i < _runs.length; i++)
@ -70,15 +59,11 @@ public class Notes extends Sheet
*/ */
public TextRun[] getTextRuns() { return _runs; } public TextRun[] getTextRuns() { return _runs; }
/** /**
* Returns the (internal, RefID based) sheet number, as used * Return <code>null</code> - Notes Masters are not yet supported
* to in PersistPtr stuff. */
*/ public MasterSheet getMasterSheet() {
public int _getSheetRefId() { return _refSheetNo; } return null;
/** }
* Returns the (internal, SlideIdentifer based) number of the
* slide we're attached to }
*/
public int _getSheetNumber() { return _slideNo; }
protected PPDrawing getPPDrawing() { return _notes.getPPDrawing(); }}

View File

@ -39,8 +39,6 @@ public class ShapeFactory {
int type = spRecord.getOptions() >> 4; int type = spRecord.getOptions() >> 4;
switch (type){ switch (type){
case ShapeTypes.TextBox: case ShapeTypes.TextBox:
shape = new TextBox(spContainer, parent);
break;
case ShapeTypes.Rectangle: case ShapeTypes.Rectangle:
EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID); EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID);
if (txtbox == null) if (txtbox == null)

View File

@ -1,4 +1,3 @@
/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -15,7 +14,6 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hslf.model; package org.apache.poi.hslf.model;
@ -33,195 +31,254 @@ import java.util.Vector;
/** /**
* This class defines the common format of "Sheets" in a powerpoint * This class defines the common format of "Sheets" in a powerpoint
* document. Such sheets could be Slides, Notes, Master etc * document. Such sheets could be Slides, Notes, Master etc
* *
* @author Nick Burch * @author Nick Burch
* @author Yegor Kozlov
*/ */
public abstract class Sheet public abstract class Sheet {
{ /**
/** * The <code>SlideShow</code> we belong to
* The <code>SlideShow</code> we belong to */
*/ private SlideShow _slideShow;
private SlideShow _slideShow;
/**
* Returns an array of all the TextRuns in the sheet.
*/
public abstract TextRun[] getTextRuns();
/** /**
* Returns the (internal, RefID based) sheet number, as used * Sheet background
* to in PersistPtr stuff. */
*/ private Background _background;
public abstract int _getSheetRefId();
/**
* Returns the (internal, SlideIdentifier based) sheet number, as used
* to reference this sheet from other records.
*/
public abstract int _getSheetNumber();
/**
* Fetch the PPDrawing from the underlying record
*/
protected abstract PPDrawing getPPDrawing();
/**
* Fetch the SlideShow we're attached to
*/
public SlideShow getSlideShow() { return _slideShow; }
/**
* Set the SlideShow we're attached to.
* Also passes it on to our child RichTextRuns
*/
public void setSlideShow(SlideShow ss) {
_slideShow = ss;
TextRun[] trs = getTextRuns();
if(trs != null) {
for(int i=0; i<trs.length; i++) {
trs[i].supplySlideShow(_slideShow);
}
}
}
/**
/** * Record container that holds sheet data.
* For a given PPDrawing, grab all the TextRuns * For slides it is org.apache.poi.hslf.record.Slide,
*/ * for notes it is org.apache.poi.hslf.record.Notes,
public static TextRun[] findTextRuns(PPDrawing ppdrawing) { * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
Vector runsV = new Vector(); */
EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers(); private SheetContainer _container;
for(int i=0; i<wrappers.length; i++) {
findTextRuns(wrappers[i].getChildRecords(),runsV);
}
TextRun[] runs = new TextRun[runsV.size()];
for(int i=0; i<runs.length; i++) {
runs[i] = (TextRun)runsV.get(i);
}
return runs;
}
/** private int _sheetNo;
* Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or
* a TextCharsAtom. Builds up TextRuns from these
*
* @param records the records to build from
* @param found vector to add any found to
*/
protected static void findTextRuns(Record[] records, Vector found) {
// Look for a TextHeaderAtom
for(int i=0; i<(records.length-1); i++) {
if(records[i] instanceof TextHeaderAtom) {
TextRun trun = null;
TextHeaderAtom tha = (TextHeaderAtom)records[i];
StyleTextPropAtom stpa = null;
// Look for a subsequent StyleTextPropAtom
if(i < (records.length-2)) {
if(records[i+2] instanceof StyleTextPropAtom) {
stpa = (StyleTextPropAtom)records[i+2];
}
}
// See what follows the TextHeaderAtom
if(records[i+1] instanceof TextCharsAtom) {
TextCharsAtom tca = (TextCharsAtom)records[i+1];
trun = new TextRun(tha,tca,stpa);
} else if(records[i+1] instanceof TextBytesAtom) {
TextBytesAtom tba = (TextBytesAtom)records[i+1];
trun = new TextRun(tha,tba,stpa);
} else if(records[i+1].getRecordType() == 4001l) {
// StyleTextPropAtom - Safe to ignore
} else if(records[i+1].getRecordType() == 4010l) {
// TextSpecInfoAtom - Safe to ignore
} else {
System.err.println("Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + records[i+1].getRecordType());
continue;
}
if(trun != null) { public Sheet(SheetContainer container, int sheetNo) {
found.add(trun); _container = container;
i++; _sheetNo = sheetNo;
} else { }
// Not a valid one, so skip on to next and look again
}
}
}
}
/** /**
* Returns all shapes contained in this Sheet * Returns an array of all the TextRuns in the sheet.
* */
* @return all shapes contained in this Sheet (Slide or Notes) public abstract TextRun[] getTextRuns();
*/
public Shape[] getShapes() {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord)ppdrawing.getEscherRecords()[0];
EscherContainerRecord spgr = null;
List ch = dg.getChildRecords();
for (Iterator it = ch.iterator(); it.hasNext();) { /**
EscherRecord rec = (EscherRecord)it.next(); * Returns the (internal, RefID based) sheet number, as used
if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ * to in PersistPtr stuff.
spgr = (EscherContainerRecord)rec; */
break; public int _getSheetRefId() {
} return _container.getSheetId();
} }
ch = spgr.getChildRecords();
ArrayList shapes = new ArrayList(); /**
for (int i=1;i<ch.size();i++) { * Returns the (internal, SlideIdentifier based) sheet number, as used
EscherContainerRecord sp = (EscherContainerRecord)ch.get(i); * to reference this sheet from other records.
Shape sh = ShapeFactory.createShape(sp, null); */
sh.setSheet(this); public int _getSheetNumber() {
shapes.add(sh); return _sheetNo;
} }
return (Shape[])shapes.toArray(new Shape[shapes.size()]);
}
/** /**
* Add a new Shape to this Slide * Fetch the PPDrawing from the underlying record
* */
* @param shape - the Shape to add protected PPDrawing getPPDrawing() {
*/ return _container.getPPDrawing();
public void addShape(Shape shape){ }
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dgContainer = (EscherContainerRecord)ppdrawing.getEscherRecords()[0]; /**
EscherContainerRecord spgr = (EscherContainerRecord)Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER); * Fetch the SlideShow we're attached to
spgr.addChildRecord(shape.getSpContainer()); */
public SlideShow getSlideShow() {
return _slideShow;
}
/**
* Return record container for this sheet
*/
public SheetContainer getSheetContainer() {
return _container;
}
/**
* Set the SlideShow we're attached to.
* Also passes it on to our child RichTextRuns
*/
public void setSlideShow(SlideShow ss) {
_slideShow = ss;
TextRun[] trs = getTextRuns();
if (trs != null) {
for (int i = 0; i < trs.length; i++) {
trs[i].supplySlideShow(_slideShow);
}
}
}
/**
* For a given PPDrawing, grab all the TextRuns
*/
public static TextRun[] findTextRuns(PPDrawing ppdrawing) {
Vector runsV = new Vector();
EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers();
for (int i = 0; i < wrappers.length; i++) {
findTextRuns(wrappers[i].getChildRecords(), runsV);
}
TextRun[] runs = new TextRun[runsV.size()];
for (int i = 0; i < runs.length; i++) {
runs[i] = (TextRun) runsV.get(i);
}
return runs;
}
/**
* Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or
* a TextCharsAtom. Builds up TextRuns from these
*
* @param records the records to build from
* @param found vector to add any found to
*/
protected static void findTextRuns(Record[] records, Vector found) {
// Look for a TextHeaderAtom
for (int i = 0; i < (records.length - 1); i++) {
if (records[i] instanceof TextHeaderAtom) {
TextRun trun = null;
TextHeaderAtom tha = (TextHeaderAtom) records[i];
StyleTextPropAtom stpa = null;
// Look for a subsequent StyleTextPropAtom
if (i < (records.length - 2)) {
if (records[i + 2] instanceof StyleTextPropAtom) {
stpa = (StyleTextPropAtom) records[i + 2];
}
}
// See what follows the TextHeaderAtom
if (records[i + 1] instanceof TextCharsAtom) {
TextCharsAtom tca = (TextCharsAtom) records[i + 1];
trun = new TextRun(tha, tca, stpa);
} else if (records[i + 1] instanceof TextBytesAtom) {
TextBytesAtom tba = (TextBytesAtom) records[i + 1];
trun = new TextRun(tha, tba, stpa);
} else if (records[i + 1].getRecordType() == 4001l) {
// StyleTextPropAtom - Safe to ignore
} else if (records[i + 1].getRecordType() == 4010l) {
// TextSpecInfoAtom - Safe to ignore
} else {
System.err.println("Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + records[i + 1].getRecordType());
continue;
}
if (trun != null) {
found.add(trun);
i++;
} else {
// Not a valid one, so skip on to next and look again
}
}
}
}
/**
* Returns all shapes contained in this Sheet
*
* @return all shapes contained in this Sheet (Slide or Notes)
*/
public Shape[] getShapes() {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
EscherContainerRecord spgr = null;
List ch = dg.getChildRecords();
for (Iterator it = ch.iterator(); it.hasNext();) {
EscherRecord rec = (EscherRecord) it.next();
if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
spgr = (EscherContainerRecord) rec;
break;
}
}
ch = spgr.getChildRecords();
ArrayList shapes = new ArrayList();
for (int i = 1; i < ch.size(); i++) {
EscherContainerRecord sp = (EscherContainerRecord) ch.get(i);
Shape sh = ShapeFactory.createShape(sp, null);
sh.setSheet(this);
shapes.add(sh);
}
return (Shape[]) shapes.toArray(new Shape[shapes.size()]);
}
/**
* Add a new Shape to this Slide
*
* @param shape - the Shape to add
*/
public void addShape(Shape shape) {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
EscherContainerRecord spgr = (EscherContainerRecord) Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
spgr.addChildRecord(shape.getSpContainer());
EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
dg.setNumShapes(dg.getNumShapes() + 1);
shape.setSheet(this);
shape.afterInsert(this);
// If it's a TextBox, we need to tell the PPDrawing, as it has to
// track TextboxWrappers specially
if (shape instanceof TextBox) {
TextBox tbox = (TextBox) shape;
ppdrawing.addTextboxWrapper(tbox._txtbox);
}
}
EscherDgRecord dg = (EscherDgRecord)Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
dg.setNumShapes(dg.getNumShapes()+1);
shape.setSheet(this);
shape.afterInsert(this);
// If it's a TextBox, we need to tell the PPDrawing, as it has to
// track TextboxWrappers specially
if(shape instanceof TextBox) {
TextBox tbox = (TextBox)shape;
ppdrawing.addTextboxWrapper(tbox._txtbox);
}
}
/** /**
* Return the master sheet . * Return the master sheet .
*/ */
public MasterSheet getMasterSheet(){ public abstract MasterSheet getMasterSheet();
return null;
}
/** /**
* Color scheme for this sheet. * Color scheme for this sheet.
*/ */
public ColorSchemeAtom getColorScheme(){ public ColorSchemeAtom getColorScheme() {
return null; return _container.getColorScheme();
} }
/**
* Returns the background shape for this sheet.
*
* @return the background shape for this sheet.
*/
public Background getBackground() {
if (_background == null) {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
EscherContainerRecord spContainer = null;
List ch = dg.getChildRecords();
for (Iterator it = ch.iterator(); it.hasNext();) {
EscherRecord rec = (EscherRecord) it.next();
if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
spContainer = (EscherContainerRecord) rec;
break;
}
}
_background = new Background(spContainer, null);
_background.setSheet(this);
}
return _background;
}
} }

View File

@ -44,15 +44,10 @@ import org.apache.poi.ddf.EscherRecord;
public class Slide extends Sheet public class Slide extends Sheet
{ {
private int _refSheetNo;
private int _sheetNo;
private int _slideNo; private int _slideNo;
private org.apache.poi.hslf.record.Slide _slide;
private SlideAtomsSet _atomSet; private SlideAtomsSet _atomSet;
private TextRun[] _runs; private TextRun[] _runs;
private TextRun[] _otherRuns; // Any from the PPDrawing, shouldn't really be any though
private Notes _notes; // usermodel needs to set this private Notes _notes; // usermodel needs to set this
private Background _background;
/** /**
* Constructs a Slide from the Slide record, and the SlideAtomsSet * Constructs a Slide from the Slide record, and the SlideAtomsSet
@ -64,15 +59,14 @@ public class Slide extends Sheet
* @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 slideIdentifier, int slideNumber) { public Slide(org.apache.poi.hslf.record.Slide slide, Notes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
_slide = slide; super(slide, slideIdentifier);
_notes = notes; _notes = notes;
_atomSet = atomSet; _atomSet = atomSet;
_refSheetNo = slide.getSheetId();
_sheetNo = slideIdentifier;
_slideNo = slideNumber; _slideNo = slideNumber;
// Grab the TextRuns from the PPDrawing // Grab the TextRuns from the PPDrawing
_otherRuns = findTextRuns(_slide.getPPDrawing()); TextRun[] _otherRuns = findTextRuns(getPPDrawing());
// For the text coming in from the SlideAtomsSet: // For the text coming in from the SlideAtomsSet:
// Build up TextRuns from pairs of TextHeaderAtom and // Build up TextRuns from pairs of TextHeaderAtom and
@ -105,10 +99,9 @@ public class Slide extends Sheet
* @param slideNumber The user facing number of the sheet * @param slideNumber The user facing number of the sheet
*/ */
public Slide(int sheetNumber, int sheetRefId, int slideNumber){ public Slide(int sheetNumber, int sheetRefId, int slideNumber){
_slide = new org.apache.poi.hslf.record.Slide(); super(new org.apache.poi.hslf.record.Slide(), sheetNumber);
_refSheetNo = sheetRefId;
_sheetNo = sheetNumber;
_slideNo = slideNumber; _slideNo = slideNumber;
getSheetContainer().setSheetId(sheetRefId);
} }
/** /**
@ -119,7 +112,7 @@ public class Slide extends Sheet
_notes = notes; _notes = notes;
// Update the Slide Atom's ID of where to point to // Update the Slide Atom's ID of where to point to
SlideAtom sa = _slide.getSlideAtom(); SlideAtom sa = getSlideRecord().getSlideAtom();
if(notes == null) { if(notes == null) {
// Set to 0 // Set to 0
@ -132,7 +125,7 @@ public class Slide extends Sheet
/** /**
* Changes the Slide's (external facing) page number. * Changes the Slide's (external facing) page number.
* @see SlideShow.reorderSlide() * @see org.apache.poi.hslf.usermodel.SlideShow#reorderSlide(int, int)
*/ */
public void setSlideNumber(int newSlideNumber) { public void setSlideNumber(int newSlideNumber) {
_slideNo = newSlideNumber; _slideNo = newSlideNumber;
@ -187,17 +180,6 @@ public class Slide extends Sheet
*/ */
public TextRun[] getTextRuns() { return _runs; } public TextRun[] getTextRuns() { return _runs; }
/**
* 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()
*/
public int _getSheetNumber() { return _sheetNo; }
/** /**
* Returns the (public facing) page number of this slide * Returns the (public facing) page number of this slide
*/ */
@ -206,18 +188,15 @@ public class Slide extends Sheet
/** /**
* Returns the underlying slide record * Returns the underlying slide record
*/ */
public org.apache.poi.hslf.record.Slide getSlideRecord() { return _slide; } public org.apache.poi.hslf.record.Slide getSlideRecord() {
return (org.apache.poi.hslf.record.Slide)getSheetContainer();
}
/** /**
* Returns the Notes Sheet for this slide, or null if there isn't one * Returns the Notes Sheet for this slide, or null if there isn't one
*/ */
public Notes getNotesSheet() { return _notes; } public Notes getNotesSheet() { return _notes; }
/**
* Returns the PPDrawing associated with this slide, or null if there isn't one
*/
protected PPDrawing getPPDrawing() { return _slide.getPPDrawing(); }
/** /**
* @return set of records inside <code>SlideListWithtext</code> container * @return set of records inside <code>SlideListWithtext</code> container
* which hold text data for this slide (typically for placeholders). * which hold text data for this slide (typically for placeholders).
@ -225,60 +204,43 @@ public class Slide extends Sheet
protected SlideAtomsSet getSlideAtomsSet() { return _atomSet; } protected SlideAtomsSet getSlideAtomsSet() { return _atomSet; }
/** /**
* Returns the slide master associated with this slide. * Returns master sheet associated with this slide.
* It can be either SlideMaster or TitleMaster objects.
* *
* @return the slide master associated with this slide. * @return the master sheet associated with this slide.
*/ */
public MasterSheet getMasterSheet(){ public MasterSheet getMasterSheet(){
SlideMaster[] master = getSlideShow().getSlidesMasters(); SlideMaster[] master = getSlideShow().getSlidesMasters();
SlideAtom sa = _slide.getSlideAtom(); SlideAtom sa = getSlideRecord().getSlideAtom();
int masterId = sa.getMasterID(); int masterId = sa.getMasterID();
MasterSheet sheet = null;
for (int i = 0; i < master.length; i++) { for (int i = 0; i < master.length; i++) {
if (masterId == master[i]._getSheetNumber()) return master[i]; if (masterId == master[i]._getSheetNumber()) {
sheet = master[i];
break;
}
} }
return null; if (sheet == null){
TitleMaster[] titleMaster = getSlideShow().getTitleMasters();
if(titleMaster != null) for (int i = 0; i < titleMaster.length; i++) {
if (masterId == titleMaster[i]._getSheetNumber()) {
sheet = titleMaster[i];
break;
}
}
}
return sheet;
} }
/** /**
* Change Master of this slide. * Change Master of this slide.
*/ */
public void setMasterSheet(MasterSheet master){ public void setMasterSheet(MasterSheet master){
SlideAtom sa = _slide.getSlideAtom(); SlideAtom sa = getSlideRecord().getSlideAtom();
int sheetNo = master._getSheetNumber(); int sheetNo = master._getSheetNumber();
sa.setMasterID(sheetNo); sa.setMasterID(sheetNo);
} }
public ColorSchemeAtom getColorScheme(){
return _slide.getColorScheme();
}
/**
* Returns the background shape for this sheet.
*
* @return the background shape for this sheet.
*/
public Background getBackground(){
if (_background == null){
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord)ppdrawing.getEscherRecords()[0];
EscherContainerRecord spContainer = null;
List ch = dg.getChildRecords();
for (Iterator it = ch.iterator(); it.hasNext();) {
EscherRecord rec = (EscherRecord)it.next();
if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER){
spContainer = (EscherContainerRecord)rec;
break;
}
}
_background = new Background(spContainer, null);
_background.setSheet(this);
}
return _background;
}
/** /**
* Sets whether this slide follows master background * Sets whether this slide follows master background
* *
@ -286,7 +248,7 @@ public class Slide extends Sheet
* <code>false</code> otherwise * <code>false</code> otherwise
*/ */
public void setFollowMasterBackground(boolean flag){ public void setFollowMasterBackground(boolean flag){
SlideAtom sa = _slide.getSlideAtom(); SlideAtom sa = getSlideRecord().getSlideAtom();
sa.setFollowMasterBackground(flag); sa.setFollowMasterBackground(flag);
} }
@ -297,7 +259,7 @@ public class Slide extends Sheet
* <code>false</code> otherwise * <code>false</code> otherwise
*/ */
public boolean getFollowMasterBackground(){ public boolean getFollowMasterBackground(){
SlideAtom sa = _slide.getSlideAtom(); SlideAtom sa = getSlideRecord().getSlideAtom();
return sa.getFollowMasterBackground(); return sa.getFollowMasterBackground();
} }
} }

View File

@ -36,11 +36,7 @@ import java.util.Iterator;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class SlideMaster extends MasterSheet { public class SlideMaster extends MasterSheet {
private int _refSheetNo;
private int _sheetNo;
private MainMaster _master;
private TextRun[] _runs; private TextRun[] _runs;
private Background _background;
/** /**
* all TxMasterStyleAtoms available in this master * all TxMasterStyleAtoms available in this master
@ -51,16 +47,11 @@ public class SlideMaster extends MasterSheet {
* Constructs a SlideMaster from the MainMaster record, * Constructs a SlideMaster from the MainMaster record,
* *
*/ */
public SlideMaster(org.apache.poi.hslf.record.MainMaster rec, int slideId) { public SlideMaster(MainMaster record, int sheetNo) {
_master = rec; super(record, sheetNo);
// Grab our internal sheet ID _runs = findTextRuns(getPPDrawing());
_refSheetNo = rec.getSheetId(); for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
// Grab the number of the slide we're for, via the NotesAtom
_sheetNo = slideId;
_runs = findTextRuns(_master.getPPDrawing());
} }
/** /**
@ -71,26 +62,10 @@ public class SlideMaster extends MasterSheet {
} }
/** /**
* Returns the (internal, RefID based) sheet number, as used * Returns <code>null</code> since SlideMasters doen't have master sheet.
* to in PersistPtr stuff.
*/ */
public int _getSheetRefId() { public MasterSheet getMasterSheet() {
return _refSheetNo; return null;
}
/**
* Returns the (internal, SlideIdentifer based) number of the
* slide we're attached to
*/
public int _getSheetNumber() {
return _sheetNo;
}
/**
* Returns the PPDrawing associated with this slide master
*/
protected PPDrawing getPPDrawing() {
return _master.getPPDrawing();
} }
/** /**
@ -138,44 +113,10 @@ public class SlideMaster extends MasterSheet {
TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom();
_txmaster[txdoc.getTextType()] = txdoc; _txmaster[txdoc.getTextType()] = txdoc;
TxMasterStyleAtom[] txrec = _master.getTxMasterStyleAtoms(); TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms();
for (int i = 0; i < txrec.length; i++) { for (int i = 0; i < txrec.length; i++) {
_txmaster[txrec[i].getTextType()] = txrec[i]; _txmaster[txrec[i].getTextType()] = txrec[i];
} }
} }
} }
/**
* Returns the ColorSchemeAtom associated with this slide master
*/
public ColorSchemeAtom getColorScheme(){
return _master.getColorScheme();
}
/**
* Returns the background shape for this sheet.
*
* @return the background shape for this sheet.
*/
public Background getBackground(){
if (_background == null){
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord)ppdrawing.getEscherRecords()[0];
EscherContainerRecord spContainer = null;
List ch = dg.getChildRecords();
for (Iterator it = ch.iterator(); it.hasNext();) {
EscherRecord rec = (EscherRecord)it.next();
if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER){
spContainer = (EscherContainerRecord)rec;
break;
}
}
_background = new Background(spContainer, null);
_background.setSheet(this);
}
return _background;
}
} }

View File

@ -0,0 +1,69 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hslf.model;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.record.*;
/**
* Title masters define the design template for slides with a Title Slide layout.
*
* @author Yegor Kozlov
*/
public class TitleMaster extends MasterSheet {
private TextRun[] _runs;
/**
* Constructs a TitleMaster
*
*/
public TitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
super(record, sheetNo);
_runs = findTextRuns(getPPDrawing());
for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
}
/**
* Returns an array of all the TextRuns found
*/
public TextRun[] getTextRuns() {
return _runs;
}
/**
* Delegate the call to the underlying slide master.
*/
public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
MasterSheet master = getMasterSheet();
return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
}
/**
* Returns the slide master for this title master.
*/
public MasterSheet getMasterSheet(){
SlideMaster[] master = getSlideShow().getSlidesMasters();
SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
int masterId = sa.getMasterID();
for (int i = 0; i < master.length; i++) {
if (masterId == master[i]._getSheetNumber()) return master[i];
}
return null;
}
}

View File

@ -31,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class MainMaster extends PositionDependentRecordContainer public class MainMaster extends SheetContainer
{ {
private byte[] _header; private byte[] _header;
private static long _type = 1016; private static long _type = 1016;

View File

@ -29,7 +29,7 @@ import java.io.OutputStream;
* @author Nick Burch * @author Nick Burch
*/ */
public class Notes extends PositionDependentRecordContainer public class Notes extends SheetContainer
{ {
private byte[] _header; private byte[] _header;
private static long _type = 1008l; private static long _type = 1008l;
@ -37,6 +37,7 @@ public class Notes extends PositionDependentRecordContainer
// Links to our more interesting children // Links to our more interesting children
private NotesAtom notesAtom; private NotesAtom notesAtom;
private PPDrawing ppDrawing; private PPDrawing ppDrawing;
private ColorSchemeAtom _colorScheme;
/** /**
* Returns the NotesAtom of this Notes * Returns the NotesAtom of this Notes
@ -69,6 +70,9 @@ public class Notes extends PositionDependentRecordContainer
if(_children[i] instanceof PPDrawing) { if(_children[i] instanceof PPDrawing) {
ppDrawing = (PPDrawing)_children[i]; ppDrawing = (PPDrawing)_children[i];
} }
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom)_children[i];
}
} }
} }
@ -85,4 +89,8 @@ public class Notes extends PositionDependentRecordContainer
public void writeOut(OutputStream out) throws IOException { public void writeOut(OutputStream out) throws IOException {
writeOut(_header[0],_header[1],_type,_children,out); writeOut(_header[0],_header[1],_type,_children,out);
} }
public ColorSchemeAtom getColorScheme(){
return _colorScheme;
}
} }

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.poi.hslf.record;
/**
* The superclass of all sheet container records - Slide, Notes, MainMaster, etc.
*/
public abstract class SheetContainer extends PositionDependentRecordContainer {
/**
* Returns the PPDrawing of this sheet, which has all the
* interesting data in it
*/
public abstract PPDrawing getPPDrawing();
public abstract ColorSchemeAtom getColorScheme();
}

View File

@ -31,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
* @author Nick Burch * @author Nick Burch
*/ */
public class Slide extends PositionDependentRecordContainer public class Slide extends SheetContainer
{ {
private byte[] _header; private byte[] _header;
private static long _type = 1006l; private static long _type = 1006l;

View File

@ -23,9 +23,11 @@ package org.apache.poi.hslf.usermodel;
import org.apache.poi.hslf.model.TextRun; import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.Sheet; import org.apache.poi.hslf.model.Sheet;
import org.apache.poi.hslf.model.SlideMaster; import org.apache.poi.hslf.model.SlideMaster;
import org.apache.poi.hslf.model.MasterSheet;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp; import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextProp; import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.ColorSchemeAtom;
import java.awt.*; import java.awt.*;
@ -60,7 +62,7 @@ public class RichTextRun
private TextPropCollection characterStyle; private TextPropCollection characterStyle;
private boolean sharingParagraphStyle; private boolean sharingParagraphStyle;
private boolean sharingCharacterStyle; private boolean sharingCharacterStyle;
/** /**
* Create a new wrapper around a (currently not) * Create a new wrapper around a (currently not)
* rich text string * rich text string
@ -169,7 +171,7 @@ public class RichTextRun
if (cftp == null){ if (cftp == null){
Sheet sheet = parentRun.getSheet(); Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType(); int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet(); MasterSheet master = sheet.getMasterSheet();
if (master != null) if (master != null)
cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true); cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true);
} }
@ -192,7 +194,7 @@ public class RichTextRun
fetchOrAddTextProp(characterStyle, "char_flags"); fetchOrAddTextProp(characterStyle, "char_flags");
cftp.setSubValue(value,index); cftp.setSubValue(value,index);
} }
/** /**
* Returns the named TextProp, either by fetching it (if it exists) or adding it * Returns the named TextProp, either by fetching it (if it exists) or adding it
* (if it didn't) * (if it didn't)
@ -223,7 +225,7 @@ public class RichTextRun
if (prop == null){ if (prop == null){
Sheet sheet = parentRun.getSheet(); Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType(); int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet(); MasterSheet master = sheet.getMasterSheet();
if (master != null) if (master != null)
prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true); prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true);
} }
@ -243,7 +245,7 @@ public class RichTextRun
if (prop == null){ if (prop == null){
Sheet sheet = parentRun.getSheet(); Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType(); int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet(); MasterSheet master = sheet.getMasterSheet();
if (master != null) if (master != null)
prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false); prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);
} }

View File

@ -74,6 +74,7 @@ public class SlideShow
// Friendly objects for people to deal with // Friendly objects for people to deal with
private SlideMaster[] _masters; private SlideMaster[] _masters;
private TitleMaster[] _titleMasters;
private Slide[] _slides; private Slide[] _slides;
private Notes[] _notes; private Notes[] _notes;
private FontCollection _fonts; private FontCollection _fonts;
@ -311,25 +312,33 @@ public class SlideShow
// About the only thing you can say is that the master details are in // About the only thing you can say is that the master details are in
// the first SLWT. // the first SLWT.
SlideAtomsSet[] masterSets = new SlideAtomsSet[0]; SlideAtomsSet[] masterSets = new SlideAtomsSet[0];
org.apache.poi.hslf.record.MainMaster[] mainMasterRecords = null;
if (masterSLWT != null){ if (masterSLWT != null){
masterSets = masterSLWT.getSlideAtomsSets(); masterSets = masterSLWT.getSlideAtomsSets();
// For now, we only care about the records which are MainMasters
// (In future, we might want to know about the other too)
ArrayList mmr = new ArrayList(); ArrayList mmr = new ArrayList();
ArrayList tmr = new ArrayList();
for(int i=0; i<masterSets.length; i++) { for(int i=0; i<masterSets.length; i++) {
Record r = getCoreRecordForSAS(masterSets[i]); Record r = getCoreRecordForSAS(masterSets[i]);
SlideAtomsSet sas = masterSets[i];
int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
if(r instanceof org.apache.poi.hslf.record.Slide) { if(r instanceof org.apache.poi.hslf.record.Slide) {
// Slide master, skip 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) { } else if(r instanceof org.apache.poi.hslf.record.MainMaster) {
mmr.add(r); SlideMaster master = new SlideMaster((org.apache.poi.hslf.record.MainMaster)r, sheetNo);
} master.setSlideShow(this);
mmr.add(master);
}
} }
mainMasterRecords = new org.apache.poi.hslf.record.MainMaster[mmr.size()]; _masters = new SlideMaster[mmr.size()];
mmr.toArray(mainMasterRecords); mmr.toArray(_masters);
_titleMasters = new TitleMaster[tmr.size()];
tmr.toArray(_titleMasters);
} }
@ -351,12 +360,12 @@ public class SlideShow
for(int i=0; i<notesSets.length; i++) { for(int i=0; i<notesSets.length; i++) {
// Get the right core record // Get the right core record
Record r = getCoreRecordForSAS(notesSets[i]); Record r = getCoreRecordForSAS(notesSets[i]);
// Ensure it really is a notes record // Ensure it really is a notes record
if(r instanceof org.apache.poi.hslf.record.Notes) { if(r instanceof org.apache.poi.hslf.record.Notes) {
org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes)r; org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes)r;
notesRecordsL.add( notesRecord ); notesRecordsL.add( notesRecord );
// Record the match between slide id and these notes // Record the match between slide id and these notes
SlidePersistAtom spa = notesSets[i].getSlidePersistAtom(); SlidePersistAtom spa = notesSets[i].getSlidePersistAtom();
Integer slideId = new Integer(spa.getSlideIdentifier()); Integer slideId = new Integer(spa.getSlideIdentifier());
@ -394,14 +403,6 @@ public class SlideShow
} }
// Finally, generate model objects for everything // Finally, generate model objects for everything
_masters = new SlideMaster[mainMasterRecords.length];
for(int i=0; i<_masters.length; i++) {
SlideAtomsSet sas = masterSets[i];
int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
_masters[i] = new SlideMaster(mainMasterRecords[i], sheetNo);
_masters[i].setSlideShow(this);
}
// Notes first // Notes first
_notes = new Notes[notesRecords.length]; _notes = new Notes[notesRecords.length];
for(int i=0; i<_notes.length; i++) { for(int i=0; i<_notes.length; i++) {
@ -465,10 +466,14 @@ public class SlideShow
public Notes[] getNotes() { return _notes; } public Notes[] getNotes() { return _notes; }
/** /**
* Returns an array of all the normal Slides found in the slideshow * Returns an array of all the normal Slide Masters found in the slideshow
*/ */
public SlideMaster[] getSlidesMasters() { return _masters; } public SlideMaster[] getSlidesMasters() { return _masters; }
/**
* Returns an array of all the normal Title Masters found in the slideshow
*/
public TitleMaster[] getTitleMasters() { return _titleMasters; }
/** /**
* Returns the data of all the pictures attached to the SlideShow * Returns the data of all the pictures attached to the SlideShow
*/ */

View File

@ -0,0 +1,100 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hslf.model;
import junit.framework.TestCase;
import java.io.FileInputStream;
import java.io.File;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.PPDrawing;
import org.apache.poi.hslf.usermodel.SlideShow;
/**
* Test common functionality of the <code>Sheet</code> object.
* For each ppt in the test directory check that all sheets are properly initialized
*
* @author Yegor Kozlov
*/
public class TestSheet extends TestCase{
/**
* For each ppt in the test directory check that all sheets are properly initialized
*/
public void testSheet() throws Exception {
File home = new File(System.getProperty("HSLF.testdata.path"));
File[] files = home.listFiles();
for (int i = 0; i < files.length; i++) {
if(!files[i].getName().endsWith(".ppt")) continue;
try {
FileInputStream is = new FileInputStream(files[i]);
HSLFSlideShow hslf = new HSLFSlideShow(is);
is.close();
SlideShow ppt = new SlideShow(hslf);
doSlideShow(ppt);
} catch (EncryptedPowerPointFileException e){
; //skip encrypted ppt
}
}
}
private void doSlideShow(SlideShow ppt) throws Exception {
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
verify(slide[i]);
Notes notes = slide[i].getNotesSheet();
if(notes != null) verify(notes);
MasterSheet master = slide[i].getMasterSheet();
assertNotNull(master);
verify(master);
}
}
private void verify(Sheet sheet){
ColorSchemeAtom colorscheme = sheet.getColorScheme();
assertNotNull(colorscheme);
PPDrawing ppdrawing = sheet.getPPDrawing();
assertNotNull(ppdrawing);
Background background = sheet.getBackground();
assertNotNull(background);
assertTrue(sheet._getSheetNumber() != 0);
assertTrue(sheet._getSheetRefId() != 0);
TextRun[] txt = sheet.getTextRuns();
assertTrue(txt != null);
for (int i = 0; i < txt.length; i++) {
assertNotNull(txt[i].getSheet());
}
Shape[] shape = sheet.getShapes();
assertTrue(shape != null);
for (int i = 0; i < shape.length; i++) {
assertNotNull(shape[i].getSheet());
}
assertNotNull(sheet.getSlideShow());
}
}

View File

@ -27,6 +27,7 @@ import org.apache.poi.hslf.record.StyleTextPropAtom.*;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.awt.*;
/** /**
* Tests for SlideMaster * Tests for SlideMaster
@ -81,13 +82,63 @@ public class TestSlideMaster extends TestCase{
assertEquals("Georgia", env.getFontCollection().getFontWithId(b2)); assertEquals("Georgia", env.getFontCollection().getFontWithId(b2));
} }
/**
* Test we can read default text attributes for a title master sheet
*/
public void testTitleMasterTextAttributes() throws Exception {
SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt"));
TitleMaster[] master = ppt.getTitleMasters();
assertEquals(1, master.length);
assertEquals(32, master[0].getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "font.size", true).getValue());
CharFlagsTextProp prop1 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "char_flags", true);
assertEquals(true, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
assertEquals(20, master[0].getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "font.size", true).getValue());
CharFlagsTextProp prop2 = (CharFlagsTextProp)master[0].getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "char_flags", true);
assertEquals(true, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
}
/**
* Slide 3 has title layout and follows the TitleMaster. Verify that.
*/
public void testTitleMaster() throws Exception {
SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt"));
Slide slide = ppt.getSlides()[2];
MasterSheet masterSheet = slide.getMasterSheet();
assertTrue(masterSheet instanceof TitleMaster);
TextRun[] txt = slide.getTextRuns();
for (int i = 0; i < txt.length; i++) {
RichTextRun rt = txt[i].getRichTextRuns()[0];
switch(txt[i].getRunType()){
case TextHeaderAtom.CENTER_TITLE_TYPE:
assertEquals("Arial", rt.getFontName());
assertEquals(32, rt.getFontSize());
assertEquals(true, rt.isBold());
assertEquals(true, rt.isUnderlined());
break;
case TextHeaderAtom.CENTRE_BODY_TYPE:
assertEquals("Courier New", rt.getFontName());
assertEquals(20, rt.getFontSize());
assertEquals(true, rt.isBold());
assertEquals(false, rt.isUnderlined());
break;
}
}
}
/** /**
* If a style attribute is not set ensure it is read from the master * If a style attribute is not set ensure it is read from the master
*/ */
public void testMasterAttributes() throws Exception { public void testMasterAttributes() throws Exception {
SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt")); SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt"));
Slide[] slide = ppt.getSlides(); Slide[] slide = ppt.getSlides();
assertEquals(2, slide.length); assertEquals(3, slide.length);
TextRun[] trun; TextRun[] trun;
trun = slide[0].getTextRuns(); trun = slide[0].getTextRuns();

View File

@ -163,4 +163,25 @@ public class TestBugs extends TestCase {
assertTrue("No Exceptions while reading file", true); assertTrue("No Exceptions while reading file", true);
} }
/**
* Bug 41381: Exception from Slide.getMasterSheet() on a seemingly valid PPT file
*/
public void test41381() throws Exception {
FileInputStream is = new FileInputStream(new File(cwd, "alterman_security.ppt"));
HSLFSlideShow hslf = new HSLFSlideShow(is);
is.close();
SlideShow ppt = new SlideShow(hslf);
assertTrue("No Exceptions while reading file", true);
assertEquals(1, ppt.getSlidesMasters().length);
assertEquals(1, ppt.getTitleMasters().length);
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
MasterSheet master = slide[i].getMasterSheet();
if (i == 0) assertTrue(master instanceof TitleMaster); //the first slide follows TitleMaster
else assertTrue(master instanceof SlideMaster);
}
}
} }