diff --git a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java index 50e75becb..881a71da9 100644 --- a/src/java/org/apache/poi/sl/usermodel/TextParagraph.java +++ b/src/java/org/apache/poi/sl/usermodel/TextParagraph.java @@ -364,4 +364,14 @@ public interface TextParagraph< * Fetch the text runs that are contained within this block of text */ List getTextRuns(); -} + + /** + * Convenience method to determine if this text paragraph is part of + * the slide header or footer + * + * @return true if this paragraph is part of a header or footer placeholder + * + * @since POI 3.15-beta2 + */ + boolean isHeaderOrFooter(); +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index 0939edb96..9576eea3c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -755,7 +755,7 @@ public class XSLFTextParagraph implements TextParagraph ppt1 = openSampleSlideshow("bug58144-headers-footers-2003.ppt"); + HSLFSlide sl1 = (HSLFSlide)ppt1.getSlides().get(0); + HeadersFooters hfs1 = sl1.getHeadersFooters(); + assertNull(hfs1.getHeaderText()); + assertEquals("Confidential", hfs1.getFooterText()); + List> llp1 = sl1.getTextParagraphs(); + assertEquals("Test", HSLFTextParagraph.getText(llp1.get(0))); + assertFalse(llp1.get(0).get(0).isHeaderOrFooter()); + ppt1.close(); + + String ppt2007s[] = { + "bug58144-headers-footers-2007.ppt", "bug58144-headers-footers-2007.pptx" + }; + + for (String pptName : ppt2007s) { + SlideShow ppt2 = openSampleSlideshow(pptName); + Slide sl2 = ppt2.getSlides().get(0); + + if (ppt2 instanceof HSLFSlideShow) { + HeadersFooters hfs2 = ((HSLFSlide)sl2).getHeadersFooters(); + assertNull(hfs2.getHeaderText()); + assertEquals("Slide footer", hfs2.getFooterText()); + } + + List> shapes = sl2.getShapes(); + TextShape ts0 = (TextShape)shapes.get(0); + assertEquals("Test file", ts0.getText()); + TextShape ts1 = (TextShape)shapes.get(1); + assertEquals("Has some text in the headers and footers", ts1.getText()); + TextShape ts2 = (TextShape)shapes.get(2); + assertEquals("Slide footer", ts2.getText()); + List> ltp2 = ts2.getTextParagraphs(); + assertTrue(ltp2.get(0).isHeaderOrFooter()); + ppt2.close(); + } + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java index 63ec3d7a6..f34cd4be7 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java @@ -17,37 +17,65 @@ package org.apache.poi.hslf.model; -import org.apache.poi.hslf.record.*; -import org.apache.poi.hslf.usermodel.*; +import org.apache.poi.hslf.record.CString; +import org.apache.poi.hslf.record.Document; +import org.apache.poi.hslf.record.HeadersFootersAtom; +import org.apache.poi.hslf.record.HeadersFootersContainer; +import org.apache.poi.hslf.record.OEPlaceholderAtom; +import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.record.RecordTypes; +import org.apache.poi.hslf.record.SheetContainer; +import org.apache.poi.hslf.usermodel.HSLFSheet; +import org.apache.poi.hslf.usermodel.HSLFSlideShow; +import org.apache.poi.hslf.usermodel.HSLFTextShape; /** * Header / Footer settings. * * You can get these on slides, or across all notes - * - * @author Yegor Kozlov */ public final class HeadersFooters { - private HeadersFootersContainer _container; - private boolean _newRecord; - private HSLFSlideShow _ppt; - private HSLFSheet _sheet; - private boolean _ppt2007; + private final HeadersFootersContainer _container; + private final HSLFSheet _sheet; + private final boolean _ppt2007; - public HeadersFooters(HeadersFootersContainer rec, HSLFSlideShow ppt, boolean newRecord, boolean isPpt2007){ - _container = rec; - _newRecord = newRecord; - _ppt = ppt; - _ppt2007 = isPpt2007; + public HeadersFooters(HSLFSlideShow ppt, short headerFooterType) { + this(ppt.getSlideMasters().get(0), headerFooterType); } - public HeadersFooters(HeadersFootersContainer rec, HSLFSheet sheet, boolean newRecord, boolean isPpt2007){ - _container = rec; - _newRecord = newRecord; + public HeadersFooters(HSLFSheet sheet, short headerFooterType) { _sheet = sheet; - _ppt2007 = isPpt2007; + + @SuppressWarnings("resource") + HSLFSlideShow ppt = _sheet.getSlideShow(); + Document doc = ppt.getDocumentRecord(); + + // detect if this ppt was saved in Office2007 + String tag = ppt.getSlideMasters().get(0).getProgrammableTag(); + _ppt2007 = "___PPT12".equals(tag); + + SheetContainer sc = _sheet.getSheetContainer(); + HeadersFootersContainer hdd = (HeadersFootersContainer)sc.findFirstOfType(RecordTypes.HeadersFooters.typeID); + // boolean ppt2007 = sc.findFirstOfType(RecordTypes.RoundTripContentMasterId.typeID) != null; + + if (hdd == null) { + for (Record ch : doc.getChildRecords()) { + if (ch instanceof HeadersFootersContainer + && ((HeadersFootersContainer) ch).getOptions() == headerFooterType) { + hdd = (HeadersFootersContainer) ch; + break; + } + } + } + + if (hdd == null) { + hdd = new HeadersFootersContainer(headerFooterType); + Record lst = doc.findFirstOfType(RecordTypes.List.typeID); + doc.addChildAfter(hdd, lst); + } + _container = hdd; } /** @@ -66,11 +94,11 @@ public final class HeadersFooters { * @param text headers's text */ public void setHeaderText(String text){ - if(_newRecord) attach(); - setHeaderVisible(true); CString cs = _container.getHeaderAtom(); - if(cs == null) cs = _container.addHeaderAtom(); + if (cs == null) { + cs = _container.addHeaderAtom(); + } cs.setText(text); } @@ -91,11 +119,11 @@ public final class HeadersFooters { * @param text footers's text */ public void setFootersText(String text){ - if(_newRecord) attach(); - setFooterVisible(true); CString cs = _container.getFooterAtom(); - if(cs == null) cs = _container.addFooterAtom(); + if (cs == null) { + cs = _container.addFooterAtom(); + } cs.setText(text); } @@ -116,12 +144,12 @@ public final class HeadersFooters { * @param text custom user date */ public void setDateTimeText(String text){ - if(_newRecord) attach(); - setUserDateVisible(true); setDateTimeVisible(true); CString cs = _container.getUserDateAtom(); - if(cs == null) cs = _container.addUserDateAtom(); + if (cs == null) { + cs = _container.addUserDateAtom(); + } cs.setText(text); } @@ -137,8 +165,7 @@ public final class HeadersFooters { * whether the footer text is displayed. */ public void setFooterVisible(boolean flag){ - if(_newRecord) attach(); - _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasFooter, flag); + setFlag(HeadersFootersAtom.fHasFooter, flag); } /** @@ -152,8 +179,7 @@ public final class HeadersFooters { * whether the header text is displayed. */ public void setHeaderVisible(boolean flag){ - if(_newRecord) attach(); - _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasHeader, flag); + setFlag(HeadersFootersAtom.fHasHeader, flag); } /** @@ -167,8 +193,7 @@ public final class HeadersFooters { * whether the date is displayed in the footer. */ public void setDateTimeVisible(boolean flag){ - if(_newRecord) attach(); - _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasDate, flag); + setFlag(HeadersFootersAtom.fHasDate, flag); } /** @@ -182,8 +207,7 @@ public final class HeadersFooters { * whether the date is displayed in the footer. */ public void setUserDateVisible(boolean flag){ - if(_newRecord) attach(); - _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasUserDate, flag); + setFlag(HeadersFootersAtom.fHasUserDate, flag); } /** @@ -197,8 +221,7 @@ public final class HeadersFooters { * whether the slide number is displayed in the footer. */ public void setSlideNumberVisible(boolean flag){ - if(_newRecord) attach(); - _container.getHeadersFootersAtom().setFlag(HeadersFootersAtom.fHasSlideNumber, flag); + setFlag(HeadersFootersAtom.fHasSlideNumber, flag); } /** @@ -216,32 +239,13 @@ public final class HeadersFooters { * @param formatId an integer that specifies the format ID to be used to style the datetime. */ public void setDateTimeFormat(int formatId){ - if(_newRecord) attach(); _container.getHeadersFootersAtom().setFormatId(formatId); } - /** - * Attach this HeadersFootersContainer to the parent Document record - */ - private void attach(){ - Document doc = _ppt.getDocumentRecord(); - Record[] ch = doc.getChildRecords(); - Record lst = null; - for (int i=0; i < ch.length; i++){ - if(ch[i].getRecordType() == RecordTypes.List.typeID){ - lst = ch[i]; - break; - } - } - doc.addChildAfter(_container, lst); - _newRecord = false; - } - private boolean isVisible(int flag, int placeholderId){ boolean visible; if(_ppt2007){ - HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlideMasters().get(0); - HSLFTextShape placeholder = master.getPlaceholder(placeholderId); + HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); visible = placeholder != null && placeholder.getText() != null; } else { visible = _container.getHeadersFootersAtom().getFlag(flag); @@ -251,17 +255,23 @@ public final class HeadersFooters { private String getPlaceholderText(int placeholderId, CString cs){ String text = null; - if(_ppt2007){ - HSLFSheet master = _sheet != null ? _sheet : _ppt.getSlideMasters().get(0); - HSLFTextShape placeholder = master.getPlaceholder(placeholderId); - if(placeholder != null) text = placeholder.getText(); + if (_ppt2007) { + HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); + if (placeholder != null) { + text = placeholder.getText(); + } - //default text in master placeholders is not visible - if("*".equals(text)) text = null; + // default text in master placeholders is not visible + if("*".equals(text)) { + text = null; + } } else { text = cs == null ? null : cs.getText(); } return text; } + private void setFlag(int type, boolean flag) { + _container.getHeadersFootersAtom().setFlag(type, flag); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java index 28bc7bbf0..3ad7b086c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java @@ -120,9 +120,9 @@ public abstract class RecordContainer extends Record * given type. Does not descend. */ public Record findFirstOfType(long type) { - for(int i=0; i<_children.length; i++) { - if(_children[i].getRecordType() == type) { - return _children[i]; + for (Record r : _children) { + if (r.getRecordType() == type) { + return r; } } return null; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java index 453a790fd..d3a613222 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java @@ -31,7 +31,6 @@ import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.Comment2000; import org.apache.poi.hslf.record.EscherTextboxWrapper; import org.apache.poi.hslf.record.HeadersFootersContainer; -import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.RecordContainer; import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.SSSlideInfoAtom; @@ -422,26 +421,8 @@ public final class HSLFSlide extends HSLFSheet implements Slide