<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45590 - Fix for Header/footer extraction for .ppt files saved in Office 2007</action>
<action dev="POI-DEVELOPERS" type="fix">Big improvement in how HWPF handles unicode text, and more sanity checking of text ranges within HWPF</action>
<action dev="POI-DEVELOPERS" type="add">Include headers and footers int he extracted text from HWPF's WordExtractor</action>
<action dev="POI-DEVELOPERS" type="add">Added support to HWPF for headers and footers</action>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45590 - Fix for Header/footer extraction for .ppt files saved in Office 2007</action>
<action dev="POI-DEVELOPERS" type="fix">Big improvement in how HWPF handles unicode text, and more sanity checking of text ranges within HWPF</action>
<action dev="POI-DEVELOPERS" type="add">Include headers and footers int he extracted text from HWPF's WordExtractor</action>
<action dev="POI-DEVELOPERS" type="add">Added support to HWPF for headers and footers</action>
private HeadersFootersContainer _container;\r
private boolean _newRecord;\r
private SlideShow _ppt;\r
+ private Sheet _sheet;\r
+ private boolean _ppt2007;\r
\r
- public HeadersFooters(HeadersFootersContainer rec, SlideShow ppt, boolean newRecord){\r
+\r
+ public HeadersFooters(HeadersFootersContainer rec, SlideShow ppt, boolean newRecord, boolean isPpt2007){\r
_container = rec;\r
_newRecord = newRecord;\r
_ppt = ppt;\r
+ _ppt2007 = isPpt2007;\r
+ }\r
+\r
+ public HeadersFooters(HeadersFootersContainer rec, Sheet sheet, boolean newRecord, boolean isPpt2007){\r
+ _container = rec;\r
+ _newRecord = newRecord;\r
+ _sheet = sheet;\r
+ _ppt2007 = isPpt2007;\r
}\r
\r
/**\r
* @return Headers's text\r
*/\r
public String getHeaderText(){\r
- CString cs = _container.getHeaderAtom();\r
- return cs == null ? null : cs.getText();\r
+ CString cs = _container == null ? null : _container.getHeaderAtom();\r
+ return getPlaceholderText(OEPlaceholderAtom.MasterHeader, cs);\r
}\r
\r
/**\r
* @return Footer's text\r
*/\r
public String getFooterText(){\r
- CString cs = _container.getFooterAtom();\r
- return cs == null ? null : cs.getText();\r
+ CString cs = _container == null ? null : _container.getFooterAtom();\r
+ return getPlaceholderText(OEPlaceholderAtom.MasterFooter, cs);\r
}\r
\r
/**\r
* @return custom user date\r
*/\r
public String getDateTimeText(){\r
- CString cs = _container.getUserDateAtom();\r
- return cs == null ? null : cs.getText();\r
+ CString cs = _container == null ? null : _container.getUserDateAtom();\r
+ return getPlaceholderText(OEPlaceholderAtom.MasterDate, cs);\r
}\r
\r
/**\r
* whether the footer text is displayed.\r
*/\r
public boolean isFooterVisible(){\r
- return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasFooter);\r
+ return isVisible(HeadersFootersAtom.fHasFooter, OEPlaceholderAtom.MasterFooter);\r
}\r
\r
/**\r
* whether the header text is displayed.\r
*/\r
public boolean isHeaderVisible(){\r
- return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasHeader);\r
+ return isVisible(HeadersFootersAtom.fHasHeader, OEPlaceholderAtom.MasterHeader);\r
}\r
\r
/**\r
* whether the date is displayed in the footer.\r
*/\r
public boolean isDateTimeVisible(){\r
- return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasDate);\r
+ return isVisible(HeadersFootersAtom.fHasDate, OEPlaceholderAtom.MasterDate);\r
}\r
\r
/**\r
* whether the custom user date is used instead of today's date.\r
*/\r
public boolean isUserDateVisible(){\r
- return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasUserDate);\r
+ return isVisible(HeadersFootersAtom.fHasUserDate, OEPlaceholderAtom.MasterDate);\r
}\r
\r
/**\r
* whether the slide number is displayed in the footer.\r
*/\r
public boolean isSlideNumberVisible(){\r
- return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasSlideNumber);\r
+ return isVisible(HeadersFootersAtom.fHasSlideNumber, OEPlaceholderAtom.MasterSlideNumber);\r
}\r
\r
/**\r
doc.addChildAfter(_container, lst);\r
_newRecord = false;\r
}\r
+\r
+ private boolean isVisible(int flag, int placeholderId){\r
+ boolean visible;\r
+ if(_ppt2007){\r
+ Sheet master = _sheet != null ? _sheet : _ppt.getSlidesMasters()[0];\r
+ TextShape placeholder = master.getPlaceholder(placeholderId);\r
+ visible = placeholder != null && placeholder.getText() != null;\r
+ } else {\r
+ visible = _container.getHeadersFootersAtom().getFlag(flag);\r
+ }\r
+ return visible;\r
+ }\r
+\r
+ private String getPlaceholderText(int placeholderId, CString cs){\r
+ String text = null;\r
+ if(_ppt2007){\r
+ Sheet master = _sheet != null ? _sheet : _ppt.getSlidesMasters()[0];\r
+ TextShape placeholder = master.getPlaceholder(placeholderId);\r
+ if(placeholder != null) text = placeholder.getText();\r
+\r
+ //default text in master placeholders is not visible\r
+ if("*".equals(text)) text = null;\r
+ } else {\r
+ text = cs == null ? null : cs.getText();\r
+ }\r
+ return text;\r
+ }\r
+\r
}\r
import org.apache.poi.hslf.record.SheetContainer;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.record.OEPlaceholderAtom;
import org.apache.poi.hslf.model.textproperties.TextProp;
/**
return tx.getPlaceholderAtom() != null;
}
- /**
- * Return placeholder by text type
- */
- public TextShape getPlaceholder(int type){
- Shape[] shape = getShapes();
- for (int i = 0; i < shape.length; i++) {
- if(shape[i] instanceof TextShape){
- TextShape tx = (TextShape)shape[i];
- TextRun run = tx.getTextRun();
- if(run != null && run.getRunType() == type){
- return tx;
- }
- }
- }
- return null;
- }
}
public void draw(Graphics2D graphics){
}
+
+ /**
+ * Return placeholder by text type
+ *
+ * @param type type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom}
+ * @return <code>TextShape</code> or <code>null</code>
+ */
+ public TextShape getPlaceholderByTextType(int type){
+ Shape[] shape = getShapes();
+ for (int i = 0; i < shape.length; i++) {
+ if(shape[i] instanceof TextShape){
+ TextShape tx = (TextShape)shape[i];
+ TextRun run = tx.getTextRun();
+ if(run != null && run.getRunType() == type){
+ return tx;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Search text placeholer by its type
+ *
+ * @param type type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
+ * @return <code>TextShape</code> or <code>null</code>
+ */
+ public TextShape getPlaceholder(int type){
+ Shape[] shape = getShapes();
+ for (int i = 0; i < shape.length; i++) {
+ if(shape[i] instanceof TextShape){
+ TextShape tx = (TextShape)shape[i];
+ int placeholderId = 0;
+ OEPlaceholderAtom oep = tx.getPlaceholderAtom();
+ if(oep != null) {
+ placeholderId = oep.getPlaceholderId();
+ } else {
+ //special case for files saved in Office 2007
+ RoundTripHFPlaceholder12 hldr = (RoundTripHFPlaceholder12)tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
+ if(hldr != null) placeholderId = hldr.getPlaceholderId();
+ }
+ if(placeholderId == type){
+ return tx;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return programmable tag associated with this sheet, e.g. <code>___PPT12</code>.
+ *
+ * @return programmable tag associated with this sheet.
+ */
+ public String getProgrammableTag(){
+ String tag = null;
+ RecordContainer progTags = (RecordContainer)
+ getSheetContainer().findFirstOfType(
+ RecordTypes.ProgTags.typeID
+ );
+ if(progTags != null) {
+ RecordContainer progBinaryTag = (RecordContainer)
+ progTags.findFirstOfType(
+ RecordTypes.ProgBinaryTag.typeID
+ );
+ if(progBinaryTag != null) {
+ CString binaryTag = (CString)
+ progBinaryTag.findFirstOfType(
+ RecordTypes.CString.typeID
+ );
+ if(binaryTag != null) tag = binaryTag.getText();
+ }
+ }
+
+ return tag;
+
+ }
+
+
}
public HeadersFooters getHeadersFooters(){
HeadersFootersContainer hdd = null;
Record[] ch = getSheetContainer().getChildRecords();
+ boolean ppt2007 = false;
for (int i = 0; i < ch.length; i++) {
if(ch[i] instanceof HeadersFootersContainer){
hdd = (HeadersFootersContainer)ch[i];
- break;
+ } else if (ch[i].getRecordType() == RecordTypes.RoundTripContentMasterId.typeID){
+ ppt2007 = true;
}
}
boolean newRecord = false;
- if(hdd == null) return getSlideShow().getSlideHeadersFooters();
- else return new HeadersFooters(hdd, getSlideShow(), newRecord);
+ if(hdd == null && !ppt2007) {
+ return getSlideShow().getSlideHeadersFooters();
+ }
+ else {
+ if(hdd == null) {
+ hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
+ newRecord = true;
+ }
+ return new HeadersFooters(hdd, this, newRecord, ppt2007);
+ }
}
}
int type = getTextRun().getRunType();
MasterSheet master = getSheet().getMasterSheet();
if(master != null){
- TextShape masterShape = master.getPlaceholder(type);
+ TextShape masterShape = master.getPlaceholderByTextType(type);
if(masterShape != null) valign = masterShape.getVerticalAlignment();
} else {
//not found in the master sheet. Use the hardcoded defaults.
/**
* OEPlaceholderAtom (3011).
* <p>
- * Atom that describes the placeholder.
+ * An atom record that specifies whether a shape is a placeholder shape.
* </p>
*
* @author Yegor Kozlov
public class OEPlaceholderAtom extends RecordAtom{
+ /**
+ * The full size of the master body text placeholder shape.
+ */
public static final int PLACEHOLDER_FULLSIZE = 0;
+
+ /**
+ * Half of the size of the master body text placeholder shape.
+ */
public static final int PLACEHOLDER_HALFSIZE = 1;
+
+ /**
+ * A quarter of the size of the master body text placeholder shape.
+ */
public static final int PLACEHOLDER_QUARTSIZE = 2;
+ /**
+ * MUST NOT be used for this field.
+ */
public static final byte None = 0;
+ /**
+ * The corresponding shape contains the master title text.
+ * The corresponding slide MUST be a main master slide.
+ */
public static final byte MasterTitle = 1;
+ /**
+ * The corresponding shape contains the master body text.
+ * The corresponding slide MUST be a main master slide.
+ */
public static final byte MasterBody = 2;
+ /**
+ * The corresponding shape contains the master center title text.
+ * The corresponding slide MUST be a title master slide.
+ */
public static final byte MasterCenteredTitle = 3;
- public static final byte MasterNotesSlideImage = 4;
+ /**
+ * The corresponding shape contains the master sub-title text.
+ * The corresponding slide MUST be a title master slide.
+ */
+ public static final byte MasterSubTitle = 4;
- public static final byte MasterNotesBodyImage = 5;
+ /**
+ * The corresponding shape contains the shared properties for slide image shapes.
+ * The corresponding slide MUST be a notes master slide.
+ */
+ public static final byte MasterNotesSlideImage = 5;
- public static final byte MasterDate = 6;
+ /**
+ * The corresponding shape contains the master body text.
+ * The corresponding slide MUST be a notes master slide.
+ */
+ public static final byte MasterNotesBody = 6;
- public static final byte MasterSlideNumber = 7;
+ /**
+ * The corresponding shape contains the date text field.
+ * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
+ */
+ public static final byte MasterDate = 7;
- public static final byte MasterFooter = 8;
+ /**
+ * The corresponding shape contains a slide number text field.
+ * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
+ */
+ public static final byte MasterSlideNumber = 8;
- public static final byte MasterHeader = 9;
+ /**
+ * The corresponding shape contains a footer text field.
+ * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide.
+ */
+ public static final byte MasterFooter = 9;
- public static final byte MasterSubtitle = 10;
+ /**
+ * The corresponding shape contains a header text field.
+ * The corresponding slide must be a notes master slide or handout master slide.
+ */
+ public static final byte MasterHeader = 10;
- public static final byte GenericTextObject = 11;
+ /**
+ * The corresponding shape contains a presentation slide image.
+ * The corresponding slide MUST be a notes slide.
+ */
+ public static final byte NotesSlideImage = 11;
- public static final byte Title = 12;
+ /**
+ * The corresponding shape contains the notes text.
+ * The corresponding slide MUST be a notes slide.
+ */
+ public static final byte NotesBody = 12;
- public static final byte Body = 13;
+ /**
+ * The corresponding shape contains the title text.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte Title = 13;
- public static final byte NotesBody = 14;
+ /**
+ * The corresponding shape contains the body text.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte Body = 14;
+ /**
+ * The corresponding shape contains the title text.
+ * The corresponding slide MUST be a presentation slide.
+ */
public static final byte CenteredTitle = 15;
+ /**
+ * The corresponding shape contains the sub-title text.
+ * The corresponding slide MUST be a presentation slide.
+ */
public static final byte Subtitle = 16;
+ /**
+ * The corresponding shape contains the title text with vertical text flow.
+ * The corresponding slide MUST be a presentation slide.
+ */
public static final byte VerticalTextTitle = 17;
+ /**
+ * The corresponding shape contains the body text with vertical text flow.
+ * The corresponding slide MUST be a presentation slide.
+ */
public static final byte VerticalTextBody = 18;
- public static final byte NotesSlideImage = 19;
-
- public static final byte Object = 20;
+ /**
+ * The corresponding shape contains a generic object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte Object = 19;
- public static final byte Graph = 21;
+ /**
+ * The corresponding shape contains a chart object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte Graph = 20;
- public static final byte Table = 22;
+ /**
+ * The corresponding shape contains a table object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte Table = 21;
- public static final byte ClipArt = 23;
+ /**
+ * The corresponding shape contains a clipart object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte ClipArt = 22;
- public static final byte OrganizationChart = 24;
+ /**
+ * The corresponding shape contains an organization chart object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte OrganizationChart = 23;
- public static final byte MediaClip = 25;
+ /**
+ * The corresponding shape contains a media object.
+ * The corresponding slide MUST be a presentation slide.
+ */
+ public static final byte MediaClip = 24;
private byte[] _header;
*/
protected OEPlaceholderAtom(byte[] source, int start, int len) {
_header = new byte[8];
- System.arraycopy(source,start,_header,0,8);
+ int offset = start;
+ System.arraycopy(source,start,_header,0,8);
+ offset += _header.length;
- placementId = LittleEndian.getInt(source, start);
- placeholderId = LittleEndian.getUnsignedByte(source, start+4);
- placeholderSize = LittleEndian.getUnsignedByte(source, start+5);
+ placementId = LittleEndian.getInt(source, offset); offset += 4;
+ placeholderId = LittleEndian.getUnsignedByte(source, offset); offset++;
+ placeholderSize = LittleEndian.getUnsignedByte(source, offset); offset++;
}
/**
/**
* Returns the placement Id.
+ * <p>
+ * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
+ * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
+ * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.
+ * </p>
*
* @return the placement Id.
*/
/**
* Sets the placement Id.
+ * <p>
+ * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
+ * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
+ * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.
+ * </p>
*
* @param id the placement Id.
*/
/**
* Returns the placeholder Id.
*
+ * <p>
+ * placeholder Id specifies the type of the placeholder shape.
+ * The value MUST be one of the static constants defined in this class
+ * </p>
+ *
* @return the placeholder Id.
*/
public int getPlaceholderId(){
/**
* Sets the placeholder Id.
*
+ * <p>
+ * placeholder Id specifies the type of the placeholder shape.
+ * The value MUST be one of the static constants defined in this class
+ * </p>
* @param id the placeholder Id.
*/
public void setPlaceholderId(byte id){
// Records ~12050 seem to be related to Document Encryption
public static final Type DocumentEncryptionAtom = new Type(12052,DocumentEncryptionAtom.class);
+ public static final Type OriginalMainMasterId = new Type(1052,null);
+ public static final Type CompositeMasterId = new Type(1052,null);
+ public static final Type RoundTripContentMasterInfo12 = new Type(1054,null);
+ public static final Type RoundTripShapeId12 = new Type(1055,null);
+ public static final Type RoundTripHFPlaceholder12 = new Type(1056,RoundTripHFPlaceholder12.class);
+ public static final Type RoundTripContentMasterId = new Type(1058,null);
+ public static final Type RoundTripOArtTextStyles12 = new Type(1059,null);
+ public static final Type RoundTripShapeCheckSumForCustomLayouts12 = new Type(1062,null);
+ public static final Type RoundTripNotesMasterTextStyles12 = new Type(1063,null);
+ public static final Type RoundTripCustomTableStyles12 = new Type(1064,null);
+
//records greater then 0xF000 belong to with Microsoft Office Drawing format also known as Escher
public static final int EscherDggContainer = 0xf000;
public static final int EscherDgg = 0xf006;
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+ \r
+\r
+package org.apache.poi.hslf.record;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.util.Date;\r
+\r
+import org.apache.poi.hslf.util.SystemTimeUtils;\r
+import org.apache.poi.util.LittleEndian;\r
+\r
+/**\r
+ * An atom record that specifies that a shape is a header or footer placeholder shape\r
+ *\r
+ * @since PowerPoint 2007\r
+ * @author Yegor Kozlov\r
+ */\r
+\r
+public class RoundTripHFPlaceholder12 extends RecordAtom\r
+{\r
+ /**\r
+ * Record header.\r
+ */\r
+ private byte[] _header;\r
+\r
+ /**\r
+ * Specifies the placeholder shape ID.\r
+ *\r
+ * MUST be {@link OEPlaceholderAtom#MasterDate}, {@link OEPlaceholderAtom#MasterSlideNumber}, \r
+ * {@link OEPlaceholderAtom#MasterFooter}, or {@link OEPlaceholderAtom#MasterHeader}\r
+ */\r
+ private byte _placeholderId;\r
+\r
+ /**\r
+ * Constructs the comment atom record from its source data.\r
+ *\r
+ * @param source the source data as a byte array.\r
+ * @param start the start offset into the byte array.\r
+ * @param len the length of the slice in the byte array.\r
+ */\r
+ protected RoundTripHFPlaceholder12(byte[] source, int start, int len) {\r
+ // Get the header.\r
+ _header = new byte[8];\r
+ System.arraycopy(source,start,_header,0,8);\r
+\r
+ // Get the record data.\r
+ _placeholderId = source[start+8];\r
+ }\r
+\r
+ /**\r
+ * Gets the comment number (note - each user normally has their own count).\r
+ * @return the comment number.\r
+ */\r
+ public int getPlaceholderId() {\r
+ return _placeholderId;\r
+ }\r
+\r
+ /**\r
+ * Sets the comment number (note - each user normally has their own count).\r
+ * @param number the comment number.\r
+ */\r
+ public void setPlaceholderId(int number) {\r
+ _placeholderId = (byte)number;\r
+ }\r
+\r
+ /**\r
+ * Gets the record type.\r
+ * @return the record type.\r
+ */\r
+ public long getRecordType() { return RecordTypes.RoundTripHFPlaceholder12.typeID; }\r
+\r
+ /**\r
+ * Write the contents of the record back, so it can be written\r
+ * to disk\r
+ *\r
+ * @param out the output stream to write to.\r
+ * @throws java.io.IOException if an error occurs.\r
+ */\r
+ public void writeOut(OutputStream out) throws IOException {\r
+ out.write(_header);\r
+ out.write(_placeholderId);\r
+ }\r
+}
\ No newline at end of file
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.model.HeadersFooters;
-import org.apache.poi.hslf.model.Notes;
-import org.apache.poi.hslf.model.PPFont;
-import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
-import org.apache.poi.hslf.model.Slide;
-import org.apache.poi.hslf.model.SlideMaster;
-import org.apache.poi.hslf.model.TitleMaster;
+import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.record.DocumentAtom;
import org.apache.poi.hslf.record.FontCollection;
* @return Header / Footer settings for slides
*/
public HeadersFooters getSlideHeadersFooters(){
+ //detect if this ppt was saved in Office2007
+ String tag = getSlidesMasters()[0].getProgrammableTag();
+ boolean ppt2007 = "___PPT12".equals(tag);
+
HeadersFootersContainer hdd = null;
Record[] ch = _documentRecord.getChildRecords();
for (int i = 0; i < ch.length; i++) {
hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
newRecord = true;
}
- return new HeadersFooters(hdd, this, newRecord);
+ return new HeadersFooters(hdd, this, newRecord, ppt2007);
}
/**
* @return Header / Footer settings for notes
*/
public HeadersFooters getNotesHeadersFooters(){
+ //detect if this ppt was saved in Office2007
+ String tag = getSlidesMasters()[0].getProgrammableTag();
+ boolean ppt2007 = "___PPT12".equals(tag);
+
HeadersFootersContainer hdd = null;
Record[] ch = _documentRecord.getChildRecords();
for (int i = 0; i < ch.length; i++) {
((HeadersFootersContainer)ch[i]).getOptions() == HeadersFootersContainer.NotesHeadersFootersContainer){
hdd = (HeadersFootersContainer)ch[i];
break;
- }
+ }
}
boolean newRecord = false;
if(hdd == null) {
hdd = new HeadersFootersContainer(HeadersFootersContainer.NotesHeadersFootersContainer);
newRecord = true;
}
- return new HeadersFooters(hdd, this, newRecord);
+ if(ppt2007 && _notes.length > 0){
+ return new HeadersFooters(hdd, _notes[0], newRecord, ppt2007);
+ } else {
+ return new HeadersFooters(hdd, this, newRecord, ppt2007);
+ }
}
+
}
assertEquals("custom date format", hd2.getDateTimeText());\r
}\r
\r
+ /**\r
+ * If Headers / Footers are not set, all the getters should return <code>false</code> or <code>null</code>\r
+ */\r
+ public void testReadNoHeadersFooters() throws Exception\r
+ {\r
+ File file = new File(cwd, "basic_test_ppt_file.ppt");\r
+ FileInputStream is = new FileInputStream(file);\r
+ SlideShow ppt = new SlideShow(is);\r
+ is.close();\r
+\r
+ HeadersFooters slideHdd = ppt.getSlideHeadersFooters();\r
+ assertFalse(slideHdd.isFooterVisible());\r
+ assertNull(slideHdd.getFooterText());\r
+ assertFalse(slideHdd.isSlideNumberVisible());\r
+ assertFalse(slideHdd.isHeaderVisible());\r
+ assertNull(slideHdd.getHeaderText());\r
+ assertFalse(slideHdd.isUserDateVisible());\r
+ assertNull(slideHdd.getDateTimeText());\r
+\r
+\r
+ HeadersFooters notesHdd = ppt.getNotesHeadersFooters();\r
+ assertFalse(notesHdd.isFooterVisible());\r
+ assertNull(notesHdd.getFooterText());\r
+ assertFalse(notesHdd.isHeaderVisible());\r
+ assertNull(notesHdd.getHeaderText());\r
+ assertFalse(notesHdd.isUserDateVisible());\r
+ assertNull(notesHdd.getDateTimeText());\r
+\r
+ Slide[] slide = ppt.getSlides();\r
+ for(int i=0 ; i < slide.length; i++){\r
+ HeadersFooters hd1 = slide[i].getHeadersFooters();\r
+ assertFalse(hd1.isFooterVisible());\r
+ assertNull(hd1.getFooterText());\r
+ assertFalse(hd1.isHeaderVisible());\r
+ assertNull(hd1.getHeaderText());\r
+ assertFalse(hd1.isUserDateVisible());\r
+ assertNull(hd1.getDateTimeText());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Test extraction of headers / footers from PPTs saved in Office 2007\r
+ */\r
+ public void testRead2007() throws Exception\r
+ {\r
+ File file = new File(cwd, "headers_footers_2007.ppt");\r
+ FileInputStream is = new FileInputStream(file);\r
+ SlideShow ppt = new SlideShow(is);\r
+ is.close();\r
+\r
+ HeadersFooters slideHdd = ppt.getSlideHeadersFooters();\r
+ assertTrue(slideHdd.isFooterVisible());\r
+ assertEquals("THE FOOTER TEXT", slideHdd.getFooterText());\r
+ assertTrue(slideHdd.isSlideNumberVisible());\r
+ assertFalse(slideHdd.isHeaderVisible());\r
+ assertNull(slideHdd.getHeaderText());\r
+ assertTrue(slideHdd.isUserDateVisible());\r
+ assertEquals("Wednesday, August 06, 2008", slideHdd.getDateTimeText());\r
+\r
+\r
+ HeadersFooters notesHdd = ppt.getNotesHeadersFooters();\r
+ assertTrue(notesHdd.isFooterVisible());\r
+ assertEquals("THE NOTES FOOTER TEXT", notesHdd.getFooterText());\r
+ assertTrue(notesHdd.isHeaderVisible());\r
+ assertEquals("THE NOTES HEADER TEXT", notesHdd.getHeaderText());\r
+ assertTrue(notesHdd.isUserDateVisible());\r
+ assertTrue(notesHdd.isDateTimeVisible());\r
+ //TODO: depending on the formatId getDateTimeText() should return formatted date\r
+ //assertEquals("08/12/08", notesHdd.getDateTimeText());\r
+\r
+ //per-slide headers / footers\r
+ Slide[] slide = ppt.getSlides();\r
+ //the first slide uses presentation-scope headers / footers\r
+ HeadersFooters hd1 = slide[0].getHeadersFooters();\r
+ assertTrue(hd1.isFooterVisible());\r
+ assertEquals("THE FOOTER TEXT", hd1.getFooterText());\r
+ assertTrue(hd1.isSlideNumberVisible());\r
+ assertFalse(hd1.isHeaderVisible());\r
+ assertNull(hd1.getHeaderText());\r
+ assertTrue(hd1.isUserDateVisible());\r
+ assertTrue(hd1.isDateTimeVisible());\r
+ assertEquals("Wednesday, August 06, 2008", hd1.getDateTimeText());\r
+\r
+ //the second slide uses custom per-slide headers / footers\r
+ HeadersFooters hd2 = slide[1].getHeadersFooters();\r
+ assertTrue(hd2.isFooterVisible());\r
+ assertEquals("THE FOOTER TEXT FOR SLIDE 2", hd2.getFooterText());\r
+ assertTrue(hd2.isSlideNumberVisible());\r
+ assertFalse(hd2.isHeaderVisible());\r
+ assertNull(hd2.getHeaderText());\r
+ assertTrue(hd2.isUserDateVisible());\r
+ assertTrue(hd2.isDateTimeVisible());\r
+ assertEquals("August 06, 2008", hd2.getDateTimeText());\r
+\r
+ //the third slide uses per-slide headers / footers\r
+ HeadersFooters hd3 = slide[2].getHeadersFooters();\r
+ assertTrue(hd3.isFooterVisible());\r
+ assertEquals("THE FOOTER TEXT", hd3.getFooterText());\r
+ assertTrue(hd3.isSlideNumberVisible());\r
+ assertFalse(hd3.isHeaderVisible());\r
+ assertNull(hd3.getHeaderText());\r
+ assertTrue(hd3.isUserDateVisible());\r
+ assertTrue(hd3.isDateTimeVisible());\r
+ assertEquals("Wednesday, August 06, 2008", hd3.getDateTimeText());\r
+ }\r
+\r
public void testCreateSlideFooters() throws Exception\r
{\r
SlideShow ppt = new SlideShow();\r