diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java index 6c013e9bb..4371e2a37 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java @@ -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) ; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Notes.java b/src/scratchpad/src/org/apache/poi/hslf/model/Notes.java index 20547571f..44fb80630 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Notes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Notes.java @@ -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 null - Notes Masters are not yet supported + */ + public MasterSheet getMasterSheet() { + return null; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index 40f59eb0f..66c95e50c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -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) diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index e9953cd78..c53f7f9ed 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -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 SlideShow 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 SlideShow 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; iSlideListWithtext 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 * false 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 * false otherwise */ public boolean getFollowMasterBackground(){ - SlideAtom sa = _slide.getSlideAtom(); + SlideAtom sa = getSlideRecord().getSlideAtom(); return sa.getFollowMasterBackground(); } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java index 5489e4bfd..e442ae304 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java @@ -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 null 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; - } - } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java b/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java new file mode 100644 index 000000000..9b5e8bfc4 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java @@ -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; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java b/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java index 728d8fca2..2915040e1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/MainMaster.java @@ -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; diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java index de3eec62a..4c66e12ad 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java @@ -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; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java new file mode 100644 index 000000000..1f0ece601 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SheetContainer.java @@ -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(); + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java b/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java index 2b12507e3..26bdfc804 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Slide.java @@ -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; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java index 99515198e..a9028cfab 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java @@ -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); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java index 3b464f2f3..e77f9ff13 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -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; iSheet 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()); + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java index 3a5d61ea5..9a733b565 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java @@ -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(); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index 21540fb5e..8a5a16c59 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -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); + } + } + }