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 f89c211539
commit d4134d80ef
18 changed files with 607 additions and 364 deletions

View File

@ -16,6 +16,9 @@
*/
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.
*
@ -24,5 +27,14 @@ package org.apache.poi.hslf.model;
* @author Yegor Kozlov
*/
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;
import org.apache.poi.hslf.record.PPDrawing;
/**
* 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
@ -32,9 +30,6 @@ import org.apache.poi.hslf.record.PPDrawing;
public class Notes extends Sheet
{
private int _refSheetNo;
private int _slideNo;
private org.apache.poi.hslf.record.Notes _notes;
private TextRun[] _runs;
/**
@ -44,18 +39,12 @@ public class Notes extends Sheet
* @param notes the Notes record to read from
*/
public Notes (org.apache.poi.hslf.record.Notes notes) {
_notes = notes;
// Grab our internal sheet ID
_refSheetNo = notes.getSheetId();
// Grab the number of the slide we're for, via the NotesAtom
_slideNo = _notes.getNotesAtom().getSlideID();
super(notes, notes.getNotesAtom().getSlideID());
// Now, build up TextRuns from pairs of TextHeaderAtom and
// one of TextBytesAtom or TextCharsAtom, found inside
// EscherTextboxWrapper's in the PPDrawing
_runs = findTextRuns(_notes.getPPDrawing());
_runs = findTextRuns(getPPDrawing());
// Set the sheet on each TextRun
for (int i = 0; i < _runs.length; i++)
@ -70,15 +59,11 @@ public class Notes extends Sheet
*/
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, SlideIdentifer based) number of the
* slide we're attached to
*/
public int _getSheetNumber() { return _slideNo; }
protected PPDrawing getPPDrawing() { return _notes.getPPDrawing(); }}
/**
* Return <code>null</code> - Notes Masters are not yet supported
*/
public MasterSheet getMasterSheet() {
return null;
}
}

