<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Support for Headers / Footers in HSLF</action>
<action dev="POI-DEVELOPERS" type="fix">44953 - Extensive fixes for data validation</action>
<action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
<li><link href="#Freeform">How to create shapes of arbitrary geometry</link></li>
<li><link href="#Graphics2D">Shapes and Graphics2D</link></li>
<li><link href="#Render">How to convert slides into images</link></li>
+ <li><link href="#HeadersFooters">Headers / Footers</link></li>
</ul>
</section>
<section><title>Features</title>
</section>
</section>
+ <anchor id="HeadersFooters"/>
+ <section><title>How to extract Headers / Footers from an existing presentation</title>
+ <source>
+
+ FileInputStream is = new FileInputStream("slideshow.ppt");
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+ Slide[] slides = ppt.getSlides();
+
+ //presentation-scope headers / footers
+ HeadersFooters hdd = ppt.getSlideHeadersFooters();
+ if(hdd.isFooterVisible()) {
+ String footerText = hdd.getFooterText();
+ }
+
+ //per-slide headers / footers
+ for (int i=0; i < slides.length; i++){
+ HeadersFooters hdd2 = slides[i].getHeadersFooters();
+ if(hdd2.isFooterVisible()) {
+ String footerText = hdd2.getFooterText();
+ }
+ if(hdd2.isUserDateVisible()) {
+ String customDate = hdd2.getDateTimeText();
+ }
+ if(hdd2.isSlideNumberVisible()){
+ int slideNUm = slides[i].getSlideNumber();
+ }
+
+ }
+ </source>
+ </section>
+ <section><title>How to set Headers / Footers</title>
+ <source>
+
+ SlideShow ppt = new SlideShow();
+
+ //presentation-scope headers / footers
+ HeadersFooters hdd = ppt.getSlideHeadersFooters();
+ hdd.setSlideNumberVisible(true);
+ hdd.setFootersText("Created by POI-HSLF");
+ </source>
+ </section>
</section>
</body>
</document>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Support for Headers / Footers in HSLF</action>
<action dev="POI-DEVELOPERS" type="fix">44953 - Extensive fixes for data validation</action>
<action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
--- /dev/null
+/* ====================================================================
+ 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.examples;
+
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.hslf.model.HeadersFooters;
+import org.apache.poi.hslf.model.Slide;
+
+import java.io.FileOutputStream;
+
+/**
+ * Demonstrates how to set headers / footers
+ *
+ * @author Yegor Kozlov
+ */
+public class HeadersFootersDemo {
+ public static void main(String[] args) throws Exception {
+ SlideShow ppt = new SlideShow();
+
+ HeadersFooters slideHeaders = ppt.getSlideHeadersFooters();
+ slideHeaders.setFootersText("Created by POI-HSLF");
+ slideHeaders.setSlideNumberVisible(true);
+ slideHeaders.setDateTimeText("custom date time");
+
+ HeadersFooters notesHeaders = ppt.getNotesHeadersFooters();
+ notesHeaders.setFootersText("My notes footers");
+ notesHeaders.setHeaderText("My notes header");
+
+ Slide slide = ppt.createSlide();
+
+ FileOutputStream out = new FileOutputStream("headers_footers.ppt");
+ ppt.write(out);
+ out.close();
+
+ }
+
+}
--- /dev/null
+\r
+/* ====================================================================\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
+package org.apache.poi.hslf.model;\r
+\r
+import org.apache.poi.hslf.record.*;\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+\r
+/**\r
+ * Header / Footer settings.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class HeadersFooters {\r
+\r
+ private HeadersFootersContainer _container;\r
+ private boolean _newRecord;\r
+ private SlideShow _ppt;\r
+\r
+ public HeadersFooters(HeadersFootersContainer rec, SlideShow ppt, boolean newRecord){\r
+ _container = rec;\r
+ _newRecord = newRecord;\r
+ _ppt = ppt;\r
+ }\r
+\r
+ /**\r
+ * Headers's text\r
+ *\r
+ * @return Headers's text\r
+ */\r
+ public String getHeaderText(){\r
+ CString cs = _container.getHeaderAtom();\r
+ return cs == null ? null : cs.getText();\r
+ }\r
+\r
+ /**\r
+ * Sets headers's text\r
+ *\r
+ * @param text headers's text\r
+ */\r
+ public void setHeaderText(String text){\r
+ if(_newRecord) attach();\r
+\r
+ setHeaderVisible(true);\r
+ CString cs = _container.getHeaderAtom();\r
+ if(cs == null) cs = _container.addHeaderAtom();\r
+\r
+ cs.setText(text);\r
+ }\r
+\r
+ /**\r
+ * Footer's text\r
+ *\r
+ * @return Footer's text\r
+ */\r
+ public String getFooterText(){\r
+ CString cs = _container.getFooterAtom();\r
+ return cs == null ? null : cs.getText();\r
+ }\r
+\r
+ /**\r
+ * Sets footers's text\r
+ *\r
+ * @param text footers's text\r
+ */\r
+ public void setFootersText(String text){\r
+ if(_newRecord) attach();\r
+\r
+ setFooterVisible(true);\r
+ CString cs = _container.getFooterAtom();\r
+ if(cs == null) cs = _container.addFooterAtom();\r
+\r
+ cs.setText(text);\r
+ }\r
+\r
+ /**\r
+ * This is the date that the user wants in the footers, instead of today's date.\r
+ *\r
+ * @return custom user date\r
+ */\r
+ public String getDateTimeText(){\r
+ CString cs = _container.getUserDateAtom();\r
+ return cs == null ? null : cs.getText();\r
+ }\r
+\r
+ /**\r
+ * Sets custom user date to be displayed instead of today's date.\r
+ *\r
+ * @param text custom user date\r
+ */\r
+ public void setDateTimeText(String text){\r
+ if(_newRecord) attach();\r
+\r
+ setUserDateVisible(true);\r
+ setDateTimeVisible(true);\r
+ CString cs = _container.getUserDateAtom();\r
+ if(cs == null) cs = _container.addUserDateAtom();\r
+\r
+ cs.setText(text);\r
+ }\r
+\r
+ /**\r
+ * whether the footer text is displayed.\r
+ */\r
+ public boolean isFooterVisible(){\r
+ return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasFooter);\r
+ }\r
+\r
+ /**\r
+ * whether the footer text is displayed.\r
+ */\r
+ public void setFooterVisible(boolean flag){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasFooter, flag);\r
+ }\r
+\r
+ /**\r
+ * whether the header text is displayed.\r
+ */\r
+ public boolean isHeaderVisible(){\r
+ return _container.getHeadersFootersAtom().getFlag(HeadersFootersAtom.fHasHeader);\r
+ }\r
+\r
+ /**\r
+ * whether the header text is displayed.\r
+ */\r
+ public void setHeaderVisible(boolean flag){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasHeader, flag);\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
+ }\r
+\r
+ /**\r
+ * whether the date is displayed in the footer.\r
+ */\r
+ public void setDateTimeVisible(boolean flag){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasDate, flag);\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
+ }\r
+\r
+ /**\r
+ * whether the date is displayed in the footer.\r
+ */\r
+ public void setUserDateVisible(boolean flag){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasUserDate, flag);\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
+ }\r
+\r
+ /**\r
+ * whether the slide number is displayed in the footer.\r
+ */\r
+ public void setSlideNumberVisible(boolean flag){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasSlideNumber, flag);\r
+ }\r
+\r
+ /**\r
+ * An integer that specifies the format ID to be used to style the datetime.\r
+ *\r
+ * @return an integer that specifies the format ID to be used to style the datetime.\r
+ */\r
+ public int getDateTimeFormat(){\r
+ return _container.getHeadersFootersAtom().getFormatId();\r
+ }\r
+\r
+ /**\r
+ * An integer that specifies the format ID to be used to style the datetime.\r
+ *\r
+ * @param formatId an integer that specifies the format ID to be used to style the datetime.\r
+ */\r
+ public void setDateTimeFormat(int formatId){\r
+ if(_newRecord) attach();\r
+ _container.getHeadersFootersAtom().setFormatId(formatId);\r
+ }\r
+\r
+ /**\r
+ * Attach this HeadersFootersContainer to the parent Document record\r
+ */\r
+ private void attach(){\r
+ Document doc = _ppt.getDocumentRecord();\r
+ Record[] ch = doc.getChildRecords();\r
+ Record lst = null;\r
+ for (int i=0; i < ch.length; i++){\r
+ if(ch[i].getRecordType() == RecordTypes.List.typeID){\r
+ lst = ch[i];\r
+ break;\r
+ }\r
+ }\r
+ doc.addChildAfter(_container, lst);\r
+ _newRecord = false;\r
+ }\r
+}\r
import java.util.Iterator;
import java.awt.*;
-import org.apache.poi.hslf.record.SlideAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.record.*;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherContainerRecord;
}
}
+ /**
+ * Header / Footer settings for this slide.
+ *
+ * @return Header / Footer settings for this slide
+ */
+ public HeadersFooters getHeadersFooters(){
+ HeadersFootersContainer hdd = null;
+ Record[] ch = getSheetContainer().getChildRecords();
+ for (int i = 0; i < ch.length; i++) {
+ if(ch[i] instanceof HeadersFootersContainer){
+ hdd = (HeadersFootersContainer)ch[i];
+ break;
+ }
+ }
+ boolean newRecord = false;
+ if(hdd == null) return getSlideShow().getSlideHeadersFooters();
+ else return new HeadersFooters(hdd, getSlideShow(), newRecord);
+ }
}
* Grabs the count, from the first two bytes of the header.
* The meaning of the count is specific to the type of the parent record
*/
- public int getCount() {
+ public int getOptions() {
return (int)LittleEndian.getShort(_header);
}
* Sets the count
* The meaning of the count is specific to the type of the parent record
*/
- public void setCount(int count) {
+ public void setOptions(int count) {
LittleEndian.putShort(_header, (short)count);
}
CString csa = new CString();
CString csb = new CString();
CString csc = new CString();
- csa.setCount(0x00);
- csb.setCount(0x10);
- csc.setCount(0x20);
+ csa.setOptions(0x00);
+ csb.setOptions(0x10);
+ csc.setOptions(0x20);
_children[0] = csa;
_children[1] = csb;
_children[2] = csc;
CString cs1 = new CString();
CString cs2 = new CString();
CString cs3 = new CString();
-// cs1.setCount(0x00);
-// cs2.setCount(0x10);
+// cs1.setOptions(0x00);
+// cs2.setOptions(0x10);
_children[0] = new ExEmbedAtom();
_children[1] = new ExOleObjAtom();
_children[2] = cs1;
// Setup our child records
CString csa = new CString();
CString csb = new CString();
- csa.setCount(0x00);
- csb.setCount(0x10);
+ csa.setOptions(0x00);
+ csb.setOptions(0x10);
_children[0] = new ExHyperlinkAtom();
_children[1] = csa;
_children[2] = csb;
--- /dev/null
+\r
+/* ====================================================================\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 org.apache.poi.util.LittleEndian;\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+/**\r
+ * An atom record that specifies options for displaying headers and footers\r
+ * on a presentation slide or notes slide.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+\r
+public class HeadersFootersAtom extends RecordAtom {\r
+\r
+ /**\r
+ * A bit that specifies whether the date is displayed in the footer.\r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasDate = 1;\r
+\r
+ /**\r
+ * A bit that specifies whether the current datetime is used for displaying the datetime.\r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasTodayDate = 2;\r
+\r
+ /**\r
+ * A bit that specifies whether the date specified in UserDateAtom record\r
+ * is used for displaying the datetime.\r
+ *\r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasUserDate = 4;\r
+\r
+ /**\r
+ * A bit that specifies whether the slide number is displayed in the footer.\r
+ * \r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasSlideNumber = 8;\r
+\r
+ /**\r
+ * bit that specifies whether the header text is displayed.\r
+ *\r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasHeader = 16;\r
+\r
+ /**\r
+ * bit that specifies whether the footer text is displayed.\r
+ *\r
+ * @see {@link #getMask()}, {@link #setMask(int)}},\r
+ */\r
+ public static final int fHasFooter = 32;\r
+\r
+ /**\r
+ * record header\r
+ */\r
+ private byte[] _header;\r
+\r
+ /**\r
+ * record data\r
+ */\r
+ private byte[] _recdata;\r
+\r
+ /**\r
+ * Build an instance of <code>HeadersFootersAtom</code> from on-disk data\r
+ */\r
+ protected HeadersFootersAtom(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
+ // Grab the record data\r
+ _recdata = new byte[len-8];\r
+ System.arraycopy(source,start+8,_recdata,0,len-8);\r
+ }\r
+\r
+ /**\r
+ * Create a new instance of <code>HeadersFootersAtom</code>\r
+ */\r
+ public HeadersFootersAtom() {\r
+ _recdata = new byte[4];\r
+\r
+ _header = new byte[8];\r
+ LittleEndian.putShort(_header, 2, (short)getRecordType());\r
+ LittleEndian.putInt(_header, 4, _recdata.length);\r
+ }\r
+\r
+ public long getRecordType() {\r
+ return RecordTypes.HeadersFootersAtom.typeID;\r
+ }\r
+\r
+ /**\r
+ * Write the contents of the record back, so it can be written to disk\r
+ */\r
+ public void writeOut(OutputStream out) throws IOException {\r
+ out.write(_header);\r
+ out.write(_recdata);\r
+ }\r
+\r
+ /**\r
+ * A signed integer that specifies the format ID to be used to style the datetime.\r
+ * <p>\r
+ * It MUST be in the range [0, 12]. </br>\r
+ * This value is converted into a string as specified by the index field of the DateTimeMCAtom record.\r
+ * It MUST be ignored unless fHasTodayDate is TRUE.\r
+ * </b>\r
+ *\r
+ * @return A signed integer that specifies the format ID to be used to style the datetime.\r
+ */\r
+ public int getFormatId(){\r
+ return LittleEndian.getShort(_recdata, 0);\r
+ }\r
+\r
+ /**\r
+ * A signed integer that specifies the format ID to be used to style the datetime.\r
+ *\r
+ * @param formatId A signed integer that specifies the format ID to be used to style the datetime.\r
+ */\r
+ public void setFormatId(int formatId){\r
+ LittleEndian.putUShort(_recdata, 0, formatId);\r
+ }\r
+\r
+ /**\r
+ * A bit mask specifying options for displaying headers and footers\r
+ *\r
+ * <li> A - {@link #fHasDate} (1 bit): A bit that specifies whether the date is displayed in the footer.\r
+ * <li> B - {@link #fHasTodayDate} (1 bit): A bit that specifies whether the current datetime is used for\r
+ * displaying the datetime.\r
+ * <li> C - {@link #fHasUserDate} (1 bit): A bit that specifies whether the date specified in UserDateAtom record\r
+ * is used for displaying the datetime.\r
+ * <li> D - {@link #fHasSlideNumber} (1 bit): A bit that specifies whether the slide number is displayed in the footer.\r
+ * <li> E - {@link #fHasHeader} (1 bit): A bit that specifies whether the header text specified by HeaderAtom\r
+ * record is displayed.\r
+ * <li> F - {@link #fHasFooter} (1 bit): A bit that specifies whether the footer text specified by FooterAtom\r
+ * record is displayed.\r
+ * <li> reserved (10 bits): MUST be zero and MUST be ignored.\r
+ *\r
+ * @return A bit mask specifying options for displaying headers and footers\r
+ */\r
+ public int getMask(){\r
+ return LittleEndian.getShort(_recdata, 2);\r
+ }\r
+\r
+ /**\r
+ * A bit mask specifying options for displaying headers and footers\r
+ *\r
+ * @param mask A bit mask specifying options for displaying headers and footers\r
+ */\r
+ public void setMask(int mask){\r
+ LittleEndian.putUShort(_recdata, 2, mask);\r
+ }\r
+\r
+ /**\r
+ * @param bit the bit to check\r
+ * @return whether the specified flag is set\r
+ */\r
+ public boolean getFlag(int bit){\r
+ return (getMask() & bit) != 0;\r
+ }\r
+\r
+ /**\r
+ * @param bit the bit to set\r
+ * @param value whether the specified bit is set\r
+ */\r
+ public void setFlag(int bit, boolean value){\r
+ int mask = getMask();\r
+ if(value) mask |= bit;\r
+ else mask &= ~bit;\r
+ setMask(mask);\r
+ }\r
+\r
+ public String toString(){\r
+ StringBuffer buf = new StringBuffer();\r
+ buf.append("HeadersFootersAtom\n");\r
+ buf.append("\tFormatId: " + getFormatId() + "\n");\r
+ buf.append("\tMask : " + getMask() + "\n");\r
+ buf.append("\t fHasDate : " + getFlag(fHasDate) + "\n");\r
+ buf.append("\t fHasTodayDate : " + getFlag(fHasTodayDate) + "\n");\r
+ buf.append("\t fHasUserDate : " + getFlag(fHasUserDate) + "\n");\r
+ buf.append("\t fHasSlideNumber : " + getFlag(fHasSlideNumber) + "\n");\r
+ buf.append("\t fHasHeader : " + getFlag(fHasHeader) + "\n");\r
+ buf.append("\t fHasFooter : " + getFlag(fHasFooter) + "\n");\r
+ return buf.toString();\r
+ }\r
+}\r
--- /dev/null
+\r
+/* ====================================================================\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
+package org.apache.poi.hslf.record;\r
+\r
+import org.apache.poi.util.LittleEndian;\r
+import org.apache.poi.util.POILogger;\r
+\r
+import java.io.OutputStream;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * A container record that specifies information about the footers on a presentation slide.\r
+ * <p>\r
+ * It contains:<br>\r
+ * <li> 1. {@link HeadersFootersAtom}\r
+ * <li> 2. {@link CString }, Instance UserDate (0), optional: Stores the user's date.\r
+ * This is the date that the user wants in the footers, instead of today's date.\r
+ * <li> 3. {@link CString }, Instance Header (1), optional: Stores the Header's contents.\r
+ * <li> 4. {@link CString }, Instance Footer (2), optional: Stores the Footer's contents.\r
+ * </p>\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class HeadersFootersContainer extends RecordContainer {\r
+\r
+ /**\r
+ * "instance" field in the record header indicating that this HeadersFootersContaine\r
+ * is applied for slides\r
+ */\r
+ public static final short SlideHeadersFootersContainer = 0x3F;\r
+ /**\r
+ * "instance" field in the record header indicating that this HeadersFootersContaine\r
+ * is applied for notes and handouts\r
+ */\r
+ public static final short NotesHeadersFootersContainer = 0x4F;\r
+\r
+ public static final int USERDATEATOM = 0;\r
+ public static final int HEADERATOM = 1;\r
+ public static final int FOOTERATOM = 2;\r
+\r
+ private byte[] _header;\r
+ private HeadersFootersAtom hdAtom;\r
+ private CString csDate, csHeader, csFooter;\r
+\r
+ protected HeadersFootersContainer(byte[] source, int start, int len) {\r
+ // Grab the header\r
+ _header = new byte[8];\r
+ System.arraycopy(source,start,_header,0,8);\r
+\r
+ _children = Record.findChildRecords(source,start+8,len-8);\r
+ for(int i=0; i < _children.length; i++){\r
+ if(_children[i] instanceof HeadersFootersAtom) hdAtom = (HeadersFootersAtom)_children[i];\r
+ else if(_children[i] instanceof CString) {\r
+ CString cs = (CString)_children[i];\r
+ int opts = cs.getOptions() >> 4;\r
+ switch(opts){\r
+ case USERDATEATOM: csDate = cs; break;\r
+ case HEADERATOM: csHeader = cs; break;\r
+ case FOOTERATOM: csFooter = cs; break;\r
+ default:\r
+ logger.log(POILogger.WARN, "Unexpected CString.Options in HeadersFootersContainer: " + opts);\r
+ break;\r
+ }\r
+ } else {\r
+ logger.log(POILogger.WARN, "Unexpected record in HeadersFootersContainer: " + _children[i]);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ public HeadersFootersContainer(short options) {\r
+ _header = new byte[8];\r
+ LittleEndian.putShort(_header, 0, options);\r
+ LittleEndian.putShort(_header, 2, (short)getRecordType());\r
+\r
+ hdAtom = new HeadersFootersAtom();\r
+ _children = new Record[]{\r
+ hdAtom\r
+ };\r
+ csDate = csHeader = csFooter = null;\r
+\r
+ }\r
+\r
+ /**\r
+ * Return the type, which is <code>{@link RecordTypes#HeadersFooters}</code>\r
+ */\r
+ public long getRecordType() {\r
+ return RecordTypes.HeadersFooters.typeID;\r
+ }\r
+\r
+ /**\r
+ * Must be either {@link #SlideHeadersFootersContainer} or {@link #NotesHeadersFootersContainer}\r
+ *\r
+ * @return "instance" field in the record header\r
+ */\r
+ public int getOptions(){\r
+ return LittleEndian.getShort(_header, 0);\r
+ }\r
+\r
+ /**\r
+ * Write the contents of the record back, so it can be written to disk\r
+ */\r
+ public void writeOut(OutputStream out) throws IOException {\r
+ writeOut(_header[0],_header[1],getRecordType(),_children,out);\r
+ }\r
+\r
+ /**\r
+ * HeadersFootersAtom stores the basic information of the header and footer structure.\r
+ *\r
+ * @return <code>HeadersFootersAtom</code>\r
+ */\r
+ public HeadersFootersAtom getHeadersFootersAtom(){\r
+ return hdAtom;\r
+ }\r
+\r
+ /**\r
+ * A {@link CString} record that stores the user's date.\r
+ * <p>This is the date that the user wants in the footers, instead of today's date.</p>\r
+ *\r
+ * @return A {@link CString} record that stores the user's date or <code>null</code>\r
+ */\r
+ public CString getUserDateAtom(){\r
+ return csDate;\r
+ }\r
+\r
+ /**\r
+ * A {@link CString} record that stores the Header's contents.\r
+ *\r
+ * @return A {@link CString} record that stores the Header's contents or <code>null</code>\r
+ */\r
+ public CString getHeaderAtom(){\r
+ return csHeader;\r
+ }\r
+\r
+ /**\r
+ * A {@link CString} record that stores the Footers's contents.\r
+ *\r
+ * @return A {@link CString} record that stores the Footers's contents or <code>null</code>\r
+ */\r
+ public CString getFooterAtom(){\r
+ return csFooter;\r
+ }\r
+\r
+ /**\r
+ * Insert a {@link CString} record that stores the user's date.\r
+ *\r
+ * @return the created {@link CString} record that stores the user's date.\r
+ */\r
+ public CString addUserDateAtom(){\r
+ if(csDate != null) return csDate;\r
+\r
+ csDate = new CString();\r
+ csDate.setOptions(USERDATEATOM << 4);\r
+\r
+ addChildAfter(csDate, hdAtom);\r
+\r
+ return csDate;\r
+ }\r
+\r
+ /**\r
+ * Insert a {@link CString} record that stores the user's date.\r
+ *\r
+ * @return the created {@link CString} record that stores the user's date.\r
+ */\r
+ public CString addHeaderAtom(){\r
+ if(csHeader != null) return csHeader;\r
+\r
+ csHeader = new CString();\r
+ csHeader.setOptions(HEADERATOM << 4);\r
+\r
+ Record r = hdAtom;\r
+ if(csDate != null) r = hdAtom;\r
+ addChildAfter(csHeader, r);\r
+\r
+ return csHeader;\r
+ }\r
+\r
+ /**\r
+ * Insert a {@link CString} record that stores the user's date.\r
+ *\r
+ * @return the created {@link CString} record that stores the user's date.\r
+ */\r
+ public CString addFooterAtom(){\r
+ if(csFooter != null) return csFooter;\r
+\r
+ csFooter = new CString();\r
+ csFooter.setOptions(FOOTERATOM << 4);\r
+\r
+ Record r = hdAtom;\r
+ if(csHeader != null) r = csHeader;\r
+ else if(csDate != null) r = csDate;\r
+ addChildAfter(csFooter, r);\r
+\r
+ return csFooter;\r
+ }\r
+}\r
public static final Type ExHyperlinkAtom = new Type(4051,ExHyperlinkAtom.class);
public static final Type ExHyperlink = new Type(4055,ExHyperlink.class);
public static final Type SlideNumberMCAtom = new Type(4056,null);
- public static final Type HeadersFooters = new Type(4057,null);
- public static final Type HeadersFootersAtom = new Type(4058,null);
+ public static final Type HeadersFooters = new Type(4057,HeadersFootersContainer.class);
+ public static final Type HeadersFootersAtom = new Type(4058,HeadersFootersAtom.class);
public static final Type TxInteractiveInfoAtom = new Type(4063,TxInteractiveInfoAtom.class);
public static final Type CharFormatAtom = new Type(4066,null);
public static final Type ParaFormatAtom = new Type(4067,null);
public int getNumberOfFonts() {
return getDocumentRecord().getEnvironment().getFontCollection().getNumberOfFonts();
}
+
+ /**
+ * Return Header / Footer settings for slides
+ *
+ * @return Header / Footer settings for slides
+ */
+ public HeadersFooters getSlideHeadersFooters(){
+ HeadersFootersContainer hdd = null;
+ Record[] ch = _documentRecord.getChildRecords();
+ for (int i = 0; i < ch.length; i++) {
+ if(ch[i] instanceof HeadersFootersContainer &&
+ ((HeadersFootersContainer)ch[i]).getOptions() == HeadersFootersContainer.SlideHeadersFootersContainer){
+ hdd = (HeadersFootersContainer)ch[i];
+ break;
+ }
+ }
+ boolean newRecord = false;
+ if(hdd == null) {
+ hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
+ newRecord = true;
+ }
+ return new HeadersFooters(hdd, this, newRecord);
+ }
+
+ /**
+ * Return Header / Footer settings for notes
+ *
+ * @return Header / Footer settings for notes
+ */
+ public HeadersFooters getNotesHeadersFooters(){
+ HeadersFootersContainer hdd = null;
+ Record[] ch = _documentRecord.getChildRecords();
+ for (int i = 0; i < ch.length; i++) {
+ if(ch[i] instanceof HeadersFootersContainer &&
+ ((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);
+ }
}
--- /dev/null
+\r
+/* ====================================================================\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
+\r
+package org.apache.poi.hslf.model;\r
+\r
+import java.io.*;\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+\r
+import junit.framework.TestCase;\r
+\r
+/**\r
+ * Test {@link org.apache.poi.hslf.model.HeadersFooters} object\r
+ */\r
+public class TestHeadersFooters extends TestCase\r
+{\r
+\r
+ public static final String cwd = System.getProperty("HSLF.testdata.path");\r
+\r
+ public void testRead() throws Exception\r
+ {\r
+ File file = new File(cwd, "headers_footers.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("Global Slide Footer", slideHdd.getFooterText());\r
+ assertTrue(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
+ assertTrue(notesHdd.isFooterVisible());\r
+ assertEquals("Notes Footer", notesHdd.getFooterText());\r
+ assertTrue(notesHdd.isHeaderVisible());\r
+ assertEquals("Notes Header", notesHdd.getHeaderText());\r
+ assertTrue(notesHdd.isUserDateVisible());\r
+ assertNull(notesHdd.getDateTimeText());\r
+\r
+ Slide[] slide = ppt.getSlides();\r
+ //the first slide uses presentation-scope headers / footers\r
+ HeadersFooters hd1 = slide[0].getHeadersFooters();\r
+ assertEquals(slideHdd.isFooterVisible(), hd1.isFooterVisible());\r
+ assertEquals(slideHdd.getFooterText(), hd1.getFooterText());\r
+ assertEquals(slideHdd.isSlideNumberVisible(), hd1.isSlideNumberVisible());\r
+ assertEquals(slideHdd.isHeaderVisible(), hd1.isHeaderVisible());\r
+ assertEquals(slideHdd.getHeaderText(), hd1.getHeaderText());\r
+ assertEquals(slideHdd.isUserDateVisible(), hd1.isUserDateVisible());\r
+ assertEquals(slideHdd.getDateTimeText(), hd1.getDateTimeText());\r
+\r
+ //the first slide uses per-slide headers / footers\r
+ HeadersFooters hd2 = slide[1].getHeadersFooters();\r
+ assertEquals(true, hd2.isFooterVisible());\r
+ assertEquals("per-slide footer", hd2.getFooterText());\r
+ assertEquals(true, hd2.isUserDateVisible());\r
+ assertEquals("custom date format", hd2.getDateTimeText());\r
+ }\r
+\r
+ public void testCreateSlideFooters() throws Exception\r
+ {\r
+ SlideShow ppt = new SlideShow();\r
+ HeadersFooters hdd = ppt.getSlideHeadersFooters();\r
+ hdd.setFootersText("My slide footer");\r
+ hdd.setSlideNumberVisible(true);\r
+\r
+ ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+ ppt.write(out);\r
+ byte[] b = out.toByteArray();\r
+\r
+ SlideShow ppt2 = new SlideShow(new ByteArrayInputStream(b));\r
+ HeadersFooters hdd2 = ppt2.getSlideHeadersFooters();\r
+ assertTrue(hdd2.isSlideNumberVisible());\r
+ assertTrue(hdd2.isFooterVisible());\r
+ assertEquals("My slide footer", hdd2.getFooterText());\r
+ }\r
+\r
+ public void testCreateNotesFooters() throws Exception\r
+ {\r
+ SlideShow ppt = new SlideShow();\r
+ HeadersFooters hdd = ppt.getNotesHeadersFooters();\r
+ hdd.setFootersText("My notes footer");\r
+ hdd.setHeaderText("My notes header");\r
+ hdd.setSlideNumberVisible(true);\r
+\r
+ ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+ ppt.write(out);\r
+ byte[] b = out.toByteArray();\r
+\r
+ SlideShow ppt2 = new SlideShow(new ByteArrayInputStream(b));\r
+ HeadersFooters hdd2 = ppt2.getNotesHeadersFooters();\r
+ assertTrue(hdd2.isSlideNumberVisible());\r
+ assertTrue(hdd2.isFooterVisible());\r
+ assertEquals("My notes footer", hdd2.getFooterText());\r
+ assertTrue(hdd2.isHeaderVisible());\r
+ assertEquals("My notes header", hdd2.getHeaderText());\r
+ }\r
+}
\ No newline at end of file
}
public void testCount() throws Exception {
CString ca = new CString(data_a, 0, data_a.length);
- assertEquals(0, ca.getCount());
+ assertEquals(0, ca.getOptions());
CString cb = new CString(data_b, 0, data_a.length);
- assertEquals(0x10, cb.getCount());
+ assertEquals(0x10, cb.getOptions());
- ca.setCount(28);
- assertEquals(28, ca.getCount());
+ ca.setOptions(28);
+ assertEquals(28, ca.getOptions());
}
public void testText() throws Exception {
public void testChange() throws Exception {
CString ca = new CString(data_a, 0, data_a.length);
ca.setText("Comments");
- ca.setCount(0x10);
+ ca.setOptions(0x10);
try {
for(int i=0; i<data_a.length; i++) {
--- /dev/null
+\r
+/* ====================================================================\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
+\r
+package org.apache.poi.hslf.record;\r
+\r
+\r
+import junit.framework.TestCase;\r
+import java.io.ByteArrayOutputStream;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * Tests that {@link HeadersFootersAtom} works properly\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestHeadersFootersAtom extends TestCase {\r
+ // From a real file\r
+ private byte[] data = new byte[] {\r
+ 0x00, 0x00, (byte)0xDA, 0x0F, 0x04, 0x00, 0x00, 00,\r
+ 0x00, 0x00, 0x23, 0x00 };\r
+\r
+ public void testRead() throws Exception {\r
+ HeadersFootersAtom record = new HeadersFootersAtom(data, 0, data.length);\r
+ assertEquals(RecordTypes.HeadersFootersAtom.typeID, record.getRecordType());\r
+\r
+ assertEquals(0, record.getFormatId());\r
+ assertEquals(0x23, record.getMask());\r
+\r
+ assertTrue(record.getFlag(HeadersFootersAtom.fHasDate));\r
+ assertTrue(record.getFlag(HeadersFootersAtom.fHasTodayDate));\r
+ assertFalse(record.getFlag(HeadersFootersAtom.fHasUserDate));\r
+ assertFalse(record.getFlag(HeadersFootersAtom.fHasSlideNumber));\r
+ assertFalse(record.getFlag(HeadersFootersAtom.fHasHeader));\r
+ assertTrue(record.getFlag(HeadersFootersAtom.fHasFooter));\r
+ }\r
+\r
+ public void testWrite() throws Exception {\r
+ HeadersFootersAtom record = new HeadersFootersAtom(data, 0, data.length);\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(data, b));\r
+ }\r
+\r
+ public void testNewRecord() throws Exception {\r
+ HeadersFootersAtom record = new HeadersFootersAtom();\r
+ record.setFlag(HeadersFootersAtom.fHasDate, true);\r
+ record.setFlag(HeadersFootersAtom.fHasTodayDate, true);\r
+ record.setFlag(HeadersFootersAtom.fHasFooter, true);\r
+\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(data, b));\r
+ }\r
+\r
+ public void testFlags() throws Exception {\r
+ HeadersFootersAtom record = new HeadersFootersAtom();\r
+\r
+ //in a new record all the bits are 0\r
+ for(int i = 0; i < 6; i++) assertFalse(record.getFlag(1 << i));\r
+\r
+ record.setFlag(HeadersFootersAtom.fHasTodayDate, true);\r
+ assertTrue(record.getFlag(HeadersFootersAtom.fHasTodayDate));\r
+\r
+ record.setFlag(HeadersFootersAtom.fHasTodayDate, true);\r
+ assertTrue(record.getFlag(HeadersFootersAtom.fHasTodayDate));\r
+\r
+ record.setFlag(HeadersFootersAtom.fHasTodayDate, false);\r
+ assertFalse(record.getFlag(HeadersFootersAtom.fHasTodayDate));\r
+\r
+ record.setFlag(HeadersFootersAtom.fHasTodayDate, false);\r
+ assertFalse(record.getFlag(HeadersFootersAtom.fHasTodayDate));\r
+\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+\r
+/* ====================================================================\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
+\r
+package org.apache.poi.hslf.record;\r
+\r
+\r
+import junit.framework.TestCase;\r
+import java.io.ByteArrayOutputStream;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * Tests that {@link HeadersFootersContainer} works properly\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestHeadersFootersContainer extends TestCase {\r
+ // SlideHeadersFootersContainer\r
+ private byte[] slideData = new byte[] {\r
+ 0x3F, 0x00, (byte)0xD9, 0x0F, 0x2E, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, (byte)0xDA, 0x0F, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00,\r
+ 0x20, 0x00, (byte)0xBA, 0x0F, 0x1A, 0x00, 0x00, 0x00,\r
+ 0x4D, 0x00, 0x79, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74,\r
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, 0x31, 0x00\r
+\r
+ };\r
+\r
+ // NotesHeadersFootersContainer\r
+ private byte[] notesData = new byte[] {\r
+ 0x4F, 0x00, (byte)0xD9, 0x0F, 0x48, 0x00, 0x00, 0x00,\r
+ 0x00, 0x00, (byte)0xDA, 0x0F, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x00,\r
+ 0x10, 0x00, (byte)0xBA, 0x0F, 0x16, 0x00, 0x00, 0x00,\r
+ 0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x48, 0x00,\r
+ 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00,\r
+ 0x20, 0x00, (byte)0xBA, 0x0F, 0x16, 0x00, 0x00, 0x00,\r
+ 0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00,\r
+ 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00\r
+ };\r
+\r
+ public void testReadSlideHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(slideData, 0, slideData.length);\r
+ assertEquals(RecordTypes.HeadersFooters.typeID, record.getRecordType());\r
+ assertEquals(HeadersFootersContainer.SlideHeadersFootersContainer, record.getOptions());\r
+ assertEquals(2, record.getChildRecords().length);\r
+\r
+ HeadersFootersAtom hdd = record.getHeadersFootersAtom();\r
+ assertNotNull(hdd);\r
+\r
+ CString csFooter = record.getFooterAtom();\r
+ assertNotNull(csFooter);\r
+ assertEquals(HeadersFootersContainer.FOOTERATOM, csFooter.getOptions() >> 4);\r
+\r
+ assertEquals("My Footer - 1", csFooter.getText());\r
+\r
+ assertNull(record.getUserDateAtom());\r
+ assertNull(record.getHeaderAtom());\r
+ }\r
+\r
+ public void testWriteSlideHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(slideData, 0, slideData.length);\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(slideData, b));\r
+ }\r
+\r
+ public void testNewSlideHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);\r
+\r
+ assertNotNull(record.getHeadersFootersAtom());\r
+ assertNull(record.getUserDateAtom());\r
+ assertNull(record.getHeaderAtom());\r
+ assertNull(record.getFooterAtom());\r
+\r
+ HeadersFootersAtom hd = record.getHeadersFootersAtom();\r
+ hd.setFlag(HeadersFootersAtom.fHasDate, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasTodayDate, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasFooter, true);\r
+\r
+ CString csFooter = record.addFooterAtom();\r
+ assertNotNull(csFooter);\r
+ assertEquals(HeadersFootersContainer.FOOTERATOM, csFooter.getOptions() >> 4);\r
+ csFooter.setText("My Footer - 1");\r
+\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(slideData, b));\r
+ }\r
+\r
+ public void testReadNotesHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(notesData, 0, notesData.length);\r
+ assertEquals(RecordTypes.HeadersFooters.typeID, record.getRecordType());\r
+ assertEquals(HeadersFootersContainer.NotesHeadersFootersContainer, record.getOptions());\r
+ assertEquals(3, record.getChildRecords().length);\r
+\r
+ HeadersFootersAtom hdd = record.getHeadersFootersAtom();\r
+ assertNotNull(hdd);\r
+\r
+ CString csHeader = record.getHeaderAtom();\r
+ assertNotNull(csHeader);\r
+ assertEquals(HeadersFootersContainer.HEADERATOM, csHeader.getOptions() >> 4);\r
+ assertEquals("Note Header", csHeader.getText());\r
+\r
+ CString csFooter = record.getFooterAtom();\r
+ assertNotNull(csFooter);\r
+ assertEquals(HeadersFootersContainer.FOOTERATOM, csFooter.getOptions() >> 4);\r
+ assertEquals("Note Footer", csFooter.getText());\r
+ }\r
+\r
+ public void testWriteNotesHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(notesData, 0, notesData.length);\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(notesData, b));\r
+ }\r
+\r
+ public void testNewNotesHeadersFootersContainer() throws Exception {\r
+ HeadersFootersContainer record = new HeadersFootersContainer(HeadersFootersContainer.NotesHeadersFootersContainer);\r
+\r
+ assertNotNull(record.getHeadersFootersAtom());\r
+ assertNull(record.getUserDateAtom());\r
+ assertNull(record.getHeaderAtom());\r
+ assertNull(record.getFooterAtom());\r
+\r
+ HeadersFootersAtom hd = record.getHeadersFootersAtom();\r
+ hd.setFlag(HeadersFootersAtom.fHasDate, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasTodayDate, false);\r
+ hd.setFlag(HeadersFootersAtom.fHasUserDate, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasSlideNumber, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasHeader, true);\r
+ hd.setFlag(HeadersFootersAtom.fHasFooter, true);\r
+\r
+ CString csHeader = record.addHeaderAtom();\r
+ assertNotNull(csHeader);\r
+ assertEquals(HeadersFootersContainer.HEADERATOM, csHeader.getOptions() >> 4);\r
+ csHeader.setText("Note Header");\r
+\r
+ CString csFooter = record.addFooterAtom();\r
+ assertNotNull(csFooter);\r
+ assertEquals(HeadersFootersContainer.FOOTERATOM, csFooter.getOptions() >> 4);\r
+ csFooter.setText("Note Footer");\r
+\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+ record.writeOut(baos);\r
+ byte[] b = baos.toByteArray();\r
+\r
+ assertTrue(Arrays.equals(notesData, b));\r
+ }\r
+\r
+}
\ No newline at end of file