diff --git a/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java b/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java
index 75180c2d1..ec0cec8dc 100644
--- a/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java
+++ b/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java
@@ -16,13 +16,10 @@
==================================================================== */
package org.apache.poi.hslf.examples;
import java.io.FileInputStream;
+import java.io.IOException;
-import org.apache.poi.ddf.EscherClientDataRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.hslf.record.InteractiveInfo;
import org.apache.poi.hslf.record.InteractiveInfoAtom;
-import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
@@ -30,12 +27,11 @@ import org.apache.poi.hslf.usermodel.HSLFSoundData;
/**
* For each slide iterate over shapes and found associated sound data.
- *
- * @author Yegor Kozlov
*/
public class SoundFinder {
- public static void main(String[] args) throws Exception {
- HSLFSlideShow ppt = new HSLFSlideShow(new FileInputStream(args[0]));
+ public static void main(String[] args) throws IOException {
+ FileInputStream fis = new FileInputStream(args[0]);
+ HSLFSlideShow ppt = new HSLFSlideShow(fis);
HSLFSoundData[] sounds = ppt.getSoundData();
for (HSLFSlide slide : ppt.getSlides()) {
@@ -49,6 +45,8 @@ public class SoundFinder {
System.out.println(" " + sounds[soundRef].getSoundType());
}
}
+ ppt.close();
+ fis.close();
}
/**
@@ -59,19 +57,9 @@ public class SoundFinder {
protected static int getSoundReference(HSLFShape shape){
int soundRef = -1;
//dive into the shape container and search for InteractiveInfoAtom
- EscherContainerRecord spContainer = shape.getSpContainer();
- for (EscherRecord obj : spContainer.getChildRecords()) {
- if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
- byte[] data = obj.serialize();
- for (Record record : Record.findChildRecords(data, 8, data.length - 8)) {
- if (record instanceof InteractiveInfo) {
- InteractiveInfoAtom info = ((InteractiveInfo)record).getInteractiveInfoAtom();
- if (info.getAction() == InteractiveInfoAtom.ACTION_MEDIA) {
- soundRef = info.getSoundRef();
- }
- }
- }
- }
+ InteractiveInfoAtom info = shape.getClientDataRecord(RecordTypes.InteractiveInfo.typeID);
+ if (info != null && info.getAction() == InteractiveInfoAtom.ACTION_MEDIA) {
+ soundRef = info.getSoundRef();
}
return soundRef;
}
diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
index 28c1fa3f1..4433605f3 100644
--- a/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
+++ b/src/examples/src/org/apache/poi/xslf/usermodel/Tutorial3.java
@@ -23,7 +23,7 @@ import java.awt.Rectangle;
import java.io.FileOutputStream;
import java.io.IOException;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
/**
* How to set slide title
diff --git a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
index bea83a83c..0b307ad53 100644
--- a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
+++ b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
@@ -76,7 +76,7 @@ public class EscherClientDataRecord
public String toString()
{
String nl = System.getProperty("line.separator");
- String extraData = HexDump.dump(this.remainingData, 0, 0);
+ String extraData = HexDump.dump(getRemainingData(), 0, 0);
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
" Version: 0x" + HexDump.toHex(getVersion()) + nl +
@@ -88,7 +88,7 @@ public class EscherClientDataRecord
@Override
public String toXml(String tab) {
- String extraData = HexDump.dump(this.remainingData, 0, 0).trim();
+ String extraData = HexDump.dump(getRemainingData(), 0, 0).trim();
StringBuilder builder = new StringBuilder();
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()),
HexDump.toHex(getVersion()), HexDump.toHex(getInstance())))
diff --git a/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java b/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
index 76ae92de7..3bcedbe85 100644
--- a/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
+++ b/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java
@@ -33,7 +33,12 @@ public class DrawMasterSheet extends DrawSheet {
* for instance, slide masters and layouts don't display placeholders
*/
@Override
- protected boolean canDraw(Shape,?> shape){
- return !(shape instanceof SimpleShape) || !((SimpleShape,?>)shape).isPlaceholder();
+ protected boolean canDraw(Shape,?> shape) {
+ if (shape instanceof SimpleShape) {
+ Placeholder ph = ((SimpleShape,?>)shape).getPlaceholder();
+ return ph == null;
+ } else {
+ return true;
+ }
}
}
diff --git a/src/java/org/apache/poi/sl/usermodel/Placeholder.java b/src/java/org/apache/poi/sl/usermodel/Placeholder.java
new file mode 100644
index 000000000..a3bc9c7c8
--- /dev/null
+++ b/src/java/org/apache/poi/sl/usermodel/Placeholder.java
@@ -0,0 +1,138 @@
+/* ====================================================================
+ 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.sl.usermodel;
+
+public enum Placeholder {
+ /**
+ * No placeholder shape.
+ */
+ NONE(0,0,0,0,0),
+ /**
+ * Title text placeholder shape.
+ */
+ TITLE(13,1,1,1,1),
+ /**
+ * Body text placeholder shape.
+ */
+ BODY(14,2,12,6,2),
+ /**
+ * Center title text placeholder shape.
+ */
+ CENTERED_TITLE(15,3,3,3,3),
+ /**
+ * Sub-title text placeholder shape.
+ */
+ SUBTITLE(16,4,4,4,4),
+ /**
+ * Date placeholder shape.
+ */
+ DATETIME(7,7,7,7,5),
+ /**
+ * Slide number placeholder shape.
+ */
+ SLIDE_NUMBER(8,8,8,8,6),
+ /**
+ * Footer placeholder shape.
+ */
+ FOOTER(9,9,9,9,7),
+ /**
+ * Header placeholder shape.
+ */
+ HEADER(10,10,10,10,8),
+ /**
+ * Object placeholder shape.
+ */
+ CONTENT(19,19,19,19,9),
+ /**
+ * Graph object placeholder shape.
+ */
+ CHART(20,20,20,20,10),
+ /**
+ * Table object placeholder shape.
+ */
+ TABLE(21,21,21,21,11),
+ /**
+ * Clipart object placeholder shape.
+ */
+ CLIP_ART(22,22,22,22,12),
+ /**
+ * Organization chart object placeholder shape.
+ */
+ DGM(23,23,23,23,13),
+ /**
+ * Media object placeholder shape.
+ */
+ MEDIA(24,24,24,24,14),
+ /**
+ * Slide image placeholder shape.
+ */
+ SLIDE_IMAGE(11,11,11,5,15),
+ /**
+ * Picture object placeholder shape.
+ */
+ PICTURE(26,26,26,26,16),
+ /**
+ * Vertical object placeholder shape.
+ */
+ VERTICAL_OBJECT(25,25,25,25,-2),
+ /**
+ * Vertical title text placeholder shape.
+ */
+ VERTICAL_TEXT_TITLE(17,17,17,17,-2),
+ /**
+ * Vertical body text placeholder shape.
+ */
+ VERTICAL_TEXT_BODY(18,18,18,18,-2)
+ ;
+
+ public final int nativeSlideId;
+ public final int nativeSlideMasterId;
+ public final int nativeNotesId;
+ public final int nativeNotesMasterId;
+ public final int ooxmlId;
+
+ Placeholder(int nativeSlideId, int nativeSlideMasterId, int nativeNotesId, int nativeNotesMasterId, int ooxmlId) {
+ this.nativeSlideId = nativeSlideId;
+ this.nativeSlideMasterId = nativeSlideMasterId;
+ this.nativeNotesId = nativeNotesId;
+ this.nativeNotesMasterId = nativeNotesMasterId;
+ this.ooxmlId = ooxmlId;
+ }
+
+ public static Placeholder lookupNative(int nativeId) {
+ for (Placeholder ph : values()) {
+ if (ph.nativeSlideId == nativeId ||
+ ph.nativeSlideMasterId == nativeId ||
+ ph.nativeNotesId == nativeId ||
+ ph.nativeNotesMasterId == nativeId
+ ) {
+ return ph;
+ }
+ }
+ return null;
+ }
+
+ public static Placeholder lookupOoxml(int ooxmlId) {
+ for (Placeholder ph : values()) {
+ if (ph.ooxmlId == ooxmlId) {
+ return ph;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/sl/usermodel/SimpleShape.java b/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
index 8ed151b49..53ee6de52 100644
--- a/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/SimpleShape.java
@@ -28,25 +28,6 @@ public interface SimpleShape<
P extends TextParagraph
> extends Shape, IAdjustableShape, PlaceableShape {
- enum Placeholder {
- TITLE,
- BODY,
- CENTERED_TITLE,
- SUBTITLE,
- DATETIME,
- SLIDE_NUMBER,
- FOOTER,
- HEADER,
- CONTENT,
- CHART,
- TABLE,
- CLIP_ART,
- DGM,
- MEDIA,
- SLIDE_IMAGE,
- PICTURE
- }
-
FillStyle getFillStyle();
LineDecoration getLineDecoration();
@@ -69,7 +50,20 @@ public interface SimpleShape<
ShapeType getShapeType();
void setShapeType(ShapeType type);
- boolean isPlaceholder();
+ /**
+ * @return the placeholder or null if none is assigned
+ * @see #setPlaceholder(Placeholder)
+ */
+ Placeholder getPlaceholder();
+
+ /**
+ * Specifies that the corresponding shape should be represented by the generating application
+ * as a placeholder. When a shape is considered a placeholder by the generating application
+ * it can have special properties to alert the user that they may enter content into the shape.
+ *
+ * @param placeholder the placeholder or null to remove the reference to the placeholder
+ */
+ void setPlaceholder(Placeholder placeholder);
Shadow getShadow();
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java
index 6dbdf2d4f..290b5f494 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java
@@ -21,11 +21,13 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D;
+import org.apache.poi.POIXMLException;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.Background;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
@@ -70,4 +72,10 @@ public class XSLFBackground extends XSLFSimpleShape
protected CTTransform2D getXfrm() {
return CTTransform2D.Factory.newInstance();
}
+
+ @Override
+ public void setPlaceholder(Placeholder placeholder) {
+ // extending XSLFSimpleShape is a bit unlucky ...
+ throw new POIXMLException("Can't set a placeholder for a background");
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
index ef8a2adf0..0ca895efa 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
@@ -19,7 +19,9 @@
package org.apache.poi.xslf.usermodel;
+import org.apache.poi.POIXMLException;
import org.apache.poi.sl.usermodel.ConnectorShape;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
@@ -69,4 +71,8 @@ public class XSLFConnectorShape extends XSLFSimpleShape
return null;
}
+ @Override
+ public void setPlaceholder(Placeholder placeholder) {
+ throw new POIXMLException("A connector shape can't be a placeholder.");
+ }
}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
index 48c8babdd..b9d7e37f6 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
@@ -28,6 +28,7 @@ import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.PictureShape;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
@@ -118,6 +119,12 @@ public class XSLFPictureShape extends XSLFSimpleShape
}
return _data;
}
+
+ @Override
+ public void setPlaceholder(Placeholder placeholder) {
+ super.setPlaceholder(placeholder);
+ }
+
/**
* For an external linked picture, return the last-seen
@@ -168,7 +175,6 @@ public class XSLFPictureShape extends XSLFSimpleShape
return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR());
}
- @SuppressWarnings("deprecation")
@Override
void copy(XSLFShape sh){
super.copy(sh);
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
index dc1ef5af2..f25c9278e 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
@@ -33,7 +33,7 @@ import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
@@ -255,6 +255,14 @@ public abstract class XSLFShape implements Shape {
return _ph;
}
+ public Placeholder getPlaceholder() {
+ CTPlaceholder ph = getCTPlaceholder();
+ if (ph == null || !ph.isSetType()) {
+ return null;
+ }
+ return Placeholder.lookupOoxml(ph.getType().intValue());
+ }
+
/**
* Specifies that the corresponding shape should be represented by the generating application
* as a placeholder. When a shape is considered a placeholder by the generating application
@@ -272,7 +280,7 @@ public abstract class XSLFShape implements Shape {
if (nv.isSetPh()) nv.unsetPh();
_ph = null;
} else {
- nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1));
+ nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ooxmlId));
}
}
@@ -442,7 +450,6 @@ public abstract class XSLFShape implements Shape {
protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr) {
- @SuppressWarnings("deprecation")
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
Arrays.sort(gs, new Comparator() {
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
index 5dac2181e..e8fa1da03 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
@@ -42,8 +42,8 @@ import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawPictureShape;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Sheet;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
index c6bbb1ff0..8b92ec231 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
@@ -34,6 +34,7 @@ import org.apache.poi.sl.usermodel.LineDecoration;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
import org.apache.poi.sl.usermodel.PaintStyle;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.SimpleShape;
@@ -815,7 +816,6 @@ public abstract class XSLFSimpleShape extends XSLFShape
return ph != null;
}
- @SuppressWarnings("deprecation")
public Guide getAdjustValue(String name) {
CTPresetGeometry2D prst = getSpPr().getPrstGeom();
if (prst.isSetAvLst()) {
@@ -918,4 +918,9 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
}
}
+
+ @Override
+ public void setPlaceholder(Placeholder placeholder) {
+ super.setPlaceholder(placeholder);
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
index 4be19ea43..491062163 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
@@ -27,7 +27,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Notes;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
index 95835e495..1d49b068e 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
@@ -24,7 +24,7 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
index cf45bf744..34d282cd0 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
@@ -27,7 +27,7 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
index 4a1856d7f..d78749c75 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
@@ -28,6 +28,7 @@ import org.apache.poi.POIXMLException;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawTextShape;
import org.apache.poi.sl.usermodel.Insets2D;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Beta;
@@ -54,7 +55,6 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
implements TextShape {
private final List _paragraphs;
- @SuppressWarnings("deprecation")
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
super(shape, sheet);
@@ -497,13 +497,13 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
public void setPlaceholder(Placeholder placeholder) {
super.setPlaceholder(placeholder);
}
-
+
public Placeholder getTextType(){
CTPlaceholder ph = getCTPlaceholder();
if (ph == null) return null;
int val = ph.getType().intValue();
- return Placeholder.values()[val - 1];
+ return Placeholder.lookupOoxml(val);
}
@Override
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
index 02fac93bc..ae18fc70c 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFNotes.java
@@ -22,7 +22,7 @@ import static org.junit.Assert.assertNull;
import java.io.IOException;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test;
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
index 452f22ebc..9b6f44895 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
@@ -28,7 +28,7 @@ import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.draw.geom.TestPresetGeometries;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Units;
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
index cee11e541..15352b448 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextBox.java
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertNull;
import java.io.IOException;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
index c8a1aeebd..a87a9cb55 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
@@ -31,7 +31,7 @@ import java.util.List;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFTextShape;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java b/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
index 5a5f82d16..cf6f6bc41 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
@@ -122,7 +122,7 @@ public final class PPTXMLDump {
pos += LittleEndian.INT_SIZE;
//get name of the record by type
- String recname = RecordTypes.recordName(type);
+ String recname = RecordTypes.forTypeID(type).name();
write(out, "<"+recname + " info=\""+info+"\" type=\""+type+"\" size=\""+size+"\" offset=\""+(pos-8)+"\"", padding);
if (hexHeader){
out.write(" header=\"");
diff --git a/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java b/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java
index 91d6086b1..90f404b1e 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/dev/SLWTListing.java
@@ -79,7 +79,7 @@ public final class SLWTListing {
for(int k=0; k it = spContainer.getChildIterator(); it.hasNext();) {
- EscherRecord obj = it.next();
- if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
- EscherClientDataRecord clientRecord = (EscherClientDataRecord)obj;
- byte[] recdata = clientRecord.getRemainingData();
- LittleEndian.putInt(recdata, 8, idx);
- }
+ public void setActiveXIndex(int idx) {
+ ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID);
+ if (oe == null) {
+ throw new HSLFException("OEShapeAtom for ActiveX doesn't exist");
}
+ oe.setExObjIdRef(idx);
}
public int getControlIndex(){
int idx = -1;
- OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
- if(oe != null) idx = oe.getOptions();
+ ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID);
+ if(oe != null) idx = oe.getExObjIdRef();
return idx;
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
index d4da2a310..5650b2b2d 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
@@ -17,14 +17,24 @@
package org.apache.poi.hslf.model;
-import java.io.ByteArrayOutputStream;
-
-import org.apache.poi.ddf.EscherClientDataRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.record.*;
-import org.apache.poi.hslf.usermodel.*;
+import org.apache.poi.hslf.record.AnimationInfo;
+import org.apache.poi.hslf.record.AnimationInfoAtom;
+import org.apache.poi.hslf.record.ExMCIMovie;
+import org.apache.poi.hslf.record.ExObjList;
+import org.apache.poi.hslf.record.ExObjRefAtom;
+import org.apache.poi.hslf.record.ExVideoContainer;
+import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.InteractiveInfoAtom;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.sl.usermodel.ShapeContainer;
/**
@@ -82,11 +92,7 @@ public final class MovieShape extends HSLFPictureShape {
setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100);
setEscherProperty(EscherProperties.FILL__NOFILLHITTEST, 0x10001);
- EscherClientDataRecord cldata = new EscherClientDataRecord();
- cldata.setOptions((short)0xF);
- _escherContainer.addChildRecord(cldata);
-
- OEShapeAtom oe = new OEShapeAtom();
+ ExObjRefAtom oe = new ExObjRefAtom();
InteractiveInfo info = new InteractiveInfo();
InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
infoAtom.setAction(InteractiveInfoAtom.ACTION_MEDIA);
@@ -96,16 +102,10 @@ public final class MovieShape extends HSLFPictureShape {
AnimationInfoAtom anAtom = an.getAnimationInfoAtom();
anAtom.setFlag(AnimationInfoAtom.Automatic, true);
- //convert hslf into ddf
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try {
- oe.writeOut(out);
- an.writeOut(out);
- info.writeOut(out);
- } catch(Exception e){
- throw new HSLFException(e);
- }
- cldata.setRemainingData(out.toByteArray());
+ HSLFEscherClientDataRecord cldata = getClientData(true);
+ cldata.addChild(oe);
+ cldata.addChild(an);
+ cldata.addChild(info);
return _escherContainer;
}
@@ -117,8 +117,8 @@ public final class MovieShape extends HSLFPictureShape {
* @param idx the index of the movie
*/
public void setMovieIndex(int idx){
- OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
- oe.setOptions(idx);
+ ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID);
+ oe.setExObjIdRef(idx);
AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if(an != null) {
@@ -135,7 +135,6 @@ public final class MovieShape extends HSLFPictureShape {
AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if(an != null){
an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag);
- updateClientData();
}
}
@@ -150,13 +149,16 @@ public final class MovieShape extends HSLFPictureShape {
/**
* @return UNC or local path to a video file
*/
+ @SuppressWarnings("resource")
public String getPath(){
- OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
- int idx = oe.getOptions();
+ ExObjRefAtom oe = getClientDataRecord(RecordTypes.ExObjRefAtom.typeID);
+ int idx = oe.getExObjIdRef();
HSLFSlideShow ppt = getSheet().getSlideShow();
ExObjList lst = (ExObjList)ppt.getDocumentRecord().findFirstOfType(RecordTypes.ExObjList.typeID);
- if(lst == null) return null;
+ if(lst == null) {
+ return null;
+ }
Record[] r = lst.getChildRecords();
for (int i = 0; i < r.length; i++) {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
index c61c5ce5a..c0e5948d7 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
@@ -17,14 +17,22 @@
package org.apache.poi.hslf.model;
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.usermodel.*;
-import org.apache.poi.hslf.record.ExObjList;
-import org.apache.poi.hslf.record.Record;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hslf.record.ExEmbed;
+import org.apache.poi.hslf.record.ExObjList;
+import org.apache.poi.hslf.record.ExObjRefAtom;
+import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
+import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.usermodel.HSLFObjectData;
+import org.apache.poi.hslf.usermodel.HSLFPictureData;
+import org.apache.poi.hslf.usermodel.HSLFPictureShape;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@@ -88,26 +96,19 @@ public final class OLEShape extends HSLFPictureShape {
EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID);
spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE);
- EscherContainerRecord uerCont = ecr.getChildById((short)RecordTypes.EscherClientData);
- if (uerCont == null) {
- uerCont = new EscherContainerRecord();
- ecr.addChildRecord(uerCont);
+ HSLFEscherClientDataRecord cldata = getClientData(true);
+ ExObjRefAtom uer = null;
+ for (Record r : cldata.getHSLFChildRecords()) {
+ if (r.getRecordType() == RecordTypes.ExObjRefAtom.typeID) {
+ uer = (ExObjRefAtom)r;
+ break;
+ }
}
- uerCont.setRecordId((short)RecordTypes.EscherClientData);
- uerCont.setVersion((short)0x000F); // yes, we are still a container ...
-
- UnknownEscherRecord uer = uerCont.getChildById((short)RecordTypes.ExObjRefAtom.typeID);
if (uer == null) {
- uer = new UnknownEscherRecord();
- uerCont.addChildRecord(uer);
+ uer = new ExObjRefAtom();
+ cldata.addChild(uer);
}
-
- byte uerData[] = new byte[12];
- LittleEndian.putShort( uerData, 0, (short)0 ); // options = 0
- LittleEndian.putShort( uerData, 2, (short)RecordTypes.ExObjRefAtom.typeID); // recordId
- LittleEndian.putInt( uerData, 4, 4 ); // remaining bytes
- LittleEndian.putInt( uerData, 8, objectId ); // the data
- uer.fillFields(uerData, 0, null);
+ uer.setExObjIdRef(objectId);
}
@@ -116,6 +117,7 @@ public final class OLEShape extends HSLFPictureShape {
*
* @return the unique identifier for the OLE object
*/
+ @SuppressWarnings("resource")
public HSLFObjectData getObjectData(){
HSLFSlideShow ppt = getSheet().getSlideShow();
HSLFObjectData[] ole = ppt.getEmbeddedObjects();
@@ -153,6 +155,7 @@ public final class OLEShape extends HSLFPictureShape {
* 6. MetaFile( 4033), optional
*
*/
+ @SuppressWarnings("resource")
public ExEmbed getExEmbed(){
if(_exEmbed == null){
HSLFSlideShow ppt = getSheet().getSlideShow();
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java
new file mode 100644
index 000000000..fa362c8dd
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjRefAtom.java
@@ -0,0 +1,94 @@
+/* ====================================================================
+ 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;
+
+import org.apache.poi.util.LittleEndian;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * ExObjRefAtom (3009).
+ *
+ * An atom record that specifies a reference to an external object.
+ *
+ */
+
+public final class ExObjRefAtom extends RecordAtom {
+ private byte[] _header;
+
+ /**
+ * A 4-byte unsigned integer that specifies a reference to an external object.
+ * It MUST be equal to the value of the exObjId field of an ExMediaAtom record
+ * or the value of the exObjId field of an ExOleObjAtom record.
+ */
+ private int exObjIdRef;
+
+ /**
+ * Create a new instance of ExObjRefAtom
+ */
+ public ExObjRefAtom() {
+ _header = new byte[8];
+ LittleEndian.putUShort(_header, 0, 0);
+ LittleEndian.putUShort(_header, 2, (int)getRecordType());
+ LittleEndian.putInt(_header, 4, 4);
+ exObjIdRef = 0;
+ }
+
+ /**
+ * Build an instance of ExObjRefAtom
from on-disk data
+ *
+ * @param source the source data as a byte array.
+ * @param start the start offset into the byte array.
+ * @param len the length of the slice in the byte array.
+ */
+ protected ExObjRefAtom(byte[] source, int start, int len) {
+ _header = new byte[8];
+ int offset = start;
+ System.arraycopy(source,start,_header,0,8);
+ offset += _header.length;
+ exObjIdRef = (int)LittleEndian.getUInt(source, offset);
+ }
+
+ /**
+ * @return type of this record {@link RecordTypes#ExObjRefAtom}.
+ */
+ public long getRecordType() {
+ return RecordTypes.ExObjRefAtom.typeID;
+ }
+
+ public int getExObjIdRef(){
+ return exObjIdRef;
+ }
+
+ public void setExObjIdRef(int id){
+ exObjIdRef = id;
+ }
+
+ /**
+ * Write the contents of the record back, so it can be written
+ * to disk
+ */
+ public void writeOut(OutputStream out) throws IOException {
+ out.write(_header);
+
+ byte[] recdata = new byte[4];
+ LittleEndian.putUInt(recdata, 0, exObjIdRef);
+
+ out.write(recdata);
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java b/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java
new file mode 100644
index 000000000..e6a2cdcac
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java
@@ -0,0 +1,120 @@
+/* ====================================================================
+ 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.ddf.EscherClientDataRecord;
+import org.apache.poi.ddf.EscherRecordFactory;
+import org.apache.poi.ddf.EscherSerializationListener;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * An atom record that specifies whether a shape is a placeholder shape.
+ * The number, position, and type of placeholder shapes are determined by
+ * the slide layout as specified in the SlideAtom record.
+ *
+ * @since POI 3.14-Beta2
+ */
+public class HSLFEscherClientDataRecord extends EscherClientDataRecord {
+
+ private final List _childRecords = new ArrayList();
+
+ public List extends Record> getHSLFChildRecords() {
+ return _childRecords;
+ }
+
+ public void removeChild(Class extends Record> childClass) {
+ Iterator iter = _childRecords.iterator();
+ while (iter.hasNext()) {
+ if (childClass.isInstance(iter.next())) {
+ iter.remove();
+ }
+ }
+ }
+
+ public void addChild(Record childRecord) {
+ _childRecords.add(childRecord);
+ }
+
+ @Override
+ public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
+ int bytesRemaining = readHeader( data, offset );
+ byte remainingData[] = new byte[bytesRemaining];
+ System.arraycopy(data, offset+8, remainingData, 0, bytesRemaining);
+ setRemainingData(remainingData);
+ return bytesRemaining + 8;
+ }
+
+ @Override
+ public int serialize(int offset, byte[] data, EscherSerializationListener listener) {
+ listener.beforeRecordSerialize( offset, getRecordId(), this );
+
+ LittleEndian.putShort(data, offset, getOptions());
+ LittleEndian.putShort(data, offset+2, getRecordId());
+
+ byte childBytes[] = getRemainingData();
+
+ LittleEndian.putInt(data, offset+4, childBytes.length);
+ System.arraycopy(childBytes, 0, data, offset+8, childBytes.length);
+ int recordSize = 8+childBytes.length;
+ listener.afterRecordSerialize( offset+recordSize, getRecordId(), recordSize, this );
+ return recordSize;
+ }
+
+ @Override
+ public int getRecordSize() {
+ return 8 + getRemainingData().length;
+ }
+
+ @Override
+ public byte[] getRemainingData() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ for (Record r : _childRecords) {
+ r.writeOut(bos);
+ }
+ } catch (IOException e) {
+ throw new HSLFException(e);
+ }
+ return bos.toByteArray();
+ }
+
+ @Override
+ public void setRemainingData( byte[] remainingData ) {
+ _childRecords.clear();
+ int offset = 0;
+ while (offset < remainingData.length) {
+ Record r = Record.buildRecordAtOffset(remainingData, offset);
+ _childRecords.add(r);
+ long rlen = LittleEndian.getUInt(remainingData,offset+4);
+ offset += 8 + rlen;
+ }
+ }
+
+ public String getRecordName() {
+ return "HSLFClientData";
+ }
+
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java b/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java
index c985864f0..a37ea943c 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherRecordFactory.java
@@ -29,7 +29,7 @@ import org.apache.poi.util.LittleEndian;
* @see EscherRecordFactory
*/
public class HSLFEscherRecordFactory extends DefaultEscherRecordFactory {
- private static Class>[] escherRecordClasses = { EscherPlaceholder.class };
+ private static Class>[] escherRecordClasses = { EscherPlaceholder.class, HSLFEscherClientDataRecord.class };
private static Map> recordsMap = recordsToMap( escherRecordClasses );
@@ -65,6 +65,10 @@ public class HSLFEscherRecordFactory extends DefaultEscherRecordFactory {
}
escherRecord.setRecordId(recordId);
escherRecord.setOptions(options);
+ if (escherRecord instanceof EscherContainerRecord) {
+ ((EscherContainerRecord)escherRecord).fillFields(data, offset, this);
+ }
+
return escherRecord;
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
index 1d8d7df62..54d5d8622 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
@@ -201,6 +201,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
private int placementId;
private int placeholderId;
private int placeholderSize;
+ private short unusedShort = 0;
/**
@@ -227,8 +228,9 @@ public final class OEPlaceholderAtom extends RecordAtom{
offset += _header.length;
placementId = LittleEndian.getInt(source, offset); offset += 4;
- placeholderId = LittleEndian.getUnsignedByte(source, offset); offset++;
- placeholderSize = LittleEndian.getUnsignedByte(source, offset); offset++;
+ placeholderId = LittleEndian.getUByte(source, offset); offset++;
+ placeholderSize = LittleEndian.getUByte(source, offset); offset++;
+ unusedShort = LittleEndian.getShort(source, offset);
}
/**
@@ -322,6 +324,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
LittleEndian.putInt(recdata, 0, placementId);
recdata[4] = (byte)placeholderId;
recdata[5] = (byte)placeholderSize;
+ LittleEndian.putShort(recdata, 6, unusedShort);
out.write(recdata);
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/OEShapeAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/OEShapeAtom.java
deleted file mode 100644
index 00b873f6d..000000000
--- a/src/scratchpad/src/org/apache/poi/hslf/record/OEShapeAtom.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ====================================================================
- 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;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.poi.util.LittleEndian;
-
-/**
- * Atom that contains information that describes shape client data.
- *
- * @author Yegor Kozlov
- */
-public final class OEShapeAtom extends RecordAtom
-{
-
- /**
- * Record header.
- */
- private byte[] _header;
-
- /**
- * record data
- */
- private byte[] _recdata;
-
- /**
- * Constructs a brand new link related atom record.
- */
- public OEShapeAtom() {
- _recdata = new byte[4];
-
- _header = new byte[8];
- LittleEndian.putShort(_header, 2, (short)getRecordType());
- LittleEndian.putInt(_header, 4, _recdata.length);
- }
-
- /**
- * Constructs the link related atom record from its
- * source data.
- *
- * @param source the source data as a byte array.
- * @param start the start offset into the byte array.
- * @param len the length of the slice in the byte array.
- */
- protected OEShapeAtom(byte[] source, int start, int len) {
- // Get the header
- _header = new byte[8];
- System.arraycopy(source,start,_header,0,8);
-
- // Grab the record data
- _recdata = new byte[len-8];
- System.arraycopy(source,start+8,_recdata,0,len-8);
- }
-
- /**
- * Gets the record type.
- * @return the record type.
- */
- public long getRecordType() { return RecordTypes.OEShapeAtom.typeID; }
-
- /**
- * Write the contents of the record back, so it can be written
- * to disk
- *
- * @param out the output stream to write to.
- * @throws java.io.IOException if an error occurs.
- */
- public void writeOut(OutputStream out) throws IOException {
- out.write(_header);
- out.write(_recdata);
- }
-
- /**
- * shape flags.
- *
- * @return shape flags.
- */
- public int getOptions(){
- return LittleEndian.getInt(_recdata, 0);
- }
-
- /**
- * shape flags.
- *
- * @param id shape flags.
- */
- public void setOptions(int id){
- LittleEndian.putInt(_recdata, 0, id);
- }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
index 637f9a8ab..90b24ed9f 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
@@ -20,7 +20,6 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -36,7 +35,6 @@ import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherSpgrRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
-import org.apache.poi.ddf.UnknownEscherRecord;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@@ -57,7 +55,7 @@ public final class PPDrawing extends RecordAtom {
private byte[] _header;
private long _type;
- private EscherRecord[] childRecords;
+ private final List childRecords = new ArrayList();
private EscherTextboxWrapper[] textboxWrappers;
//cached EscherDgRecord
@@ -66,7 +64,7 @@ public final class PPDrawing extends RecordAtom {
/**
* Get access to the underlying Escher Records
*/
- public EscherRecord[] getEscherRecords() { return childRecords; }
+ public List getEscherRecords() { return childRecords; }
/**
* Get access to the atoms inside Textboxes
@@ -76,6 +74,20 @@ public final class PPDrawing extends RecordAtom {
/* ******************** record stuff follows ********************** */
+ /**
+ * Creates a new, empty, PPDrawing (typically for use with a new Slide
+ * or Notes)
+ */
+ public PPDrawing() {
+ _header = new byte[8];
+ LittleEndian.putUShort(_header, 0, 15);
+ LittleEndian.putUShort(_header, 2, RecordTypes.PPDrawing.typeID);
+ LittleEndian.putInt(_header, 4, 0);
+
+ textboxWrappers = new EscherTextboxWrapper[]{};
+ create();
+ }
+
/**
* Sets everything up, groks the escher etc
*/
@@ -93,12 +105,11 @@ public final class PPDrawing extends RecordAtom {
// Build up a tree of Escher records contained within
final DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
- final List escherChildren = new ArrayList();
- findEscherChildren(erf, contents, 8, len-8, escherChildren);
- this.childRecords = escherChildren.toArray(new EscherRecord[escherChildren.size()]);
+ findEscherChildren(erf, contents, 8, len-8, childRecords);
+ EscherContainerRecord dgContainer = getDgContainer();
- if (1 == this.childRecords.length && (short)RecordTypes.EscherDgContainer == this.childRecords[0].getRecordId() && this.childRecords[0] instanceof EscherContainerRecord) {
- this.textboxWrappers = findInDgContainer((EscherContainerRecord) this.childRecords[0]);
+ if (dgContainer != null) {
+ textboxWrappers = findInDgContainer(dgContainer);
} else {
// Find and EscherTextboxRecord's, and wrap them up
final List textboxes = new ArrayList();
@@ -108,15 +119,15 @@ public final class PPDrawing extends RecordAtom {
}
private EscherTextboxWrapper[] findInDgContainer(final EscherContainerRecord dgContainer) {
final List found = new LinkedList();
- final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherSpgrContainer, dgContainer);
- final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType((short)RecordTypes.EscherSpContainer, spgrContainer);
+ final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType(RecordTypes.EscherSpgrContainer, dgContainer);
+ final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType(RecordTypes.EscherSpContainer, spgrContainer);
for (EscherContainerRecord spContainer : spContainers) {
- StyleTextProp9Atom nineAtom = findInSpContainer(spContainer);
- EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherSp, spContainer);
- EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType((short)RecordTypes.EscherClientTextbox, spContainer);
+ EscherSpRecord sp = (EscherSpRecord)findFirstEscherRecordOfType(RecordTypes.EscherSp, spContainer);
+ EscherTextboxRecord clientTextbox = (EscherTextboxRecord)findFirstEscherRecordOfType(RecordTypes.EscherClientTextbox, spContainer);
if (null == clientTextbox) { continue; }
EscherTextboxWrapper w = new EscherTextboxWrapper(clientTextbox);
+ StyleTextProp9Atom nineAtom = findInSpContainer(spContainer);
w.setStyleTextProp9Atom(nineAtom);
if (null != sp) {
w.setShapeId(sp.getShapeId());
@@ -127,16 +138,26 @@ public final class PPDrawing extends RecordAtom {
}
private StyleTextProp9Atom findInSpContainer(final EscherContainerRecord spContainer) {
- EscherContainerRecord clientData = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherClientData, spContainer);
- if (null == clientData) { return null; }
- final EscherContainerRecord progTagsContainer = findFirstEscherContainerRecordOfType((short)0x1388, clientData);
- if (null == progTagsContainer) { return null; }
- final EscherContainerRecord progBinaryTag = findFirstEscherContainerRecordOfType((short)0x138A, progTagsContainer);
- if (null == progBinaryTag) { return null; }
- int size = progBinaryTag.getChildRecords().size();
+ HSLFEscherClientDataRecord cldata = spContainer.getChildById(RecordTypes.EscherClientData.typeID);
+ if (cldata == null) {
+ return null;
+ }
+ DummyPositionSensitiveRecordWithChildren progTags =
+ getChildRecord(cldata.getHSLFChildRecords(), RecordTypes.ProgTags);
+ if (progTags == null) {
+ return null;
+ }
+ DummyPositionSensitiveRecordWithChildren progBinaryTag =
+ (DummyPositionSensitiveRecordWithChildren)progTags.findFirstOfType(RecordTypes.ProgBinaryTag.typeID);
+ if (progBinaryTag == null) {
+ return null;
+ }
+ int size = progBinaryTag.getChildRecords().length;
if (2 != size) { return null; }
- final Record r0 = buildFromUnknownEscherRecord((UnknownEscherRecord) progBinaryTag.getChild(0));
- final Record r1 = buildFromUnknownEscherRecord((UnknownEscherRecord) progBinaryTag.getChild(1));
+
+ final Record r0 = progBinaryTag.getChildRecords()[0];
+ final Record r1 = progBinaryTag.getChildRecords()[1];
+
if (!(r0 instanceof CString)) { return null; }
if (!("___PPT9".equals(((CString) r0).getText()))) { return null; };
if (!(r1 instanceof BinaryTagDataBlob )) { return null; }
@@ -144,19 +165,6 @@ public final class PPDrawing extends RecordAtom {
if (1 != blob.getChildRecords().length) { return null; }
return (StyleTextProp9Atom) blob.findFirstOfType(RecordTypes.StyleTextProp9Atom.typeID);
}
- /**
- * Creates a new, empty, PPDrawing (typically for use with a new Slide
- * or Notes)
- */
- public PPDrawing(){
- _header = new byte[8];
- LittleEndian.putUShort(_header, 0, 15);
- LittleEndian.putUShort(_header, 2, RecordTypes.PPDrawing.typeID);
- LittleEndian.putInt(_header, 4, 0);
-
- textboxWrappers = new EscherTextboxWrapper[]{};
- create();
- }
/**
* Tree walking way of finding Escher Child Records
@@ -198,27 +206,22 @@ public final class PPDrawing extends RecordAtom {
/**
* Look for EscherTextboxRecords
*/
- private void findEscherTextboxRecord(EscherRecord[] toSearch, List found) {
- for(int i=0; i toSearch, List found) {
+ EscherSpRecord sp = null;
+ for (EscherRecord r : toSearch) {
+ if (r instanceof EscherSpRecord) {
+ sp = (EscherSpRecord)r;
+ } else if (r instanceof EscherTextboxRecord) {
+ EscherTextboxRecord tbr = (EscherTextboxRecord)r;
EscherTextboxWrapper w = new EscherTextboxWrapper(tbr);
+ if (sp != null) {
+ w.setShapeId(sp.getShapeId());
+ }
found.add(w);
- for (int j = i; j >= 0; j--) {
- if(toSearch[j] instanceof EscherSpRecord){
- EscherSpRecord sp = (EscherSpRecord)toSearch[j];
- w.setShapeId(sp.getShapeId());
- break;
- }
- }
- } else {
+ } else if (r.isContainerRecord()) {
// If it has children, walk them
- if(toSearch[i].isContainerRecord()) {
- List childrenL = toSearch[i].getChildRecords();
- EscherRecord[] children = new EscherRecord[childrenL.size()];
- childrenL.toArray(children);
- findEscherTextboxRecord(children,found);
- }
+ List children = r.getChildRecords();
+ findEscherTextboxRecord(children,found);
}
}
}
@@ -259,9 +262,8 @@ public final class PPDrawing extends RecordAtom {
// Now grab the children's data
byte[] b = new byte[newSize];
int done = 0;
- for(int i=0; i it = dgContainer.getChildIterator(); it.hasNext();){
- EscherRecord r = it.next();
+ for(EscherRecord r : getDgContainer().getChildRecords()){
if(r instanceof EscherDgRecord){
dg = (EscherDgRecord)r;
break;
@@ -357,59 +371,59 @@ public final class PPDrawing extends RecordAtom {
return dg;
}
- protected EscherContainerRecord findFirstEscherContainerRecordOfType(short type, EscherContainerRecord parent) {
+ protected EscherContainerRecord findFirstEscherContainerRecordOfType(RecordTypes type, EscherContainerRecord parent) {
if (null == parent) { return null; }
final List children = parent.getChildContainers();
for (EscherContainerRecord child : children) {
- if (type == child.getRecordId()) {
+ if (type.typeID == child.getRecordId()) {
return child;
}
}
return null;
}
- protected EscherRecord findFirstEscherRecordOfType(short type, EscherContainerRecord parent) {
+ protected EscherRecord findFirstEscherRecordOfType(RecordTypes type, EscherContainerRecord parent) {
if (null == parent) { return null; }
final List children = parent.getChildRecords();
for (EscherRecord child : children) {
- if (type == child.getRecordId()) {
+ if (type.typeID == child.getRecordId()) {
return child;
}
}
return null;
}
- protected EscherContainerRecord[] findAllEscherContainerRecordOfType(short type, EscherContainerRecord parent) {
+ protected EscherContainerRecord[] findAllEscherContainerRecordOfType(RecordTypes type, EscherContainerRecord parent) {
if (null == parent) { return new EscherContainerRecord[0]; }
final List children = parent.getChildContainers();
final List result = new LinkedList();
for (EscherContainerRecord child : children) {
- if (type == child.getRecordId()) {
+ if (type.typeID == child.getRecordId()) {
result.add(child);
}
}
return result.toArray(new EscherContainerRecord[result.size()]);
}
- protected Record buildFromUnknownEscherRecord(UnknownEscherRecord unknown) {
- byte[] bingo = unknown.getData();
- byte[] restoredRecord = new byte[8 + bingo.length];
- System.arraycopy(bingo, 0, restoredRecord, 8, bingo.length);
- short recordVersion = unknown.getVersion();
- short recordId = unknown.getRecordId();
- int recordLength = unknown.getRecordSize();
- LittleEndian.putShort(restoredRecord, 0, recordVersion);
- LittleEndian.putShort(restoredRecord, 2, recordId);
- LittleEndian.putInt(restoredRecord, 4, recordLength);
- return Record.createRecordForType(recordId, restoredRecord, 0, restoredRecord.length);
- }
public StyleTextProp9Atom[] getNumberedListInfo() {
final List result = new LinkedList();
- EscherContainerRecord dgContainer = (EscherContainerRecord)childRecords[0];
- final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType((short)RecordTypes.EscherSpgrContainer, dgContainer);
- final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType((short)RecordTypes.EscherSpContainer, spgrContainer);
+ EscherContainerRecord dgContainer = getDgContainer();
+ final EscherContainerRecord spgrContainer = findFirstEscherContainerRecordOfType(RecordTypes.EscherSpgrContainer, dgContainer);
+ final EscherContainerRecord[] spContainers = findAllEscherContainerRecordOfType(RecordTypes.EscherSpContainer, spgrContainer);
for (EscherContainerRecord spContainer : spContainers) {
StyleTextProp9Atom prop9 = findInSpContainer(spContainer);
- if (prop9 != null) result.add(prop9);
+ if (prop9 != null) {
+ result.add(prop9);
+ }
}
return result.toArray(new StyleTextProp9Atom[result.size()]);
}
+
+ @SuppressWarnings("unchecked")
+ private static T getChildRecord(List extends Record> children, RecordTypes type) {
+ for (Record r : children) {
+ if (r.getRecordType() == type.typeID) {
+ return (T)r;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Record.java b/src/scratchpad/src/org/apache/poi/hslf/record/Record.java
index 78db7ee27..61034f1f9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/Record.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/Record.java
@@ -166,19 +166,19 @@ public abstract class Record
// Any special record handling occurs once we have the class
Class extends Record> c = null;
try {
- c = RecordTypes.recordHandlingClass((int)type);
+ c = RecordTypes.forTypeID((short)type).handlingClass;
if(c == null) {
// How odd. RecordTypes normally subsitutes in
// a default handler class if it has heard of the record
// type but there's no support for it. Explicitly request
// that now
- c = RecordTypes.recordHandlingClass( RecordTypes.Unknown.typeID );
+ c = RecordTypes.UnknownRecordPlaceholder.handlingClass;
}
// Grab the right constructor
java.lang.reflect.Constructor extends Record> con = c.getDeclaredConstructor(new Class[] { byte[].class, Integer.TYPE, Integer.TYPE });
// Instantiate
- toReturn = con.newInstance(new Object[] { b, Integer.valueOf(start), Integer.valueOf(len) });
+ toReturn = con.newInstance(new Object[] { b, start, len });
} catch(InstantiationException ie) {
throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ie, ie);
} catch(java.lang.reflect.InvocationTargetException ite) {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
index 73a95f6d9..c20ca12b2 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
@@ -17,8 +17,8 @@
package org.apache.poi.hslf.record;
-import java.lang.reflect.Field;
import java.util.HashMap;
+import java.util.Map;
/**
* List of all known record types in a PowerPoint document, and the
@@ -26,191 +26,209 @@ import java.util.HashMap;
* There are two categories of records:
* PowerPoint records: 0 <= info <= 10002 (will carry class info)
* Escher records: info >= 0xF000 (handled by DDF, so no class info)
- *
- * @author Yegor Kozlov
- * @author Nick Burch
*/
-public final class RecordTypes {
- public static final HashMap typeToName;
- public static final HashMap> typeToClass;
-
- public static final Type Unknown = new Type(0,null);
- public static final Type Document = new Type(1000,Document.class);
- public static final Type DocumentAtom = new Type(1001,DocumentAtom.class);
- public static final Type EndDocument = new Type(1002,null);
- public static final Type Slide = new Type(1006,Slide.class);
- public static final Type SlideAtom = new Type(1007,SlideAtom.class);
- public static final Type Notes = new Type(1008,Notes.class);
- public static final Type NotesAtom = new Type(1009,NotesAtom.class);
- public static final Type Environment = new Type(1010,Environment.class);
- public static final Type SlidePersistAtom = new Type(1011,SlidePersistAtom.class);
- public static final Type SSlideLayoutAtom = new Type(1015,null);
- public static final Type MainMaster = new Type(1016,MainMaster.class);
- public static final Type SSSlideInfoAtom = new Type(1017,SSSlideInfoAtom.class);
- public static final Type SlideViewInfo = new Type(1018,null);
- public static final Type GuideAtom = new Type(1019,null);
- public static final Type ViewInfo = new Type(1020,null);
- public static final Type ViewInfoAtom = new Type(1021,null);
- public static final Type SlideViewInfoAtom = new Type(1022,null);
- public static final Type VBAInfo = new Type(1023,null);
- public static final Type VBAInfoAtom = new Type(1024,null);
- public static final Type SSDocInfoAtom = new Type(1025,null);
- public static final Type Summary = new Type(1026,null);
- public static final Type DocRoutingSlip = new Type(1030,null);
- public static final Type OutlineViewInfo = new Type(1031,null);
- public static final Type SorterViewInfo = new Type(1032,null);
- public static final Type ExObjList = new Type(1033,ExObjList.class);
- public static final Type ExObjListAtom = new Type(1034,ExObjListAtom.class);
- public static final Type PPDrawingGroup = new Type(1035,PPDrawingGroup.class);
- public static final Type PPDrawing = new Type(1036,PPDrawing.class);
- public static final Type NamedShows = new Type(1040,null);
- public static final Type NamedShow = new Type(1041,null);
- public static final Type NamedShowSlides = new Type(1042,null);
- public static final Type SheetProperties = new Type(1044,null);
- public static final Type RoundTripCustomTableStyles12Atom = new Type(1064,null);
- public static final Type List = new Type(2000,null);
- public static final Type FontCollection = new Type(2005,FontCollection.class);
- public static final Type BookmarkCollection = new Type(2019,null);
- public static final Type SoundCollection = new Type(2020,SoundCollection.class);
- public static final Type SoundCollAtom = new Type(2021,null);
- public static final Type Sound = new Type(2022,Sound.class);
- public static final Type SoundData = new Type(2023,SoundData.class);
- public static final Type BookmarkSeedAtom = new Type(2025,null);
- public static final Type ColorSchemeAtom = new Type(2032,ColorSchemeAtom.class);
- public static final Type ExObjRefAtom = new Type(3009,null);
- public static final Type OEShapeAtom = new Type(3009,OEShapeAtom.class);
- public static final Type OEPlaceholderAtom = new Type(3011,OEPlaceholderAtom.class);
- public static final Type GPopublicintAtom = new Type(3024,null);
- public static final Type GRatioAtom = new Type(3031,null);
- public static final Type OutlineTextRefAtom = new Type(3998,OutlineTextRefAtom.class);
- public static final Type TextHeaderAtom = new Type(3999,TextHeaderAtom.class);
- public static final Type TextCharsAtom = new Type(4000,TextCharsAtom.class);
- public static final Type StyleTextPropAtom = new Type(4001, StyleTextPropAtom.class);//0x0fa1 RT_StyleTextPropAtom
- public static final Type MasterTextPropAtom = new Type(4002, MasterTextPropAtom.class);
- public static final Type TxMasterStyleAtom = new Type(4003,TxMasterStyleAtom.class);
- public static final Type TxCFStyleAtom = new Type(4004,null);
- public static final Type TxPFStyleAtom = new Type(4005,null);
- public static final Type TextRulerAtom = new Type(4006,TextRulerAtom.class);
- public static final Type TextBookmarkAtom = new Type(4007,null);
- public static final Type TextBytesAtom = new Type(4008,TextBytesAtom.class);
- public static final Type TxSIStyleAtom = new Type(4009,null);
- public static final Type TextSpecInfoAtom = new Type(4010, TextSpecInfoAtom.class);
- public static final Type DefaultRulerAtom = new Type(4011,null);
- public static final Type StyleTextProp9Atom = new Type(4012, StyleTextProp9Atom.class); //0x0FAC RT_StyleTextProp9Atom
- public static final Type FontEntityAtom = new Type(4023,FontEntityAtom.class);
- public static final Type FontEmbeddedData = new Type(4024,null);
- public static final Type CString = new Type(4026,CString.class);
- public static final Type MetaFile = new Type(4033,null);
- public static final Type ExOleObjAtom = new Type(4035,ExOleObjAtom.class);
- public static final Type SrKinsoku = new Type(4040,null);
- public static final Type HandOut = new Type(4041,DummyPositionSensitiveRecordWithChildren.class);
- public static final Type ExEmbed = new Type(4044,ExEmbed.class);
- public static final Type ExEmbedAtom = new Type(4045,ExEmbedAtom.class);
- public static final Type ExLink = new Type(4046,null);
- public static final Type BookmarkEntityAtom = new Type(4048,null);
- public static final Type ExLinkAtom = new Type(4049,null);
- public static final Type SrKinsokuAtom = new Type(4050,null);
- 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,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 static final Type RecolorInfoAtom = new Type(4071,null);
- public static final Type ExQuickTimeMovie = new Type(4074,null);
- public static final Type ExQuickTimeMovieData = new Type(4075,null);
- public static final Type ExControl = new Type(4078,ExControl.class);
- public static final Type SlideListWithText = new Type(4080,SlideListWithText.class);
- public static final Type InteractiveInfo = new Type(4082,InteractiveInfo.class);
- public static final Type InteractiveInfoAtom = new Type(4083,InteractiveInfoAtom.class);
- public static final Type UserEditAtom = new Type(4085,UserEditAtom.class);
- public static final Type CurrentUserAtom = new Type(4086,null);
- public static final Type DateTimeMCAtom = new Type(4087,null);
- public static final Type GenericDateMCAtom = new Type(4088,null);
- public static final Type FooterMCAtom = new Type(4090,null);
- public static final Type ExControlAtom = new Type(4091,ExControlAtom.class);
- public static final Type ExMediaAtom = new Type(4100,ExMediaAtom.class);
- public static final Type ExVideoContainer = new Type(4101,ExVideoContainer.class);
- public static final Type ExAviMovie = new Type(4102,ExAviMovie.class);
- public static final Type ExMCIMovie = new Type(4103,ExMCIMovie.class);
- public static final Type ExMIDIAudio = new Type(4109,null);
- public static final Type ExCDAudio = new Type(4110,null);
- public static final Type ExWAVAudioEmbedded = new Type(4111,null);
- public static final Type ExWAVAudioLink = new Type(4112,null);
- public static final Type ExOleObjStg = new Type(4113,ExOleObjStg.class);
- public static final Type ExCDAudioAtom = new Type(4114,null);
- public static final Type ExWAVAudioEmbeddedAtom = new Type(4115,null);
- public static final Type AnimationInfo = new Type(4116,AnimationInfo.class);
- public static final Type AnimationInfoAtom = new Type(4081,AnimationInfoAtom.class);
- public static final Type RTFDateTimeMCAtom = new Type(4117,null);
- public static final Type ProgTags = new Type(5000,DummyPositionSensitiveRecordWithChildren.class);
- public static final Type ProgStringTag = new Type(5001,null);
- public static final Type ProgBinaryTag = new Type(5002,DummyPositionSensitiveRecordWithChildren.class);
- public static final Type BinaryTagData = new Type(5003, BinaryTagDataBlob.class);//0x138b RT_BinaryTagDataBlob
- public static final Type PrpublicintOptions = new Type(6000,null);
- public static final Type PersistPtrFullBlock = new Type(6001,PersistPtrHolder.class);
- public static final Type PersistPtrIncrementalBlock = new Type(6002,PersistPtrHolder.class);
- public static final Type GScalingAtom = new Type(10001,null);
- public static final Type GRColorAtom = new Type(10002,null);
+public enum RecordTypes {
+ Unknown(0,null),
+ UnknownRecordPlaceholder(-1, UnknownRecordPlaceholder.class),
+ Document(1000,Document.class),
+ DocumentAtom(1001,DocumentAtom.class),
+ EndDocument(1002,null),
+ Slide(1006,Slide.class),
+ SlideAtom(1007,SlideAtom.class),
+ Notes(1008,Notes.class),
+ NotesAtom(1009,NotesAtom.class),
+ Environment(1010,Environment.class),
+ SlidePersistAtom(1011,SlidePersistAtom.class),
+ SSlideLayoutAtom(1015,null),
+ MainMaster(1016,MainMaster.class),
+ SSSlideInfoAtom(1017,SSSlideInfoAtom.class),
+ SlideViewInfo(1018,null),
+ GuideAtom(1019,null),
+ ViewInfo(1020,null),
+ ViewInfoAtom(1021,null),
+ SlideViewInfoAtom(1022,null),
+ VBAInfo(1023,null),
+ VBAInfoAtom(1024,null),
+ SSDocInfoAtom(1025,null),
+ Summary(1026,null),
+ DocRoutingSlip(1030,null),
+ OutlineViewInfo(1031,null),
+ SorterViewInfo(1032,null),
+ ExObjList(1033,ExObjList.class),
+ ExObjListAtom(1034,ExObjListAtom.class),
+ PPDrawingGroup(1035,PPDrawingGroup.class),
+ PPDrawing(1036,PPDrawing.class),
+ NamedShows(1040,null),
+ NamedShow(1041,null),
+ NamedShowSlides(1042,null),
+ SheetProperties(1044,null),
+ RoundTripCustomTableStyles12Atom(1064,null),
+ List(2000,null),
+ FontCollection(2005,FontCollection.class),
+ BookmarkCollection(2019,null),
+ SoundCollection(2020,SoundCollection.class),
+ SoundCollAtom(2021,null),
+ Sound(2022,Sound.class),
+ SoundData(2023,SoundData.class),
+ BookmarkSeedAtom(2025,null),
+ ColorSchemeAtom(2032,ColorSchemeAtom.class),
+ ExObjRefAtom(3009,ExObjRefAtom.class),
+ OEPlaceholderAtom(3011,OEPlaceholderAtom.class),
+ GPopublicintAtom(3024,null),
+ GRatioAtom(3031,null),
+ OutlineTextRefAtom(3998,OutlineTextRefAtom.class),
+ TextHeaderAtom(3999,TextHeaderAtom.class),
+ TextCharsAtom(4000,TextCharsAtom.class),
+ StyleTextPropAtom(4001, StyleTextPropAtom.class),//0x0fa1 RT_StyleTextPropAtom
+ MasterTextPropAtom(4002, MasterTextPropAtom.class),
+ TxMasterStyleAtom(4003,TxMasterStyleAtom.class),
+ TxCFStyleAtom(4004,null),
+ TxPFStyleAtom(4005,null),
+ TextRulerAtom(4006,TextRulerAtom.class),
+ TextBookmarkAtom(4007,null),
+ TextBytesAtom(4008,TextBytesAtom.class),
+ TxSIStyleAtom(4009,null),
+ TextSpecInfoAtom(4010, TextSpecInfoAtom.class),
+ DefaultRulerAtom(4011,null),
+ StyleTextProp9Atom(4012, StyleTextProp9Atom.class), //0x0FAC RT_StyleTextProp9Atom
+ FontEntityAtom(4023,FontEntityAtom.class),
+ FontEmbeddedData(4024,null),
+ CString(4026,CString.class),
+ MetaFile(4033,null),
+ ExOleObjAtom(4035,ExOleObjAtom.class),
+ SrKinsoku(4040,null),
+ HandOut(4041,DummyPositionSensitiveRecordWithChildren.class),
+ ExEmbed(4044,ExEmbed.class),
+ ExEmbedAtom(4045,ExEmbedAtom.class),
+ ExLink(4046,null),
+ BookmarkEntityAtom(4048,null),
+ ExLinkAtom(4049,null),
+ SrKinsokuAtom(4050,null),
+ ExHyperlinkAtom(4051,ExHyperlinkAtom.class),
+ ExHyperlink(4055,ExHyperlink.class),
+ SlideNumberMCAtom(4056,null),
+ HeadersFooters(4057,HeadersFootersContainer.class),
+ HeadersFootersAtom(4058,HeadersFootersAtom.class),
+ TxInteractiveInfoAtom(4063,TxInteractiveInfoAtom.class),
+ CharFormatAtom(4066,null),
+ ParaFormatAtom(4067,null),
+ RecolorInfoAtom(4071,null),
+ ExQuickTimeMovie(4074,null),
+ ExQuickTimeMovieData(4075,null),
+ ExControl(4078,ExControl.class),
+ SlideListWithText(4080,SlideListWithText.class),
+ InteractiveInfo(4082,InteractiveInfo.class),
+ InteractiveInfoAtom(4083,InteractiveInfoAtom.class),
+ UserEditAtom(4085,UserEditAtom.class),
+ CurrentUserAtom(4086,null),
+ DateTimeMCAtom(4087,null),
+ GenericDateMCAtom(4088,null),
+ FooterMCAtom(4090,null),
+ ExControlAtom(4091,ExControlAtom.class),
+ ExMediaAtom(4100,ExMediaAtom.class),
+ ExVideoContainer(4101,ExVideoContainer.class),
+ ExAviMovie(4102,ExAviMovie.class),
+ ExMCIMovie(4103,ExMCIMovie.class),
+ ExMIDIAudio(4109,null),
+ ExCDAudio(4110,null),
+ ExWAVAudioEmbedded(4111,null),
+ ExWAVAudioLink(4112,null),
+ ExOleObjStg(4113,ExOleObjStg.class),
+ ExCDAudioAtom(4114,null),
+ ExWAVAudioEmbeddedAtom(4115,null),
+ AnimationInfo(4116,AnimationInfo.class),
+ AnimationInfoAtom(4081,AnimationInfoAtom.class),
+ RTFDateTimeMCAtom(4117,null),
+ ProgTags(5000,DummyPositionSensitiveRecordWithChildren.class),
+ ProgStringTag(5001,null),
+ ProgBinaryTag(5002,DummyPositionSensitiveRecordWithChildren.class),
+ BinaryTagData(5003, BinaryTagDataBlob.class),//0x138b RT_BinaryTagDataBlob
+ PrpublicintOptions(6000,null),
+ PersistPtrFullBlock(6001,PersistPtrHolder.class),
+ PersistPtrIncrementalBlock(6002,PersistPtrHolder.class),
+ GScalingAtom(10001,null),
+ GRColorAtom(10002,null),
// Records ~12000 seem to be related to the Comments used in PPT 2000/XP
// (Comments in PPT97 are normal Escher text boxes)
- public static final Type Comment2000 = new Type(12000,Comment2000.class);
- public static final Type Comment2000Atom = new Type(12001,Comment2000Atom.class);
- public static final Type Comment2000Summary = new Type(12004,null);
- public static final Type Comment2000SummaryAtom = new Type(12005,null);
+ Comment2000(12000,Comment2000.class),
+ Comment2000Atom(12001,Comment2000Atom.class),
+ Comment2000Summary(12004,null),
+ Comment2000SummaryAtom(12005,null),
// Records ~12050 seem to be related to Document Encryption
- public static final Type DocumentEncryptionAtom = new Type(12052,DocumentEncryptionAtom.class);
+ DocumentEncryptionAtom(12052,DocumentEncryptionAtom.class),
+
+ OriginalMainMasterId(1052,null),
+ CompositeMasterId(1052,null),
+ RoundTripContentMasterInfo12(1054,null),
+ RoundTripShapeId12(1055,null),
+ RoundTripHFPlaceholder12(1056,RoundTripHFPlaceholder12.class),
+ RoundTripContentMasterId(1058,null),
+ RoundTripOArtTextStyles12(1059,null),
+ RoundTripShapeCheckSumForCustomLayouts12(1062,null),
+ RoundTripNotesMasterTextStyles12(1063,null),
+ RoundTripCustomTableStyles12(1064,null),
+
+ // records greater then 0xF000 belong to with Microsoft Office Drawing format also known as Escher
+ EscherDggContainer(0xF000,null),
+ EscherDgg(0xf006,null),
+ EscherCLSID(0xf016,null),
+ EscherOPT(0xf00b,null),
+ EscherBStoreContainer(0xf001,null),
+ EscherBSE(0xf007,null),
+ EscherBlip_START(0xf018,null),
+ EscherBlip_END(0xf117,null),
+ EscherDgContainer(0xf002,null),
+ EscherDg(0xf008,null),
+ EscherRegroupItems(0xf118,null),
+ EscherColorScheme(0xf120,null),
+ EscherSpgrContainer(0xf003,null),
+ EscherSpContainer(0xf004,null),
+ EscherSpgr(0xf009,null),
+ EscherSp(0xf00a,null),
+ EscherTextbox(0xf00c,null),
+ EscherClientTextbox(0xf00d,null),
+ EscherAnchor(0xf00e,null),
+ EscherChildAnchor(0xf00f,null),
+ EscherClientAnchor(0xf010,null),
+ EscherClientData(0xf011,null),
+ EscherSolverContainer(0xf005,null),
+ EscherConnectorRule(0xf012,null),
+ EscherAlignRule(0xf013,null),
+ EscherArcRule(0xf014,null),
+ EscherClientRule(0xf015,null),
+ EscherCalloutRule(0xf017,null),
+ EscherSelection(0xf119,null),
+ EscherColorMRU(0xf11a,null),
+ EscherDeletedPspl(0xf11d,null),
+ EscherSplitMenuColors(0xf11e,null),
+ EscherOleObject(0xf11f,null),
+ EscherUserDefined(0xf122,null);
+
+ private static final Map LOOKUP;
+
+ static {
+ LOOKUP = new HashMap();
+ for(RecordTypes s : values()) {
+ LOOKUP.put(s.typeID, s);
+ }
+ }
+
+ public final short typeID;
+ public final Class extends Record> handlingClass;
+
+ private RecordTypes(int typeID, Class extends Record> handlingClass) {
+ this.typeID = (short)typeID;
+ this.handlingClass = handlingClass;
+ }
+
+ public static RecordTypes forTypeID(int typeID) {
+ RecordTypes rt = LOOKUP.get((short)typeID);
+ return (rt != null) ? rt : UnknownRecordPlaceholder;
+ }
- 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;
- public static final int EscherCLSID = 0xf016;
- public static final int EscherOPT = 0xf00b;
- public static final int EscherBStoreContainer = 0xf001;
- public static final int EscherBSE = 0xf007;
- public static final int EscherBlip_START = 0xf018;
- public static final int EscherBlip_END = 0xf117;
- public static final int EscherDgContainer = 0xf002;
- public static final int EscherDg = 0xf008;
- public static final int EscherRegroupItems = 0xf118;
- public static final int EscherColorScheme = 0xf120;
- public static final int EscherSpgrContainer = 0xf003;
- public static final int EscherSpContainer = 0xf004;
- public static final int EscherSpgr = 0xf009;
- public static final int EscherSp = 0xf00a;
- public static final int EscherTextbox = 0xf00c;
- public static final int EscherClientTextbox = 0xf00d;
- public static final int EscherAnchor = 0xf00e;
- public static final int EscherChildAnchor = 0xf00f;
- public static final int EscherClientAnchor = 0xf010;
- public static final int EscherClientData = 0xf011;
- public static final int EscherSolverContainer = 0xf005;
- public static final int EscherConnectorRule = 0xf012;
- public static final int EscherAlignRule = 0xf013;
- public static final int EscherArcRule = 0xf014;
- public static final int EscherClientRule = 0xf015;
- public static final int EscherCalloutRule = 0xf017;
- public static final int EscherSelection = 0xf119;
- public static final int EscherColorMRU = 0xf11a;
- public static final int EscherDeletedPspl = 0xf11d;
- public static final int EscherSplitMenuColors = 0xf11e;
- public static final int EscherOleObject = 0xf11f;
- public static final int EscherUserDefined = 0xf122;
/**
* Returns name of the record by its type
@@ -218,10 +236,10 @@ public final class RecordTypes {
* @param type section of the record header
* @return name of the record
*/
- public static String recordName(int type) {
- String name = typeToName.get(Integer.valueOf(type));
- return (name == null) ? ("Unknown" + type) : name;
- }
+// public static String recordName(int type) {
+// String name = typeToName.get(Integer.valueOf(type));
+// return (name == null) ? ("Unknown" + type) : name;
+// }
/**
* Returns the class handling a record by its type.
@@ -232,38 +250,38 @@ public final class RecordTypes {
* @param type section of the record header
* @return class to handle the record, or null if an unknown (eg Escher) record
*/
- public static Class extends Record> recordHandlingClass(int type) {
- Class extends Record> c = typeToClass.get(Integer.valueOf(type));
- return c;
- }
-
- static {
- typeToName = new HashMap();
- typeToClass = new HashMap>();
- try {
- Field[] f = RecordTypes.class.getFields();
- for (int i = 0; i < f.length; i++){
- Object val = f[i].get(null);
-
- // Escher record, only store ID -> Name
- if (val instanceof Integer) {
- typeToName.put((Integer)val, f[i].getName());
- }
- // PowerPoint record, store ID -> Name and ID -> Class
- if (val instanceof Type) {
- Type t = (Type)val;
- Class extends Record> c = t.handlingClass;
- Integer id = Integer.valueOf(t.typeID);
- if(c == null) { c = UnknownRecordPlaceholder.class; }
-
- typeToName.put(id, f[i].getName());
- typeToClass.put(id, c);
- }
- }
- } catch (IllegalAccessException e){
- throw new RuntimeException("Failed to initialize records types");
- }
- }
+// public static Class extends Record> recordHandlingClass(int type) {
+// Class extends Record> c = typeToClass.get(Integer.valueOf(type));
+// return c;
+// }
+//
+// static {
+// typeToName = new HashMap();
+// typeToClass = new HashMap>();
+// try {
+// Field[] f = RecordTypes.class.getFields();
+// for (int i = 0; i < f.length; i++){
+// Object val = f[i].get(null);
+//
+// // Escher record, only store ID -> Name
+// if (val instanceof Integer) {
+// typeToName.put((Integer)val, f[i].getName());
+// }
+// // PowerPoint record, store ID -> Name and ID -> Class
+// if (val instanceof Type) {
+// Type t = (Type)val;
+// Class extends Record> c = t.handlingClass;
+// Integer id = Integer.valueOf(t.typeID);
+// if(c == null) { c = UnknownRecordPlaceholder.class; }
+//
+// typeToName.put(id, f[i].getName());
+// typeToClass.put(id, c);
+// }
+// }
+// } catch (IllegalAccessException e){
+// throw new RuntimeException("Failed to initialize records types");
+// }
+// }
/**
@@ -271,12 +289,12 @@ public final class RecordTypes {
* Contains both the type, and the handling class (if any), and
* offers methods to get either back out.
*/
- public static class Type {
- public final int typeID;
- public final Class extends Record> handlingClass;
- public Type(int typeID, Class extends Record> handlingClass) {
- this.typeID = typeID;
- this.handlingClass = handlingClass;
- }
- }
+// public static class Type {
+// public final int typeID;
+// public final Class extends Record> handlingClass;
+// public Type(int typeID, Class extends Record> handlingClass) {
+// this.typeID = typeID;
+// this.handlingClass = handlingClass;
+// }
+// }
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java b/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java
index 412beb1fc..e843f1dd7 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/RoundTripHFPlaceholder12.java
@@ -20,6 +20,8 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
+import org.apache.poi.util.LittleEndian;
+
/**
* An atom record that specifies that a shape is a header or footer placeholder shape
*
@@ -40,6 +42,17 @@ public final class RoundTripHFPlaceholder12 extends RecordAtom {
*/
private byte _placeholderId;
+ /**
+ * Create a new instance of RoundTripHFPlaceholder12
+ */
+ public RoundTripHFPlaceholder12(){
+ _header = new byte[8];
+ LittleEndian.putUShort(_header, 0, 0);
+ LittleEndian.putUShort(_header, 2, (int)getRecordType());
+ LittleEndian.putInt(_header, 4, 8);
+ _placeholderId = 0;
+ }
+
/**
* Constructs the comment atom record from its source data.
*
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
index 6d1c4873d..9ee64d628 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/TxMasterStyleAtom.java
@@ -171,7 +171,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
/**
* Updates the rawdata from the modified paragraph/character styles
*
- * @since 3.14-beta1
+ * @since POI 3.14-beta1
*/
public void updateStyles() {
int type = getTextType();
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
index 02608b74a..d20f0efa9 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
@@ -17,10 +17,18 @@
package org.apache.poi.hslf.usermodel;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.ExHyperlink;
+import org.apache.poi.hslf.record.ExObjList;
+import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.InteractiveInfoAtom;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
/**
* Represents a hyperlink in a PowerPoint document
@@ -156,6 +164,7 @@ public final class HSLFHyperlink {
* @param paragraphs List of TextParagraph
to lookup hyperlinks
* @return found hyperlinks
*/
+ @SuppressWarnings("resource")
public static List find(List paragraphs){
List lst = new ArrayList();
if (paragraphs == null || paragraphs.isEmpty()) return lst;
@@ -165,10 +174,10 @@ public final class HSLFHyperlink {
HSLFSlideShow ppt = firstPara.getSheet().getSlideShow();
//document-level container which stores info about all links in a presentation
ExObjList exobj = ppt.getDocumentRecord().getExObjList();
- if (exobj == null) return lst;
-
- Record[] records = firstPara.getRecords();
- find(records, exobj, lst);
+ if (exobj != null) {
+ Record[] records = firstPara.getRecords();
+ find(Arrays.asList(records), exobj, lst);
+ }
return lst;
}
@@ -179,39 +188,38 @@ public final class HSLFHyperlink {
* @param shape Shape
to lookup hyperlink in
* @return found hyperlink or null
*/
+ @SuppressWarnings("resource")
public static HSLFHyperlink find(HSLFShape shape){
- List lst = new ArrayList();
HSLFSlideShow ppt = shape.getSheet().getSlideShow();
//document-level container which stores info about all links in a presentation
ExObjList exobj = ppt.getDocumentRecord().getExObjList();
- if (exobj == null) {
- return null;
+ HSLFEscherClientDataRecord cldata = shape.getClientData(false);
+
+ if (exobj != null && cldata != null) {
+ List lst = new ArrayList();
+ find(cldata.getHSLFChildRecords(), exobj, lst);
+ return lst.isEmpty() ? null : (HSLFHyperlink)lst.get(0);
}
- EscherContainerRecord spContainer = shape.getSpContainer();
- for (Iterator it = spContainer.getChildIterator(); it.hasNext(); ) {
- EscherRecord obj = it.next();
- if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID){
- byte[] data = obj.serialize();
- Record[] records = Record.findChildRecords(data, 8, data.length-8);
- find(records, exobj, lst);
- }
- }
-
- return lst.size() == 1 ? (HSLFHyperlink)lst.get(0) : null;
+ return null;
}
- private static void find(Record[] records, ExObjList exobj, List out){
- if (records == null) return;
- for (int i = 0; i < records.length; i++) {
- //see if we have InteractiveInfo in the textrun's records
- if(!(records[i] instanceof InteractiveInfo)) continue;
-
- InteractiveInfo hldr = (InteractiveInfo)records[i];
+ private static void find(List extends Record> records, ExObjList exobj, List out){
+ ListIterator extends Record> iter = records.listIterator();
+ while (iter.hasNext()) {
+ Record r = iter.next();
+ // see if we have InteractiveInfo in the textrun's records
+ if (!(r instanceof InteractiveInfo)) {
+ continue;
+ }
+
+ InteractiveInfo hldr = (InteractiveInfo)r;
InteractiveInfoAtom info = hldr.getInteractiveInfoAtom();
int id = info.getHyperlinkID();
ExHyperlink linkRecord = exobj.get(id);
- if (linkRecord == null) continue;
+ if (linkRecord == null) {
+ continue;
+ }
HSLFHyperlink link = new HSLFHyperlink();
link.title = linkRecord.getLinkTitle();
@@ -219,8 +227,13 @@ public final class HSLFHyperlink {
link.type = info.getAction();
out.add(link);
- if (i+1 < records.length && records[i+1] instanceof TxInteractiveInfoAtom){
- TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom)records[++i];
+ if (iter.hasNext()) {
+ r = iter.next();
+ if (!(r instanceof TxInteractiveInfoAtom)) {
+ iter.previous();
+ continue;
+ }
+ TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom)r;
link.startIndex = txinfo.getStartIndex();
link.endIndex = txinfo.getEndIndex();
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java
index c0a7aef69..22b1d90ab 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPlaceholder.java
@@ -18,7 +18,7 @@
package org.apache.poi.hslf.usermodel;
import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.ShapeContainer;
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
index 38483d03a..e4ef3b1b7 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
+import java.util.List;
import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherChildAnchorRecord;
@@ -33,7 +34,10 @@ import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
+import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.Shape;
@@ -217,19 +221,32 @@ public abstract class HSLFShape implements Shape {
public static T getEscherChild(EscherContainerRecord owner, int recordId){
return owner.getChildById((short)recordId);
}
+
+ /**
+ * @since POI 3.14-Beta2
+ */
+ public static T getEscherChild(EscherContainerRecord owner, RecordTypes recordId){
+ return getEscherChild(owner, recordId.typeID);
+ }
public T getEscherChild(int recordId){
return _escherContainer.getChildById((short)recordId);
}
+ /**
+ * @since POI 3.14-Beta2
+ */
+ public T getEscherChild(RecordTypes recordId){
+ return getEscherChild(recordId.typeID);
+ }
+
/**
* Returns escher property by id.
*
* @return escher property or null
if not found.
*/
public static T getEscherProperty(AbstractEscherOptRecord opt, int propId){
- if (opt == null) return null;
- return opt.lookup(propId);
+ return (opt == null) ? null : opt.lookup(propId);
}
/**
@@ -443,7 +460,7 @@ public abstract class HSLFShape implements Shape {
}
public AbstractEscherOptRecord getEscherOptRecord() {
- AbstractEscherOptRecord opt = getEscherChild(EscherOptRecord.RECORD_ID);
+ AbstractEscherOptRecord opt = getEscherChild(RecordTypes.EscherOPT);
if (opt == null) {
opt = getEscherChild(RecordTypes.EscherUserDefined);
}
@@ -485,4 +502,48 @@ public abstract class HSLFShape implements Shape {
public boolean isPlaceholder() {
return false;
}
+
+ /**
+ * Find a record in the underlying EscherClientDataRecord
+ *
+ * @param recordType type of the record to search
+ */
+ @SuppressWarnings("unchecked")
+ public T getClientDataRecord(int recordType) {
+
+ List extends Record> records = getClientRecords();
+ if (records != null) for (Record r : records) {
+ if (r.getRecordType() == recordType){
+ return (T)r;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Search for EscherClientDataRecord, if found, convert its contents into an array of HSLF records
+ *
+ * @return an array of HSLF records contained in the shape's EscherClientDataRecord or null
+ */
+ protected List extends Record> getClientRecords() {
+ HSLFEscherClientDataRecord clientData = getClientData(false);
+ return (clientData == null) ? null : clientData.getHSLFChildRecords();
+ }
+
+ /**
+ * Create a new HSLF-specific EscherClientDataRecord
+ *
+ * @param create if true, create the missing record
+ * @return the client record or null if it was missing and create wasn't activated
+ */
+ protected HSLFEscherClientDataRecord getClientData(boolean create) {
+ HSLFEscherClientDataRecord clientData = getEscherChild(HSLFEscherClientDataRecord.RECORD_ID);
+ if (clientData == null && create) {
+ clientData = new HSLFEscherClientDataRecord();
+ clientData.setOptions((short)15);
+ clientData.setRecordId(HSLFEscherClientDataRecord.RECORD_ID);
+ getSpContainer().addChildBefore(clientData, EscherTextboxRecord.RECORD_ID);
+ }
+ return clientData;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
index 737d2927a..197171353 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
@@ -17,12 +17,27 @@
package org.apache.poi.hslf.usermodel;
-import java.util.Iterator;
import java.util.List;
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.model.*;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherClientDataRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherProperty;
+import org.apache.poi.ddf.EscherPropertyFactory;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.EscherTextboxRecord;
+import org.apache.poi.hslf.model.MovieShape;
+import org.apache.poi.hslf.model.OLEShape;
+import org.apache.poi.hslf.record.ExObjRefAtom;
+import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.InteractiveInfoAtom;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.util.POILogFactory;
@@ -50,7 +65,7 @@ public final class HSLFShapeFactory {
public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer parent){
boolean isTable = false;
EscherContainerRecord ecr = (EscherContainerRecord)spContainer.getChild(0);
- EscherRecord opt = HSLFShape.getEscherChild(ecr, (short)RecordTypes.EscherUserDefined);
+ EscherRecord opt = HSLFShape.getEscherChild(ecr, RecordTypes.EscherUserDefined);
if (opt != null) {
EscherPropertyFactory f = new EscherPropertyFactory();
@@ -120,12 +135,10 @@ public final class HSLFShapeFactory {
}
}
- OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
- if (oes != null){
- return new OLEShape(spContainer, parent);
- }
-
- return new HSLFPictureShape(spContainer, parent);
+ ExObjRefAtom oes = getClientDataRecord(spContainer, RecordTypes.ExObjRefAtom.typeID);
+ return (oes != null)
+ ? new OLEShape(spContainer, parent)
+ : new HSLFPictureShape(spContainer, parent);
}
private static HSLFShape createNonPrimitive(EscherContainerRecord spContainer, ShapeContainer parent) {
@@ -141,15 +154,10 @@ public final class HSLFShapeFactory {
@SuppressWarnings("unchecked")
protected static T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
- for (Iterator it = spContainer.getChildIterator(); it.hasNext();) {
- EscherRecord obj = it.next();
- if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
- byte[] data = obj.serialize();
- for (Record r : Record.findChildRecords(data, 8, data.length - 8)) {
- if (r.getRecordType() == recordType) {
- return (T)r;
- }
- }
+ HSLFEscherClientDataRecord cldata = spContainer.getChildById(EscherClientDataRecord.RECORD_ID);
+ if (cldata != null) for (Record r : cldata.getHSLFChildRecords()) {
+ if (r.getRecordType() == recordType) {
+ return (T)r;
}
}
return null;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
index e80070e6c..3fe79aeb1 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
@@ -149,7 +149,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet getShapes() {
PPDrawing ppdrawing = getPPDrawing();
- EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
+ EscherContainerRecord dg = ppdrawing.getDgContainer();
EscherContainerRecord spgr = null;
for (Iterator it = dg.getChildIterator(); it.hasNext();) {
@@ -187,7 +187,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet it = dg.getChildIterator(); it.hasNext();) {
- EscherRecord rec = it.next();
- if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
- spgr = (EscherContainerRecord) rec;
- break;
- }
- }
+ EscherContainerRecord dg = ppdrawing.getDgContainer();
+ EscherContainerRecord spgr = dg.getChildById(EscherContainerRecord.SPGR_CONTAINER);
if(spgr == null) {
return false;
}
@@ -292,7 +284,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet T getClientDataRecord(int recordType) {
-
- Record[] records = getClientRecords();
- if(records != null) for (int i = 0; i < records.length; i++) {
- if(records[i].getRecordType() == recordType){
- return (T)records[i];
- }
- }
- return null;
- }
-
- /**
- * Search for EscherClientDataRecord, if found, convert its contents into an array of HSLF records
- *
- * @return an array of HSLF records contained in the shape's EscherClientDataRecord or null
- */
- protected Record[] getClientRecords() {
- if(_clientData == null){
- EscherRecord r = getEscherChild(EscherClientDataRecord.RECORD_ID);
- //ddf can return EscherContainerRecord with recordId=EscherClientDataRecord.RECORD_ID
- //convert in to EscherClientDataRecord on the fly
- if(r != null && !(r instanceof EscherClientDataRecord)){
- byte[] data = r.serialize();
- r = new EscherClientDataRecord();
- r.fillFields(data, 0, new HSLFEscherRecordFactory());
- }
- _clientData = (EscherClientDataRecord)r;
- }
- if(_clientData != null && _clientRecords == null){
- byte[] data = _clientData.getRemainingData();
- _clientRecords = Record.findChildRecords(data, 0, data.length);
- }
- return _clientRecords;
- }
-
- protected void updateClientData() {
- if(_clientData != null && _clientRecords != null){
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try {
- for (int i = 0; i < _clientRecords.length; i++) {
- _clientRecords[i].writeOut(out);
- }
- } catch(Exception e){
- throw new HSLFException(e);
- }
- _clientData.setRemainingData(out.toByteArray());
- }
- }
-
public void setHyperlink(HSLFHyperlink link){
if(link.getId() == -1){
throw new HSLFException("You must call SlideShow.addHyperlink(Hyperlink link) first");
}
- EscherClientDataRecord cldata = new EscherClientDataRecord();
- cldata.setOptions((short)0xF);
- getSpContainer().addChildRecord(cldata); // TODO - junit to prove getChildRecords().add is wrong
-
InteractiveInfo info = new InteractiveInfo();
InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
@@ -356,14 +316,8 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape clRecords = getClientRecords();
+ if (clRecords == null) {
+ return null;
+ }
+ for (Record r : clRecords) {
+ if (r instanceof OEPlaceholderAtom) {
+ OEPlaceholderAtom oep = (OEPlaceholderAtom)r;
+ return Placeholder.lookupNative(oep.getPlaceholderId());
+ } else if (r instanceof RoundTripHFPlaceholder12) {
+ RoundTripHFPlaceholder12 rtp = (RoundTripHFPlaceholder12)r;
+ return Placeholder.lookupNative(rtp.getPlaceholderId());
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void setPlaceholder(Placeholder placeholder) {
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
- flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
+ if (placeholder == null) {
+ flags ^= EscherSpRecord.FLAG_HAVEMASTER;
+ } else {
+ flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
+ }
spRecord.setFlags(flags);
- EscherClientDataRecord cldata = _escherContainer.getChildById(EscherClientDataRecord.RECORD_ID);
- if (cldata == null) {
- cldata = new EscherClientDataRecord();
- // append placeholder container before EscherTextboxRecord
- _escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
- }
- cldata.setOptions((short)15);
-
- AbstractEscherOptRecord opt = getEscherOptRecord();
-
// Placeholders can't be grouped
- setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
+ setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
+
+ HSLFEscherClientDataRecord clientData = getClientData(false);
+ if (placeholder == null) {
+ if (clientData != null) {
+ clientData.removeChild(OEPlaceholderAtom.class);
+ clientData.removeChild(RoundTripHFPlaceholder12.class);
+ // remove client data if the placeholder was the only child to be carried
+ if (clientData.getChildRecords().isEmpty()) {
+ getSpContainer().removeChildRecord(clientData);
+ }
+ }
+ return;
+ }
+
+ if (clientData == null) {
+ clientData = getClientData(true);
+ }
// OEPlaceholderAtom tells powerpoint that this shape is a placeholder
- OEPlaceholderAtom oep = new OEPlaceholderAtom();
+ OEPlaceholderAtom oep = null;
+ RoundTripHFPlaceholder12 rtp = null;
+ for (Record r : clientData.getHSLFChildRecords()) {
+ if (r instanceof OEPlaceholderAtom) {
+ oep = (OEPlaceholderAtom)r;
+ break;
+ }
+ if (r instanceof RoundTripHFPlaceholder12) {
+ rtp = (RoundTripHFPlaceholder12)r;
+ break;
+ }
+ }
/**
- * Extarct from MSDN:
+ * Extract from MSDN:
*
* There is a special case when the placeholder does not have a position in the layout.
* This occurs when the user has moved the placeholder from its original position.
* In this case the placeholder ID is -1.
*/
- oep.setPlacementId(-1);
-
- boolean isMaster = (getSheet() instanceof HSLFSlideMaster);
- boolean isNotes = (getSheet() instanceof HSLFNotes);
byte phId;
+ HSLFSheet sheet = getSheet();
+ // TODO: implement/switch NotesMaster
+ if (sheet instanceof HSLFSlideMaster) {
+ phId = (byte)placeholder.nativeSlideMasterId;
+ } else if (sheet instanceof HSLFNotes) {
+ phId = (byte)placeholder.nativeNotesId;
+ } else {
+ phId = (byte)placeholder.nativeSlideId;
+ }
+
+ if (phId == -2) {
+ throw new HSLFException("Placeholder "+placeholder.name()+" not supported for this sheet type ("+sheet.getClass()+")");
+ }
+
switch (placeholder) {
- case TITLE:
- phId = (isMaster) ? OEPlaceholderAtom.MasterTitle : OEPlaceholderAtom.Title;
- break;
- case BODY:
- phId = (isMaster) ? OEPlaceholderAtom.MasterBody :
- ((isNotes) ? OEPlaceholderAtom.NotesBody : OEPlaceholderAtom.Body);
- break;
- case CENTERED_TITLE:
- phId = (isMaster) ? OEPlaceholderAtom.MasterCenteredTitle : OEPlaceholderAtom.CenteredTitle;
- break;
- case SUBTITLE:
- phId = (isMaster) ? OEPlaceholderAtom.MasterSubTitle : OEPlaceholderAtom.Subtitle;
- break;
- case DATETIME:
- phId = OEPlaceholderAtom.MasterDate;
- break;
- case SLIDE_NUMBER:
- phId = OEPlaceholderAtom.MasterSlideNumber;
- break;
- case FOOTER:
- phId = OEPlaceholderAtom.MasterFooter;
- break;
case HEADER:
- phId = OEPlaceholderAtom.MasterHeader;
- break;
- case DGM:
- case CHART:
- phId = OEPlaceholderAtom.Graph;
- break;
- case TABLE:
- phId = OEPlaceholderAtom.Table;
- break;
- case PICTURE:
- case CLIP_ART:
- phId = OEPlaceholderAtom.ClipArt;
- break;
- case MEDIA:
- phId = OEPlaceholderAtom.MediaClip;
- break;
- case SLIDE_IMAGE:
- phId = (isMaster) ? OEPlaceholderAtom.MasterNotesSlideImage : OEPlaceholderAtom.NotesSlideImage;
+ case FOOTER:
+ if (rtp == null) {
+ rtp = new RoundTripHFPlaceholder12();
+ rtp.setPlaceholderId(phId);
+ clientData.addChild(rtp);
+ }
+ if (oep != null) {
+ clientData.removeChild(OEPlaceholderAtom.class);
+ }
break;
default:
- case CONTENT:
- phId = OEPlaceholderAtom.Object;
+ if (rtp != null) {
+ clientData.removeChild(RoundTripHFPlaceholder12.class);
+ }
+ if (oep == null) {
+ oep = new OEPlaceholderAtom();
+ oep.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE);
+ // TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id
+ oep.setPlacementId(-1);
+ oep.setPlaceholderId(phId);
+ clientData.addChild(oep);
+ }
break;
}
- oep.setPlaceholderId(phId);
-
- //convert hslf into ddf record
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try {
- oep.writeOut(out);
- } catch(Exception e){
- throw new HSLFException(e);
- }
- cldata.setRemainingData(out.toByteArray());
}
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 1ebd32368..73223646c 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java
@@ -42,8 +42,8 @@ import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Notes;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Slide;
/**
@@ -163,7 +163,7 @@ public final class HSLFSlide extends HSLFSheet implements Slide interestingRecords =
- new HashMap();
+ Map interestingRecords =
+ new HashMap();
try {
_hslfSlideShow.updateAndWriteDependantRecords(null,interestingRecords);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
index d27b6f050..750c74ebf 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
@@ -474,7 +474,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
* May be null, if not needed.
* @throws IOException
*/
- public void updateAndWriteDependantRecords(OutputStream os, Map interestingRecords)
+ public void updateAndWriteDependantRecords(OutputStream os, Map interestingRecords)
throws IOException {
// For position dependent records, hold where they were and now are
// As we go along, update, and hand over, to any Position Dependent
@@ -502,7 +502,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
// Grab interesting records as they come past
// this will only save the very last record of each type
- RecordTypes.Type saveme = null;
+ RecordTypes saveme = null;
int recordType = (int)record.getRecordType();
if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
saveme = RecordTypes.PersistPtrIncrementalBlock;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
index b82bed34a..664e935d4 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
@@ -95,14 +95,14 @@ implements HSLFShapeContainer, TableShape {
EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);
AbstractEscherOptRecord opt = new EscherOptRecord();
- opt.setRecordId((short)RecordTypes.EscherUserDefined);
+ opt.setRecordId(RecordTypes.EscherUserDefined.typeID);
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__TABLEPROPERTIES, 1));
EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES), false, null);
p.setSizeOfElements(0x0004);
p.setNumberOfElementsInArray(numRows);
p.setNumberOfElementsInMemory(numRows);
opt.addEscherProperty(p);
- spCont.addChildBefore(opt, RecordTypes.EscherClientAnchor);
+ spCont.addChildBefore(opt, RecordTypes.EscherClientAnchor.typeID);
}
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
index da6e16454..8460a5b97 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
@@ -157,7 +157,7 @@ public final class HSLFTextParagraph implements TextParagraph {
}
/**
- * Return OEPlaceholderAtom
, the atom that describes a placeholder.
+ * Return {@link OEPlaceholderAtom}, the atom that describes a placeholder.
*
- * @return OEPlaceholderAtom
or null
if not found
+ * @return {@link OEPlaceholderAtom} or {@code null} if not found
*/
public OEPlaceholderAtom getPlaceholderAtom(){
return getClientDataRecord(OEPlaceholderAtom.typeID);
}
+ /**
+ * Return {@link RoundTripHFPlaceholder12}, the atom that describes a header/footer placeholder.
+ * Compare the {@link RoundTripHFPlaceholder12#getPlaceholderId()} with
+ * {@link OEPlaceholderAtom#MasterHeader} or {@link OEPlaceholderAtom#MasterFooter}, to find out
+ * what kind of placeholder this is.
+ *
+ * @return {@link RoundTripHFPlaceholder12} or {@code null} if not found
+ *
+ * @since POI 3.14-Beta2
+ */
+ public RoundTripHFPlaceholder12 getHFPlaceholderAtom() {
+ // special case for files saved in Office 2007
+ return getClientDataRecord(RoundTripHFPlaceholder12.typeID);
+ }
+
/**
*
* Assigns a hyperlink to this text shape
@@ -644,7 +660,7 @@ implements TextShape {
if (oep != null) return true;
//special case for files saved in Office 2007
- RoundTripHFPlaceholder12 hldr = getClientDataRecord(RoundTripHFPlaceholder12.typeID);
+ RoundTripHFPlaceholder12 hldr = getHFPlaceholderAtom();
if (hldr != null) return true;
return false;
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java b/src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java
index a742528e2..d5a2b60a0 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java
@@ -17,18 +17,22 @@
package org.apache.poi.hslf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-
-import junit.framework.TestCase;
+import java.io.IOException;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.junit.Before;
+import org.junit.Test;
/**
* Tests that HSLFSlideShow writes the powerpoint bit of data back out
@@ -36,7 +40,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
*
* @author Nick Burch (nick at torchbox dot com)
*/
-public final class TestReWrite extends TestCase {
+public final class TestReWrite {
// HSLFSlideShow primed on the test data
private HSLFSlideShowImpl hssA;
private HSLFSlideShowImpl hssB;
@@ -46,7 +50,8 @@ public final class TestReWrite extends TestCase {
private POIFSFileSystem pfsB;
private POIFSFileSystem pfsC;
- public void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
@@ -60,10 +65,12 @@ public final class TestReWrite extends TestCase {
hssC = new HSLFSlideShowImpl(pfsC);
}
+ @Test
public void testWritesOutTheSame() throws Exception {
assertWritesOutTheSame(hssA, pfsA);
assertWritesOutTheSame(hssB, pfsB);
}
+
public void assertWritesOutTheSame(HSLFSlideShowImpl hss, POIFSFileSystem pfs) throws Exception {
// Write out to a byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -85,13 +92,15 @@ public final class TestReWrite extends TestCase {
byte[] _nData = new byte[nProps.getSize()];
pfs.createDocumentInputStream("PowerPoint Document").read(_oData);
npfs.createDocumentInputStream("PowerPoint Document").read(_nData);
- for(int i=0; i<_oData.length; i++) {
+ for(int i=0; i<_oData.length; i++) {
//System.out.println(i + "\t" + Integer.toHexString(i));
assertEquals(_oData[i], _nData[i]);
}
+ npfs.close();
}
- public void testWithMacroStreams() throws Exception {
+ @Test
+ public void testWithMacroStreams() throws IOException {
// Check that they're apparently the same
assertSlideShowWritesOutTheSame(hssC, pfsC);
@@ -101,28 +110,25 @@ public final class TestReWrite extends TestCase {
// Write out normally, will loose the macro stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
hssC.write(baos);
- POIFSFileSystem pfsNew = new POIFSFileSystem(
- new ByteArrayInputStream(baos.toByteArray()) );
-
- try {
- pfsNew.getRoot().getEntry("Macros");
- fail();
- } catch(FileNotFoundException e) {
- // Good, as expected
- }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ POIFSFileSystem pfsNew = new POIFSFileSystem(bais);
+ assertFalse(pfsNew.getRoot().hasEntry("Macros"));
+ pfsNew.close();
// But if we write out with nodes preserved, will be there
- baos = new ByteArrayOutputStream();
+ baos.reset();
hssC.write(baos, true);
- pfsNew = new POIFSFileSystem(
- new ByteArrayInputStream(baos.toByteArray()) );
- assertNotNull( pfsNew.getRoot().getEntry("Macros") );
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ pfsNew = new POIFSFileSystem(bais);
+ assertTrue( pfsNew.getRoot().hasEntry("Macros") );
+ pfsNew.close();
}
/**
* Ensure that simply opening a slideshow (usermodel) view of it
* doesn't change things
*/
+ @Test
public void testSlideShowWritesOutTheSame() throws Exception {
assertSlideShowWritesOutTheSame(hssA, pfsA);
@@ -130,9 +136,11 @@ public final class TestReWrite extends TestCase {
// We need to identify and fix that first
//assertSlideShowWritesOutTheSame(hssB, pfsB);
}
- public void assertSlideShowWritesOutTheSame(HSLFSlideShowImpl hss, POIFSFileSystem pfs) throws Exception {
+
+ public void assertSlideShowWritesOutTheSame(HSLFSlideShowImpl hss, POIFSFileSystem pfs) throws IOException {
// Create a slideshow covering it
- HSLFSlideShow ss = new HSLFSlideShow(hss);
+ @SuppressWarnings("resource")
+ HSLFSlideShow ss = new HSLFSlideShow(hss);
ss.getSlides();
ss.getNotes();
@@ -161,17 +169,23 @@ public final class TestReWrite extends TestCase {
System.out.println(i + "\t" + Integer.toHexString(i));
assertEquals(_oData[i], _nData[i]);
}
+ npfs.close();
}
- public void test48593() throws Exception {
- HSLFSlideShow slideShow = new HSLFSlideShow();
- slideShow.createSlide();
- slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
- slideShow.createSlide();
- slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
- slideShow.createSlide();
- slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
- slideShow.createSlide();
- slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
+ @Test
+ public void test48593() throws IOException {
+ HSLFSlideShow ppt1 = new HSLFSlideShow();
+ ppt1.createSlide();
+ HSLFSlideShow ppt2 = HSLFTestDataSamples.writeOutAndReadBack(ppt1);
+ ppt2.createSlide();
+ HSLFSlideShow ppt3 = HSLFTestDataSamples.writeOutAndReadBack(ppt2);
+ ppt3.createSlide();
+ HSLFSlideShow ppt4 = HSLFTestDataSamples.writeOutAndReadBack(ppt3);
+ ppt4.createSlide();
+ HSLFTestDataSamples.writeOutAndReadBack(ppt4).close();
+ ppt4.close();
+ ppt3.close();
+ ppt2.close();
+ ppt1.close();
}
}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordTypes.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordTypes.java
index 45522dfd8..814259ca1 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordTypes.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestRecordTypes.java
@@ -18,40 +18,44 @@
package org.apache.poi.hslf.record;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
/**
* Tests that RecordTypes returns the right records and classes when asked
- *
- * @author Nick Burch (nick at torchbox dot com)
*/
-public final class TestRecordTypes extends TestCase {
+public final class TestRecordTypes {
+ @Test
public void testPPTNameLookups() {
- assertEquals("MainMaster", RecordTypes.recordName(1016));
- assertEquals("TextBytesAtom", RecordTypes.recordName(4008));
- assertEquals("VBAInfo", RecordTypes.recordName(1023));
+ assertEquals("MainMaster", RecordTypes.MainMaster.name());
+ assertEquals("TextBytesAtom", RecordTypes.TextBytesAtom.name());
+ assertEquals("VBAInfo", RecordTypes.VBAInfo.name());
}
+ @Test
public void testEscherNameLookups() {
- assertEquals("EscherDggContainer", RecordTypes.recordName(0xf000));
- assertEquals("EscherClientTextbox", RecordTypes.recordName(0xf00d));
- assertEquals("EscherSelection", RecordTypes.recordName(0xf119));
+ assertEquals("EscherDggContainer", RecordTypes.EscherDggContainer.name());
+ assertEquals("EscherClientTextbox", RecordTypes.EscherClientTextbox.name());
+ assertEquals("EscherSelection", RecordTypes.EscherSelection.name());
}
+ @Test
public void testPPTClassLookups() {
- assertEquals(Slide.class, RecordTypes.recordHandlingClass(1006));
- assertEquals(TextCharsAtom.class, RecordTypes.recordHandlingClass(4000));
- assertEquals(TextBytesAtom.class, RecordTypes.recordHandlingClass(4008));
- assertEquals(SlideListWithText.class, RecordTypes.recordHandlingClass(4080));
+ assertEquals(Slide.class, RecordTypes.Slide.handlingClass);
+ assertEquals(TextCharsAtom.class, RecordTypes.TextCharsAtom.handlingClass);
+ assertEquals(TextBytesAtom.class, RecordTypes.TextBytesAtom.handlingClass);
+ assertEquals(SlideListWithText.class, RecordTypes.SlideListWithText.handlingClass);
// If this record is ever implemented, change to one that isn't!
// This is checking the "unhandled default" stuff works
- assertEquals(UnknownRecordPlaceholder.class, RecordTypes.recordHandlingClass(2019));
+ assertEquals(UnknownRecordPlaceholder.class, RecordTypes.forTypeID(-10).handlingClass);
}
- public void testEscherClassLookups() {
+ @Test
+ public void testEscherClassLookups() {
// Should all come back with null, as DDF handles them
- assertEquals(null, RecordTypes.recordHandlingClass(0xf000));
- assertEquals(null, RecordTypes.recordHandlingClass(0xf001));
+ assertEquals(null, RecordTypes.EscherDggContainer.handlingClass);
+ assertEquals(null, RecordTypes.EscherBStoreContainer.handlingClass);
}
}
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 68684bf8d..b57d9e4f2 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
@@ -42,7 +43,9 @@ import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
import org.apache.poi.hslf.extractor.PowerPointExtractor;
import org.apache.poi.hslf.model.HeadersFooters;
import org.apache.poi.hslf.record.Document;
+import org.apache.poi.hslf.record.OEPlaceholderAtom;
import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.hslf.record.TextHeaderAtom;
@@ -50,6 +53,7 @@ import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
@@ -777,6 +781,31 @@ public final class TestBugs {
ex.close();
}
+ @Test
+ public void bug58159() throws IOException {
+ File sample = HSLFTestDataSamples.getSampleFile("bug58159_headers-and-footers.ppt");
+ HSLFSlideShow ppt = (HSLFSlideShow)SlideShowFactory.create(sample);
+ HeadersFooters hf = ppt.getSlideHeadersFooters();
+ assertNull(hf.getHeaderText());
+ assertEquals("Slide footer", hf.getFooterText());
+ hf = ppt.getNotesHeadersFooters();
+ assertEquals("Notes header", hf.getHeaderText());
+ assertEquals("Notes footer", hf.getFooterText());
+ HSLFSlide sl = ppt.getSlides().get(0);
+ hf = sl.getHeadersFooters();
+ assertNull(hf.getHeaderText());
+ assertEquals("Slide footer", hf.getFooterText());
+ for (HSLFShape shape : sl.getShapes()) {
+ if (shape instanceof HSLFTextShape) {
+ HSLFTextShape ts = (HSLFTextShape)shape;
+ Placeholder ph = ts.getPlaceholder();
+ if (Placeholder.FOOTER == ph) {
+ assertEquals("Slide footer", ts.getText());
+ }
+ }
+ }
+ ppt.close();
+ }
private static HSLFSlideShow open(String fileName) throws IOException {
File sample = HSLFTestDataSamples.getSampleFile(fileName);
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList.java
index e54da298f..b21f21657 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestNumberedList.java
@@ -42,12 +42,11 @@ public final class TestNumberedList {
@Test
public void testNumberedList() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("numbers.ppt"));
- assertTrue("No Exceptions while reading file", true);
-
final List slides = ppt.getSlides();
assertEquals(2, slides.size());
checkSlide0(slides.get(0));
checkSlide1(slides.get(1));
+ ppt.close();
}
private void checkSlide0(final HSLFSlide s) {