View File

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

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -15,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
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
* document. Such sheets could be Slides, Notes, Master etc
* document. Such sheets could be Slides, Notes, Master etc
*
* @author Nick Burch
* @author Yegor Kozlov
*/
public abstract class Sheet
{
/**
* The <code>SlideShow</code> we belong to
*/
private SlideShow _slideShow;
/**
* Returns an array of all the TextRuns in the sheet.
*/
public abstract TextRun[] getTextRuns();
public abstract class Sheet {
/**
* The <code>SlideShow</code> we belong to
*/
private SlideShow _slideShow;
/**
* 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.
*/
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);
}
}
}
/**
* Sheet background
*/
private Background _background;
/**
* 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;
}
/**
* Record container that holds sheet data.
* For slides it is org.apache.poi.hslf.record.Slide,
* for notes it is org.apache.poi.hslf.record.Notes,
* for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
*/
private SheetContainer _container;
/**
* 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;
}
private int _sheetNo;
if(trun != null) {
found.add(trun);
i++;
} else {
// Not a valid one, so skip on to next and look again
}
}
}
}
public Sheet(SheetContainer container, int sheetNo) {
_container = container;
_sheetNo = sheetNo;
}
/**
* 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();
/**
* Returns an array of all the TextRuns in the sheet.
*/
public abstract TextRun[] getTextRuns();
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();
/**
* Returns the (internal, RefID based) sheet number, as used
* to in PersistPtr stuff.
*/
public int _getSheetRefId() {
return _container.getSheetId();
}
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()]);
}
/**
* Returns the (internal, SlideIdentifier based) sheet number, as used
* to reference this sheet from other records.
*/
public int _getSheetNumber() {
return _sheetNo;
}
/**
* Add a new Shape to this Slide
*
* @param shape - the Shape to add
*/
public void addShape(Shape shape){
PPDrawing ppdrawing = getPPDrawing();
/**
* Fetch the PPDrawing from the underlying record
*/
protected PPDrawing getPPDrawing() {
return _container.getPPDrawing();
}
EscherContainerRecord dgContainer = (EscherContainerRecord)ppdrawing.getEscherRecords()[0];
EscherContainerRecord spgr = (EscherContainerRecord)Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
spgr.addChildRecord(shape.getSpContainer());
/**
* Fetch the SlideShow we're attached to
*/
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 .
*/
public MasterSheet getMasterSheet(){
return null;
}
public abstract MasterSheet getMasterSheet();
/**
* Color scheme for this sheet.
*/
public ColorSchemeAtom getColorScheme(){
return null;
public ColorSchemeAtom getColorScheme() {
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
{
private int _refSheetNo;
private int _sheetNo;
private int _slideNo;
private org.apache.poi.hslf.record.Slide _slide;
private SlideAtomsSet _atomSet;
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 Background _background;
/**
* 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
*/
public Slide(org.apache.poi.hslf.record.Slide slide, Notes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
_slide = slide;
super(slide, slideIdentifier);
_notes = notes;
_atomSet = atomSet;
_refSheetNo = slide.getSheetId();
_sheetNo = slideIdentifier;
_slideNo = slideNumber;
// Grab the TextRuns from the PPDrawing
_otherRuns = findTextRuns(_slide.getPPDrawing());
// Grab the TextRuns from the PPDrawing
TextRun[] _otherRuns = findTextRuns(getPPDrawing());
// For the text coming in from the SlideAtomsSet:
// 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
*/
public Slide(int sheetNumber, int sheetRefId, int slideNumber){
_slide = new org.apache.poi.hslf.record.Slide();
_refSheetNo = sheetRefId;
_sheetNo = sheetNumber;
super(new org.apache.poi.hslf.record.Slide(), sheetNumber);
_slideNo = slideNumber;
getSheetContainer().setSheetId(sheetRefId);
}
/**
@ -119,7 +112,7 @@ public class Slide extends Sheet
_notes = notes;
// Update the Slide Atom's ID of where to point to
SlideAtom sa = _slide.getSlideAtom();
SlideAtom sa = getSlideRecord().getSlideAtom();
if(notes == null) {
// Set to 0
@ -132,7 +125,7 @@ public class Slide extends Sheet
/**
* 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) {
_slideNo = newSlideNumber;
@ -187,17 +180,6 @@ public class Slide extends Sheet
*/
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
*/
@ -206,18 +188,15 @@ public class Slide extends Sheet
/**
* 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
*/
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
* which hold text data for this slide (typically for placeholders).
@ -225,60 +204,43 @@ public class Slide extends Sheet
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(){
SlideMaster[] master = getSlideShow().getSlidesMasters();
SlideAtom sa = _slide.getSlideAtom();
SlideAtom sa = getSlideRecord().getSlideAtom();
int masterId = sa.getMasterID();
MasterSheet sheet = null;
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.
*/
public void setMasterSheet(MasterSheet master){
SlideAtom sa = _slide.getSlideAtom();
SlideAtom sa = getSlideRecord().getSlideAtom();
int sheetNo = master._getSheetNumber();
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
*
@ -286,7 +248,7 @@ public class Slide extends Sheet
* <code>false</code> otherwise
*/
public void setFollowMasterBackground(boolean flag){
SlideAtom sa = _slide.getSlideAtom();
SlideAtom sa = getSlideRecord().getSlideAtom();
sa.setFollowMasterBackground(flag);
}
@ -297,7 +259,7 @@ public class Slide extends Sheet
* <code>false</code> otherwise
*/
public boolean getFollowMasterBackground(){
SlideAtom sa = _slide.getSlideAtom();
SlideAtom sa = getSlideRecord().getSlideAtom();
return sa.getFollowMasterBackground();
}
}

View File

@ -36,11 +36,7 @@ import java.util.Iterator;
* @author Yegor Kozlov
*/
public class SlideMaster extends MasterSheet {
private int _refSheetNo;
private int _sheetNo;
private MainMaster _master;
private TextRun[] _runs;
private Background _background;
/**
* all TxMasterStyleAtoms available in this master
@ -51,16 +47,11 @@ public class SlideMaster extends MasterSheet {
* Constructs a SlideMaster from the MainMaster record,
*
*/
public SlideMaster(org.apache.poi.hslf.record.MainMaster rec, int slideId) {
_master = rec;
public SlideMaster(MainMaster record, int sheetNo) {
super(record, sheetNo);
// Grab our internal sheet ID
_refSheetNo = rec.getSheetId();
// Grab the number of the slide we're for, via the NotesAtom
_sheetNo = slideId;
_runs = findTextRuns(_master.getPPDrawing());
_runs = findTextRuns(getPPDrawing());
for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
}
/**
@ -71,26 +62,10 @@ public class SlideMaster extends MasterSheet {
}
/**
* Returns the (internal, RefID based) sheet number, as used
* to in PersistPtr stuff.
* Returns <code>null</code> since SlideMasters doen't have master sheet.
*/
public int _getSheetRefId() {
return _refSheetNo;
}
/**
* 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();
public MasterSheet getMasterSheet() {
return null;
}
/**
@ -138,44 +113,10 @@ public class SlideMaster extends MasterSheet {
TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom();
_txmaster[txdoc.getTextType()] = txdoc;
TxMasterStyleAtom[] txrec = _master.getTxMasterStyleAtoms();
TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms();
for (int i = 0; i < txrec.length; 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
*/
public class MainMaster extends PositionDependentRecordContainer
public class MainMaster extends SheetContainer
{
private byte[] _header;
private static long _type = 1016;

View File

@ -29,7 +29,7 @@ import java.io.OutputStream;
* @author Nick Burch
*/
public class Notes extends PositionDependentRecordContainer
public class Notes extends SheetContainer
{
private byte[] _header;
private static long _type = 1008l;
@ -37,6 +37,7 @@ public class Notes extends PositionDependentRecordContainer
// Links to our more interesting children
private NotesAtom notesAtom;
private PPDrawing ppDrawing;
private ColorSchemeAtom _colorScheme;
/**
* Returns the NotesAtom of this Notes
@ -69,6 +70,9 @@ public class Notes extends PositionDependentRecordContainer
if(_children[i] instanceof PPDrawing) {
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 {
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
*/
public class Slide extends PositionDependentRecordContainer
public class Slide extends SheetContainer
{
private byte[] _header;
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.Sheet;
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.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.record.ColorSchemeAtom;
import java.awt.*;
@ -60,7 +62,7 @@ public class RichTextRun
private TextPropCollection characterStyle;
private boolean sharingParagraphStyle;
private boolean sharingCharacterStyle;
/**
* Create a new wrapper around a (currently not)
* rich text string
@ -169,7 +171,7 @@ public class RichTextRun
if (cftp == null){
Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet();
MasterSheet master = sheet.getMasterSheet();
if (master != null)
cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true);
}
@ -192,7 +194,7 @@ public class RichTextRun
fetchOrAddTextProp(characterStyle, "char_flags");
cftp.setSubValue(value,index);
}
/**
* Returns the named TextProp, either by fetching it (if it exists) or adding it
* (if it didn't)
@ -223,7 +225,7 @@ public class RichTextRun
if (prop == null){
Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet();
MasterSheet master = sheet.getMasterSheet();
if (master != null)
prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true);
}
@ -243,7 +245,7 @@ public class RichTextRun
if (prop == null){
Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType();
SlideMaster master = (SlideMaster)sheet.getMasterSheet();
MasterSheet master = sheet.getMasterSheet();
if (master != null)
prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);
}

View File

@ -74,6 +74,7 @@ public class SlideShow
// Friendly objects for people to deal with
private SlideMaster[] _masters;
private TitleMaster[] _titleMasters;
private Slide[] _slides;
private Notes[] _notes;
private FontCollection _fonts;
@ -311,25 +312,33 @@ public class SlideShow
// About the only thing you can say is that the master details are in
// the first SLWT.
SlideAtomsSet[] masterSets = new SlideAtomsSet[0];
org.apache.poi.hslf.record.MainMaster[] mainMasterRecords = null;
if (masterSLWT != null){
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 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) {
// 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) {
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()];
mmr.toArray(mainMasterRecords);
_masters = new SlideMaster[mmr.size()];
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++) {
// 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());
@ -394,14 +403,6 @@ public class SlideShow
}
// 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 = new Notes[notesRecords.length];
for(int i=0; i<_notes.length; i++) {
@ -465,10 +466,14 @@ public class SlideShow
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; }
/**
* 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
*/

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.ByteArrayInputStream;
import java.awt.*;
/**
* Tests for SlideMaster
@ -81,13 +82,63 @@ public class TestSlideMaster extends TestCase{
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
*/
public void testMasterAttributes() throws Exception {
SlideShow ppt = new SlideShow(new HSLFSlideShow(home + "/slide_master.ppt"));
Slide[] slide = ppt.getSlides();
assertEquals(2, slide.length);
assertEquals(3, slide.length);
TextRun[] trun;
trun = slide[0].getTextRuns();

View File

@ -163,4 +163,25 @@ public class TestBugs extends TestCase {
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);
}
}
}