diff options
47 files changed, 1204 insertions, 763 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java b/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java index 3bcedbe850..a39cf7d68e 100644 --- a/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java +++ b/src/java/org/apache/poi/sl/draw/DrawMasterSheet.java @@ -17,7 +17,13 @@ package org.apache.poi.sl.draw;
-import org.apache.poi.sl.usermodel.*;
+import java.awt.Graphics2D;
+
+import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.sl.usermodel.Placeholder;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.SimpleShape;
+import org.apache.poi.sl.usermodel.Slide;
public class DrawMasterSheet extends DrawSheet {
@@ -33,12 +39,15 @@ public class DrawMasterSheet extends DrawSheet { * for instance, slide masters and layouts don't display placeholders
*/
@Override
- protected boolean canDraw(Shape<?,?> shape) {
+ protected boolean canDraw(Graphics2D graphics, Shape<?,?> shape) {
if (shape instanceof SimpleShape) {
+ // in XSLF, slidenumber and date shapes aren't marked as placeholders opposed to HSLF
Placeholder ph = ((SimpleShape<?,?>)shape).getPlaceholder();
- return ph == null;
- } else {
- return true;
+ if (ph != null) {
+ Slide<?,?> slide = (Slide<?,?>)graphics.getRenderingHint(Drawable.CURRENT_SLIDE);
+ return slide.getDisplayPlaceholder(ph);
+ }
}
+ return true;
}
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawShape.java b/src/java/org/apache/poi/sl/draw/DrawShape.java index b7b0915c18..bb1f490bf6 100644 --- a/src/java/org/apache/poi/sl/draw/DrawShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawShape.java @@ -39,17 +39,33 @@ public class DrawShape implements Drawable { }
/**
+ * Sometimes it's necessary to distinguish between XSLF/HSLF for the rendering.
+ * Use this method on the shape to determine, if we work on the BIFF implementation
+ *
+ * @param shape the shape to render
+ * @return {@code true} if HSLF implementation is used
+ */
+ protected static boolean isHSLF(Shape<?,?> shape) {
+ return shape.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");
+ }
+
+ /**
* Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
*
* @param graphics the graphics whos transform matrix will be modified
*/
+ @Override
public void applyTransform(Graphics2D graphics) {
- if (!(shape instanceof PlaceableShape)) return;
+ if (!(shape instanceof PlaceableShape)) {
+ return;
+ }
PlaceableShape<?,?> ps = (PlaceableShape<?,?>)shape;
- final boolean isHSLF = ps.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");
+ final boolean isHSLF = isHSLF(shape);
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
- if (tx == null) tx = new AffineTransform();
+ if (tx == null) {
+ tx = new AffineTransform();
+ }
final Rectangle2D anchor = tx.createTransformedShape(ps.getAnchor()).getBounds2D();
char cmds[] = isHSLF ? new char[]{ 'h','v','r' } : new char[]{ 'r','h','v' };
@@ -81,7 +97,9 @@ public class DrawShape implements Drawable { // normalize rotation
rotation %= 360.;
- if (rotation < 0) rotation += 360.;
+ if (rotation < 0) {
+ rotation += 360.;
+ }
int quadrant = (((int)rotation+45)/90)%4;
double scaleX = 1.0, scaleY = 1.0;
@@ -148,9 +166,11 @@ public class DrawShape implements Drawable { return (dim2 == 0.) ? 1 : dim1/dim2;
}
+ @Override
public void draw(Graphics2D graphics) {
}
+ @Override
public void drawContent(Graphics2D graphics) {
}
@@ -176,7 +196,10 @@ public class DrawShape implements Drawable { protected static BasicStroke getStroke(StrokeStyle strokeStyle) {
float lineWidth = (float) strokeStyle.getLineWidth();
- if (lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt
+ if (lineWidth == 0.0f) {
+ // Both PowerPoint and OOo draw zero-length lines as 0.25pt
+ lineWidth = 0.25f;
+ }
LineDash lineDash = strokeStyle.getLineDash();
if (lineDash == null) {
@@ -194,7 +217,9 @@ public class DrawShape implements Drawable { }
LineCap lineCapE = strokeStyle.getLineCap();
- if (lineCapE == null) lineCapE = LineCap.FLAT;
+ if (lineCapE == null) {
+ lineCapE = LineCap.FLAT;
+ }
int lineCap;
switch (lineCapE) {
case ROUND:
diff --git a/src/java/org/apache/poi/sl/draw/DrawSheet.java b/src/java/org/apache/poi/sl/draw/DrawSheet.java index dbe82ea6c8..5c8d76abeb 100644 --- a/src/java/org/apache/poi/sl/draw/DrawSheet.java +++ b/src/java/org/apache/poi/sl/draw/DrawSheet.java @@ -17,13 +17,14 @@ package org.apache.poi.sl.draw;
-import java.awt.Dimension;
import java.awt.Color;
+import java.awt.Dimension;
import java.awt.Graphics2D;
-
import java.awt.geom.AffineTransform;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.Sheet;
public class DrawSheet implements Drawable {
@@ -34,6 +35,7 @@ public class DrawSheet implements Drawable { this.sheet = sheet;
}
+ @Override
public void draw(Graphics2D graphics) {
Dimension dim = sheet.getSlideShow().getPageSize();
Color whiteTrans = new Color(1f,1f,1f,0f);
@@ -51,7 +53,9 @@ public class DrawSheet implements Drawable { graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, new AffineTransform());
for (Shape<?,?> shape : sheet.getShapes()) {
- if(!canDraw(shape)) continue;
+ if(!canDraw(graphics, shape)) {
+ continue;
+ }
// remember the initial transform and restore it after we are done with drawing
AffineTransform at = graphics.getTransform();
@@ -73,9 +77,11 @@ public class DrawSheet implements Drawable { }
}
+ @Override
public void applyTransform(Graphics2D context) {
}
+ @Override
public void drawContent(Graphics2D context) {
}
@@ -85,7 +91,7 @@ public class DrawSheet implements Drawable { * Subclasses can override it and skip certain shapes from drawings,
* for instance, slide masters and layouts don't display placeholders
*/
- protected boolean canDraw(Shape<?,?> shape){
+ protected boolean canDraw(Graphics2D graphics, Shape<?,?> shape){
return true;
}
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawSlide.java b/src/java/org/apache/poi/sl/draw/DrawSlide.java index ae4baa27fb..2320e907a6 100644 --- a/src/java/org/apache/poi/sl/draw/DrawSlide.java +++ b/src/java/org/apache/poi/sl/draw/DrawSlide.java @@ -29,6 +29,8 @@ public class DrawSlide extends DrawSheet { }
public void draw(Graphics2D graphics) {
+ graphics.setRenderingHint(Drawable.CURRENT_SLIDE, this.sheet);
+
Background<?,?> bg = sheet.getBackground();
if(bg != null) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
@@ -37,5 +39,6 @@ public class DrawSlide extends DrawSheet { }
super.draw(graphics);
+ graphics.setRenderingHint(Drawable.CURRENT_SLIDE, null);
}
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java index b1fbd9b067..f2b24b0ff2 100644 --- a/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java +++ b/src/java/org/apache/poi/sl/draw/DrawTextParagraph.java @@ -41,10 +41,12 @@ import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.Sheet;
+import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.TextRun;
+import org.apache.poi.sl.usermodel.TextRun.FieldType;
import org.apache.poi.sl.usermodel.TextRun.TextCap;
import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.TextShape.TextDirection;
@@ -82,6 +84,7 @@ public class DrawTextParagraph implements Drawable { /**
* Resolves instances being deserialized to the predefined constants.
*/
+ @Override
protected Object readResolve() throws InvalidObjectException {
if (HYPERLINK_HREF.getName().equals(getName())) {
return HYPERLINK_HREF;
@@ -116,8 +119,11 @@ public class DrawTextParagraph implements Drawable { autoNbrIdx = index;
}
+ @Override
public void draw(Graphics2D graphics){
- if (lines.isEmpty()) return;
+ if (lines.isEmpty()) {
+ return;
+ }
double penY = y;
@@ -144,7 +150,9 @@ public class DrawTextParagraph implements Drawable { //The vertical line spacing
Double spacing = paragraph.getLineSpacing();
- if (spacing == null) spacing = 100d;
+ if (spacing == null) {
+ spacing = 100d;
+ }
for(DrawTextFragment line : lines){
double penX;
@@ -176,7 +184,9 @@ public class DrawTextParagraph implements Drawable { double rightInset = insets.right;
TextAlign ta = paragraph.getTextAlign();
- if (ta == null) ta = TextAlign.LEFT;
+ if (ta == null) {
+ ta = TextAlign.LEFT;
+ }
switch (ta) {
case CENTER:
penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;
@@ -217,9 +227,11 @@ public class DrawTextParagraph implements Drawable { return (lines.isEmpty() || rawText.trim().isEmpty());
}
+ @Override
public void applyTransform(Graphics2D graphics) {
}
+ @Override
public void drawContent(Graphics2D graphics) {
}
@@ -243,10 +255,14 @@ public class DrawTextParagraph implements Drawable { double wrappingWidth = getWrappingWidth(lines.size() == 0, graphics) + 1; // add a pixel to compensate rounding errors
// shape width can be smaller that the sum of insets (this was proved by a test file)
- if(wrappingWidth < 0) wrappingWidth = 1;
+ if(wrappingWidth < 0) {
+ wrappingWidth = 1;
+ }
int nextBreak = text.indexOf("\n", startIndex + 1);
- if (nextBreak == -1) nextBreak = it.getEndIndex();
+ if (nextBreak == -1) {
+ nextBreak = it.getEndIndex();
+ }
TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);
if (layout == null) {
@@ -279,7 +295,9 @@ public class DrawTextParagraph implements Drawable { maxLineHeight = Math.max(maxLineHeight, line.getHeight());
- if(endIndex == it.getEndIndex()) break;
+ if(endIndex == it.getEndIndex()) {
+ break;
+ }
}
rawText = text.toString();
@@ -287,7 +305,9 @@ public class DrawTextParagraph implements Drawable { protected DrawTextFragment getBullet(Graphics2D graphics, AttributedCharacterIterator firstLineAttr) {
BulletStyle bulletStyle = paragraph.getBulletStyle();
- if (bulletStyle == null) return null;
+ if (bulletStyle == null) {
+ return null;
+ }
String buCharacter;
AutoNumberingScheme ans = bulletStyle.getAutoNumberingScheme();
@@ -296,10 +316,14 @@ public class DrawTextParagraph implements Drawable { } else {
buCharacter = bulletStyle.getBulletCharacter();
}
- if (buCharacter == null) return null;
+ if (buCharacter == null) {
+ return null;
+ }
String buFont = bulletStyle.getBulletFont();
- if (buFont == null) buFont = paragraph.getDefaultFontFamily();
+ if (buFont == null) {
+ buFont = paragraph.getDefaultFontFamily();
+ }
assert(buFont != null);
PlaceableShape<?,?> ps = getParagraphShape();
@@ -313,9 +337,14 @@ public class DrawTextParagraph implements Drawable { float fontSize = (Float)firstLineAttr.getAttribute(TextAttribute.SIZE);
Double buSz = bulletStyle.getBulletFontSize();
- if (buSz == null) buSz = 100d;
- if (buSz > 0) fontSize *= buSz* 0.01;
- else fontSize = (float)-buSz;
+ if (buSz == null) {
+ buSz = 100d;
+ }
+ if (buSz > 0) {
+ fontSize *= buSz* 0.01;
+ } else {
+ fontSize = (float)-buSz;
+ }
AttributedString str = new AttributedString(mapFontCharset(buCharacter,buFont));
@@ -328,7 +357,11 @@ public class DrawTextParagraph implements Drawable { return fact.getTextFragment(layout, str);
}
- protected String getRenderableText(TextRun tr) {
+ protected String getRenderableText(Graphics2D graphics, TextRun tr) {
+ if (tr.getFieldType() == FieldType.SLIDE_NUMBER) {
+ Slide<?,?> slide = (Slide<?,?>)graphics.getRenderingHint(Drawable.CURRENT_SLIDE);
+ return (slide == null) ? "" : Integer.toString(slide.getSlideNumber());
+ }
StringBuilder buf = new StringBuilder();
TextCap cap = tr.getTextCap();
String tabs = null;
@@ -364,18 +397,24 @@ public class DrawTextParagraph implements Drawable { private String tab2space(TextRun tr) {
AttributedString string = new AttributedString(" ");
String fontFamily = tr.getFontFamily();
- if (fontFamily == null) fontFamily = "Lucida Sans";
+ if (fontFamily == null) {
+ fontFamily = "Lucida Sans";
+ }
string.addAttribute(TextAttribute.FAMILY, fontFamily);
Double fs = tr.getFontSize();
- if (fs == null) fs = 12d;
+ if (fs == null) {
+ fs = 12d;
+ }
string.addAttribute(TextAttribute.SIZE, fs.floatValue());
TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true));
double wspace = l.getAdvance();
Double tabSz = paragraph.getDefaultTabSize();
- if (tabSz == null) tabSz = wspace*4;
+ if (tabSz == null) {
+ tabSz = wspace*4;
+ }
int numSpaces = (int)Math.ceil(tabSz / wspace);
StringBuilder buf = new StringBuilder();
@@ -449,10 +488,13 @@ public class DrawTextParagraph implements Drawable { }
if (firstLine && !isHSLF()) {
if (bullet != null){
- if (indent > 0) width -= indent;
+ if (indent > 0) {
+ width -= indent;
+ }
} else {
- if (indent > 0) width -= indent; // first line indentation
- else if (indent < 0) { // hanging indentation: the first line start at the left margin
+ if (indent > 0) {
+ width -= indent; // first line indentation
+ } else if (indent < 0) { // hanging indentation: the first line start at the left margin
width += leftMargin;
}
}
@@ -480,25 +522,36 @@ public class DrawTextParagraph implements Drawable { @SuppressWarnings("rawtypes")
private PlaceableShape<?,?> getParagraphShape() {
return new PlaceableShape(){
+ @Override
public ShapeContainer<?,?> getParent() { return null; }
+ @Override
public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); }
+ @Override
public void setAnchor(Rectangle2D anchor) {}
+ @Override
public double getRotation() { return 0; }
+ @Override
public void setRotation(double theta) {}
+ @Override
public void setFlipHorizontal(boolean flip) {}
+ @Override
public void setFlipVertical(boolean flip) {}
+ @Override
public boolean getFlipHorizontal() { return false; }
+ @Override
public boolean getFlipVertical() { return false; }
+ @Override
public Sheet<?,?> getSheet() { return paragraph.getParentShape().getSheet(); }
};
}
protected AttributedString getAttributedString(Graphics2D graphics, StringBuilder text){
List<AttributedStringData> attList = new ArrayList<AttributedStringData>();
- if (text == null) text = new StringBuilder();
+ if (text == null) {
+ text = new StringBuilder();
+ }
PlaceableShape<?,?> ps = getParagraphShape();
-
DrawFontManager fontHandler = (DrawFontManager)graphics.getRenderingHint(Drawable.FONT_HANDLER);
@SuppressWarnings("unchecked")
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
@@ -506,9 +559,11 @@ public class DrawTextParagraph implements Drawable { Map<String,String> fallbackMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_FALLBACK);
for (TextRun run : paragraph){
- String runText = getRenderableText(run);
+ String runText = getRenderableText(graphics, run);
// skip empty runs
- if (runText.isEmpty()) continue;
+ if (runText.isEmpty()) {
+ continue;
+ }
// user can pass an custom object to convert fonts
String mappedFont = run.getFontFamily();
@@ -633,8 +688,11 @@ public class DrawTextParagraph implements Drawable { return string;
}
+ /**
+ * @return {@code true} if the HSLF implementation is used
+ */
protected boolean isHSLF() {
- return paragraph.getClass().getName().contains("HSLF");
+ return DrawShape.isHSLF(paragraph.getParentShape());
}
/**
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java index 3a1d8faeea..45819624bb 100644 --- a/src/java/org/apache/poi/sl/draw/DrawTextShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawTextShape.java @@ -138,6 +138,7 @@ public class DrawTextShape extends DrawSimpleShape { double y0 = y;
//noinspection RedundantCast
+ @SuppressWarnings("cast")
Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs =
(Iterator<? extends TextParagraph<?,?,? extends TextRun>>) getShape().iterator();
diff --git a/src/java/org/apache/poi/sl/draw/Drawable.java b/src/java/org/apache/poi/sl/draw/Drawable.java index 7df8533b56..cc85dde905 100644 --- a/src/java/org/apache/poi/sl/draw/Drawable.java +++ b/src/java/org/apache/poi/sl/draw/Drawable.java @@ -130,6 +130,12 @@ public interface Drawable { DrawableHint GSAVE = new DrawableHint(10);
DrawableHint GRESTORE = new DrawableHint(11);
+ /**
+ * The Common SL Draw API works sometimes cascading, but there are places
+ * where the current slide context need to be evaluated, e.g. when slide numbers
+ * are printed. In this situation we need to have a way to access the current slide
+ */
+ DrawableHint CURRENT_SLIDE = new DrawableHint(12);
/**
diff --git a/src/java/org/apache/poi/sl/usermodel/Placeholder.java b/src/java/org/apache/poi/sl/usermodel/Placeholder.java index a3bc9c7c88..e546e8bee2 100644 --- a/src/java/org/apache/poi/sl/usermodel/Placeholder.java +++ b/src/java/org/apache/poi/sl/usermodel/Placeholder.java @@ -114,12 +114,30 @@ public enum Placeholder { this.ooxmlId = ooxmlId;
}
- public static Placeholder lookupNative(int nativeId) {
+ public static Placeholder lookupNativeSlide(int nativeId) {
+ return lookupNative(nativeId, 0);
+ }
+
+ public static Placeholder lookupNativeSlideMaster(int nativeId) {
+ return lookupNative(nativeId, 1);
+ }
+
+ public static Placeholder lookupNativeNotes(int nativeId) {
+ return lookupNative(nativeId, 2);
+ }
+
+ public static Placeholder lookupNativeNotesMaster(int nativeId) {
+ return lookupNative(nativeId, 3);
+ }
+
+
+ private static Placeholder lookupNative(int nativeId, int type) {
for (Placeholder ph : values()) {
- if (ph.nativeSlideId == nativeId ||
- ph.nativeSlideMasterId == nativeId ||
- ph.nativeNotesId == nativeId ||
- ph.nativeNotesMasterId == nativeId
+ if (
+ type == 0 && ph.nativeSlideId == nativeId ||
+ type == 1 && ph.nativeSlideMasterId == nativeId ||
+ type == 2 && ph.nativeNotesId == nativeId ||
+ type == 3 && ph.nativeNotesMasterId == nativeId
) {
return ph;
}
diff --git a/src/java/org/apache/poi/sl/usermodel/Slide.java b/src/java/org/apache/poi/sl/usermodel/Slide.java index dae2f42e67..1f77ba6e5d 100644 --- a/src/java/org/apache/poi/sl/usermodel/Slide.java +++ b/src/java/org/apache/poi/sl/usermodel/Slide.java @@ -43,4 +43,14 @@ public interface Slide< */ String getTitle(); + /** + * In XSLF, slidenumber and date shapes aren't marked as placeholders + * whereas in HSLF they are activated via a HeadersFooter configuration. + * This method is used to generalize that handling. + * + * @param placeholder + * @return {@code true} if the placeholder should be displayed/rendered + * @since POI 3.16-beta2 + */ + boolean getDisplayPlaceholder(Placeholder placeholder); } diff --git a/src/java/org/apache/poi/sl/usermodel/TextRun.java b/src/java/org/apache/poi/sl/usermodel/TextRun.java index 014d3036b3..32b9c9933d 100644 --- a/src/java/org/apache/poi/sl/usermodel/TextRun.java +++ b/src/java/org/apache/poi/sl/usermodel/TextRun.java @@ -20,6 +20,7 @@ package org.apache.poi.sl.usermodel; import java.awt.Color; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.poi.util.Internal; /** * Some text. @@ -30,6 +31,10 @@ public interface TextRun { SMALL, ALL } + + enum FieldType { + SLIDE_NUMBER, DATE_TIME + } String getRawText(); void setText(String text); @@ -176,4 +181,12 @@ public interface TextRun { * @since POI 3.14-Beta2 */ Hyperlink<?,?> createHyperlink(); + + /** + * Experimental method to determine the field type, e.g. slide number + * + * @return the field type or {@code null} if text run is not a field + */ + @Internal + FieldType getFieldType(); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java index bdbc461f4b..934c0e3eec 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFLineBreak.java @@ -19,20 +19,11 @@ package org.apache.poi.xslf.usermodel;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
class XSLFLineBreak extends XSLFTextRun {
- private final CTTextCharacterProperties _brProps;
-
- XSLFLineBreak(CTRegularTextRun r, XSLFTextParagraph p, CTTextCharacterProperties brProps){
+ protected XSLFLineBreak(CTTextLineBreak r, XSLFTextParagraph p) {
super(r, p);
- _brProps = brProps;
- }
-
- @Override
- protected CTTextCharacterProperties getRPr(boolean create){
- return _brProps;
}
public void setText(String text){
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java index f6e5ad0a95..a15d90cc4d 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPropertiesDelegate.java @@ -1341,106 +1341,138 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperti this.props = props; } + @Override public CTNoFillProperties getNoFill() { return isSetNoFill() ? (CTNoFillProperties)props : null; } + @Override public boolean isSetNoFill() { return (props instanceof CTNoFillProperties); } + @Override public void setNoFill(CTNoFillProperties noFill) {} + @Override public CTNoFillProperties addNewNoFill() { return null; } + @Override public void unsetNoFill() {} + @Override public CTSolidColorFillProperties getSolidFill() { return isSetSolidFill() ? (CTSolidColorFillProperties)props : null; } + @Override public boolean isSetSolidFill() { return (props instanceof CTSolidColorFillProperties); } + @Override public void setSolidFill(CTSolidColorFillProperties solidFill) {} + @Override public CTSolidColorFillProperties addNewSolidFill() { return null; } + @Override public void unsetSolidFill() {} + @Override public CTGradientFillProperties getGradFill() { return isSetGradFill() ? (CTGradientFillProperties)props : null; } + @Override public boolean isSetGradFill() { return (props instanceof CTGradientFillProperties); } + @Override public void setGradFill(CTGradientFillProperties gradFill) {} + @Override public CTGradientFillProperties addNewGradFill() { return null; } + @Override public void unsetGradFill() {} + @Override public CTBlipFillProperties getBlipFill() { return isSetBlipFill() ? (CTBlipFillProperties)props : null; } + @Override public boolean isSetBlipFill() { return (props instanceof CTBlipFillProperties); } + @Override public void setBlipFill(CTBlipFillProperties blipFill) {} + @Override public CTBlipFillProperties addNewBlipFill() { return null; } + @Override public void unsetBlipFill() {} + @Override public CTPatternFillProperties getPattFill() { return isSetPattFill() ? (CTPatternFillProperties)props : null; } + @Override public boolean isSetPattFill() { return (props instanceof CTPatternFillProperties); } + @Override public void setPattFill(CTPatternFillProperties pattFill) {} + @Override public CTPatternFillProperties addNewPattFill() { return null; } + @Override public void unsetPattFill() {} + @Override public CTGroupFillProperties getGrpFill() { return isSetGrpFill() ? (CTGroupFillProperties)props : null; } + @Override public boolean isSetGrpFill() { return (props instanceof CTGroupFillProperties); } + @Override public void setGrpFill(CTGroupFillProperties grpFill) {} + @Override public CTGroupFillProperties addNewGrpFill() { return null; } + @Override public void unsetGrpFill() {} + @Override public boolean isSetMatrixStyle() { return false; } + @Override public CTStyleMatrixReference getMatrixStyle() { return null; } 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 70df3f806a..d73dcc8c0a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -32,6 +32,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.ColorStyle;
+import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
@@ -57,6 +58,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillPropertie import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
@@ -150,6 +152,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { protected PaintStyle getFillPaint() {
final XSLFTheme theme = getSheet().getTheme();
+ final boolean hasPlaceholder = getPlaceholder() != null;
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
public boolean fetch(XSLFShape shape) {
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
@@ -163,7 +166,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { }
PackagePart pp = shape.getSheet().getPackagePart();
- PaintStyle paint = selectPaint(fp, null, pp, theme);
+ PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
if (paint != null) {
setValue(paint);
return true;
@@ -172,7 +175,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { CTShapeStyle style = shape.getSpStyle();
if (style != null) {
fp = XSLFPropertiesDelegate.getFillDelegate(style.getFillRef());
- paint = selectPaint(fp, null, pp, theme);
+ paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
}
if (paint != null) {
setValue(paint);
@@ -230,6 +233,9 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { if (cur.toChild(namespace, nodename)) {
child = (T)cur.getObject();
}
+ if (cur.toChild("http://schemas.openxmlformats.org/drawingml/2006/main", nodename)) {
+ child = (T)cur.getObject();
+ }
cur.dispose();
return child;
}
@@ -290,61 +296,71 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { }
/**
- * Walk up the inheritance tree and fetch shape properties.
+ * Walk up the inheritance tree and fetch shape properties.<p>
*
- * The following order of inheritance is assumed:
- * <p>
- * slide <-- slideLayout <-- slideMaster
- * </p>
+ * The following order of inheritance is assumed:<p>
+ * <ol>
+ * <li>slide
+ * <li>slideLayout
+ * <li>slideMaster
+ * </ol>
+ *
+ * Currently themes and their defaults aren't correctly handled
*
* @param visitor the object that collects the desired property
* @return true if the property was fetched
*/
protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
- boolean ok = visitor.fetch(this);
+ // try shape properties in slide
+ if (visitor.fetch(this)) {
+ return true;
+ }
- XSLFSimpleShape masterShape;
- XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet();
CTPlaceholder ph = getCTPlaceholder();
-
- if (masterSheet != null && ph != null) {
- if (!ok) {
- masterShape = masterSheet.getPlaceholder(ph);
- if (masterShape != null) {
- ok = visitor.fetch(masterShape);
- }
+ if (ph == null) {
+ return false;
+ }
+ MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet();
+
+ // try slide layout
+ if (sm instanceof XSLFSlideLayout) {
+ XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm;
+ XSLFSimpleShape placeholderShape = slideLayout.getPlaceholder(ph);
+ if (placeholderShape != null && visitor.fetch(placeholderShape)) {
+ return true;
}
-
- // try slide master
- if (!ok ) {
- int textType;
- if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
- else {
- switch (ph.getType().intValue()) {
- case STPlaceholderType.INT_TITLE:
- case STPlaceholderType.INT_CTR_TITLE:
- textType = STPlaceholderType.INT_TITLE;
- break;
- case STPlaceholderType.INT_FTR:
- case STPlaceholderType.INT_SLD_NUM:
- case STPlaceholderType.INT_DT:
- textType = ph.getType().intValue();
- break;
- default:
- textType = STPlaceholderType.INT_BODY;
- break;
- }
- }
- XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet();
- if (master != null) {
- masterShape = master.getPlaceholderByType(textType);
- if (masterShape != null) {
- ok = visitor.fetch(masterShape);
- }
- }
+ sm = slideLayout.getMasterSheet();
+ }
+
+ // try slide master
+ if (sm instanceof XSLFSlideMaster) {
+ XSLFSlideMaster master = (XSLFSlideMaster)sm;
+ int textType = getPlaceholderType(ph);
+ XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
+ if (masterShape != null && visitor.fetch(masterShape)) {
+ return true;
}
}
- return ok;
+
+ return false;
+ }
+
+ private static int getPlaceholderType(CTPlaceholder ph) {
+ if ( !ph.isSetType()) {
+ return STPlaceholderType.INT_BODY;
+ }
+
+ switch (ph.getType().intValue()) {
+ case STPlaceholderType.INT_TITLE:
+ case STPlaceholderType.INT_CTR_TITLE:
+ return STPlaceholderType.INT_TITLE;
+ case STPlaceholderType.INT_FTR:
+ case STPlaceholderType.INT_SLD_NUM:
+ case STPlaceholderType.INT_DT:
+ return ph.getType().intValue();
+ default:
+ return STPlaceholderType.INT_BODY;
+ }
}
/**
@@ -358,7 +374,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { *
* @return the applied Paint or null if none was applied
*/
- protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {
+ protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) {
if (fp == null || fp.isSetNoFill()) {
return null;
} else if (fp.isSetSolidFill()) {
@@ -368,15 +384,23 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { } else if (fp.isSetGradFill()) {
return selectPaint(fp.getGradFill(), phClr, theme);
} else if (fp.isSetMatrixStyle()) {
- return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle());
+ return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder);
} else {
return null;
}
}
protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
- if (phClr == null && solidFill.isSetSchemeClr()) {
- phClr = solidFill.getSchemeClr();
+ if (solidFill.isSetSchemeClr()) {
+ // if there's a reference to the placeholder color,
+ // stop evaluating further and let the caller select
+ // the next style inheritance level
+ if (STSchemeColorVal.PH_CLR.equals(solidFill.getSchemeClr().getVal())) {
+ return null;
+ }
+ if (phClr == null) {
+ phClr = solidFill.getSchemeClr();
+ }
}
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
return DrawPaint.createSolidPaint(c.getColorStyle());
@@ -483,7 +507,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { };
}
- protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) {
+ protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
if (fillRef == null) return null;
// The idx attribute refers to the index of a fill style or
@@ -492,7 +516,6 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { // values 1-999 refer to the index of a fill style within the fillStyleLst element
// values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.
int idx = (int)fillRef.getIdx();
- CTSchemeColor phClr = fillRef.getSchemeClr();
CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
final XmlObject styleLst;
int childIdx;
@@ -511,8 +534,16 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
}
cur.dispose();
-
- return selectPaint(fp, phClr, theme.getPackagePart(), theme);
+
+ CTSchemeColor phClr = fillRef.getSchemeClr();
+ PaintStyle res = selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder);
+ // check for empty placeholder value
+ // see http://officeopenxml.com/prSlide-color.php - "Color Placeholders within Themes"
+ if (res != null || hasPlaceholder) {
+ return res;
+ }
+ XSLFColor col = new XSLFColor(fillRef, theme, phClr);
+ return DrawPaint.createSolidPaint(col.getColorStyle());
}
@Override
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 ce058f15a0..5d1d23191c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java @@ -121,6 +121,7 @@ public abstract class XSLFSimpleShape extends XSLFShape protected CTTransform2D getXfrm(boolean create) { PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() { + @Override public boolean fetch(XSLFShape shape) { XmlObject xo = shape.getShapeProperties(); if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) { @@ -234,20 +235,32 @@ public abstract class XSLFSimpleShape extends XSLFShape */ CTLineProperties getDefaultLineProperties() { CTShapeStyle style = getSpStyle(); - if (style == null) return null; + if (style == null) { + return null; + } CTStyleMatrixReference lnRef = style.getLnRef(); - if (lnRef == null) return null; + if (lnRef == null) { + return null; + } // 1-based index of a line style within the style matrix int idx = (int)lnRef.getIdx(); XSLFTheme theme = getSheet().getTheme(); - if (theme == null) return null; + if (theme == null) { + return null; + } CTBaseStyles styles = theme.getXmlObject().getThemeElements(); - if (styles == null) return null; + if (styles == null) { + return null; + } CTStyleMatrix styleMatrix = styles.getFmtScheme(); - if (styleMatrix == null) return null; + if (styleMatrix == null) { + return null; + } CTLineStyleList lineStyles = styleMatrix.getLnStyleLst(); - if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) return null; + if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) { + return null; + } return lineStyles.getLnArray(idx - 1); } @@ -301,12 +314,14 @@ public abstract class XSLFSimpleShape extends XSLFShape protected PaintStyle getLinePaint() { XSLFSheet sheet = getSheet(); final XSLFTheme theme = sheet.getTheme(); + final boolean hasPlaceholder = getPlaceholder() != null; PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() { + @Override public boolean fetch(XSLFShape shape) { CTLineProperties spPr = getLn(shape, false); XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr); PackagePart pp = shape.getSheet().getPackagePart(); - PaintStyle paint = selectPaint(fp, null, pp, theme); + PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder); if (paint != null) { setValue(paint); return true; @@ -315,7 +330,7 @@ public abstract class XSLFSimpleShape extends XSLFShape CTShapeStyle style = shape.getSpStyle(); if (style != null) { fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef()); - paint = selectPaint(fp, null, pp, theme); + paint = selectPaint(fp, null, pp, theme, hasPlaceholder); } if (paint != null) { setValue(paint); @@ -327,11 +342,15 @@ public abstract class XSLFSimpleShape extends XSLFShape fetchShapeProperty(fetcher); PaintStyle paint = fetcher.getValue(); - if (paint != null) return paint; + if (paint != null) { + return paint; + } // line color was not found, check if it is defined in the theme CTShapeStyle style = getSpStyle(); - if (style == null) return null; + if (style == null) { + return null; + } // get a reference to a line style within the style matrix. CTStyleMatrixReference lnRef = style.getLnRef(); @@ -341,7 +360,7 @@ public abstract class XSLFSimpleShape extends XSLFShape CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1); XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); PackagePart pp = sheet.getPackagePart(); - paint = selectPaint(fp, phClr, pp, theme); + paint = selectPaint(fp, phClr, pp, theme, hasPlaceholder); } return paint; @@ -387,6 +406,7 @@ public abstract class XSLFSimpleShape extends XSLFShape */ public double getLineWidth() { PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() { + @Override public boolean fetch(XSLFShape shape) { CTLineProperties ln = getLn(shape, false); if (ln != null) { @@ -409,7 +429,9 @@ public abstract class XSLFSimpleShape extends XSLFShape if (fetcher.getValue() == null) { CTLineProperties defaultLn = getDefaultLineProperties(); if (defaultLn != null) { - if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW()); + if (defaultLn.isSetW()) { + lineWidth = Units.toPoints(defaultLn.getW()); + } } } else { lineWidth = fetcher.getValue(); @@ -460,6 +482,7 @@ public abstract class XSLFSimpleShape extends XSLFShape */ public LineCompound getLineCompound() { PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() { + @Override public boolean fetch(XSLFShape shape) { CTLineProperties ln = getLn(shape, false); if (ln != null) { @@ -522,6 +545,7 @@ public abstract class XSLFSimpleShape extends XSLFShape public LineDash getLineDash() { PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() { + @Override public boolean fetch(XSLFShape shape) { CTLineProperties ln = getLn(shape, false); if (ln == null || !ln.isSetPrstDash()) { @@ -569,6 +593,7 @@ public abstract class XSLFSimpleShape extends XSLFShape */ public LineCap getLineCap() { PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() { + @Override public boolean fetch(XSLFShape shape) { CTLineProperties ln = getLn(shape, false); if (ln != null && ln.isSetCap()) { @@ -640,8 +665,10 @@ public abstract class XSLFSimpleShape extends XSLFShape /** * @return shadow of this shape or null if shadow is disabled */ + @Override public XSLFShadow getShadow() { PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() { + @Override public boolean fetch(XSLFShape shape) { XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties()); if (ep != null && ep.isSetEffectLst()) { @@ -675,6 +702,7 @@ public abstract class XSLFSimpleShape extends XSLFShape * * @return definition of the shape geometry */ + @Override public CustomGeometry getGeometry() { XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); @@ -949,6 +977,7 @@ public abstract class XSLFSimpleShape extends XSLFShape return ph != null; } + @Override public Guide getAdjustValue(String name) { XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties()); @@ -963,28 +992,35 @@ public abstract class XSLFSimpleShape extends XSLFShape return null; } + @Override public LineDecoration getLineDecoration() { return new LineDecoration() { + @Override public DecorationShape getHeadShape() { return getLineHeadDecoration(); } + @Override public DecorationSize getHeadWidth() { return getLineHeadWidth(); } + @Override public DecorationSize getHeadLength() { return getLineHeadLength(); } + @Override public DecorationShape getTailShape() { return getLineTailDecoration(); } + @Override public DecorationSize getTailWidth() { return getLineTailWidth(); } + @Override public DecorationSize getTailLength() { return getLineTailLength(); } @@ -996,32 +1032,40 @@ public abstract class XSLFSimpleShape extends XSLFShape * * @return either Color or GradientPaint or TexturePaint or null */ + @Override public FillStyle getFillStyle() { return new FillStyle() { + @Override public PaintStyle getPaint() { return XSLFSimpleShape.this.getFillPaint(); } }; } + @Override public StrokeStyle getStrokeStyle() { return new StrokeStyle() { + @Override public PaintStyle getPaint() { return XSLFSimpleShape.this.getLinePaint(); } + @Override public LineCap getLineCap() { return XSLFSimpleShape.this.getLineCap(); } + @Override public LineDash getLineDash() { return XSLFSimpleShape.this.getLineDash(); } + @Override public double getLineWidth() { return XSLFSimpleShape.this.getLineWidth(); } + @Override public LineCompound getLineCompound() { return XSLFSimpleShape.this.getLineCompound(); } 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 140921aa33..dcd9642617 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java @@ -207,7 +207,7 @@ implements Slide<XSLFShape,XSLFTextParagraph> { @Override public boolean getFollowMasterGraphics(){ - return _slide.isSetShowMasterSp() && _slide.getShowMasterSp(); + return _slide.getShowMasterSp(); } /** @@ -306,4 +306,9 @@ implements Slide<XSLFShape,XSLFTextParagraph> { Drawable draw = drawFact.getDrawable(this); draw.draw(graphics); } + + @Override + public boolean getDisplayPlaceholder(Placeholder placeholder) { + return false; + } } 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 704d09ea94..b4e53f4feb 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java @@ -104,7 +104,7 @@ implements MasterSheet<XSLFShape,XSLFTextParagraph> { @Override public boolean getFollowMasterGraphics() { - return _layout.isSetShowMasterSp() && _layout.getShowMasterSp(); + return _layout.getShowMasterSp(); } /** diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java index 7b13e5842a..7c7cceac51 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java @@ -145,7 +145,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, }
CTTableCellProperties pr = getCellProperties(create);
- if (pr == null) return null;
+ if (pr == null) {
+ return null;
+ }
switch (edge) {
case bottom:
@@ -164,7 +166,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, @Override
public void removeBorder(BorderEdge edge) {
CTTableCellProperties pr = getCellProperties(false);
- if (pr == null) return;
+ if (pr == null) {
+ return;
+ }
switch (edge) {
case bottom:
if (pr.isSetLnB()) {
@@ -195,22 +199,27 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public StrokeStyle getBorderStyle(final BorderEdge edge) {
final Double width = getBorderWidth(edge);
return (width == null) ? null : new StrokeStyle() {
+ @Override
public PaintStyle getPaint() {
return DrawPaint.createSolidPaint(getBorderColor(edge));
}
+ @Override
public LineCap getLineCap() {
return getBorderCap(edge);
}
+ @Override
public LineDash getLineDash() {
return getBorderDash(edge);
}
+ @Override
public LineCompound getLineCompound() {
return getBorderCompound(edge);
}
+ @Override
public double getLineWidth() {
return width;
}
@@ -306,7 +315,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public Color getBorderColor(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false);
- if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
+ if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) {
+ return null;
+ }
CTSolidColorFillProperties fill = ln.getSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
@@ -381,7 +392,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public void setFillColor(Color color) {
CTTableCellProperties spPr = getCellProperties(true);
if (color == null) {
- if(spPr.isSetSolidFill()) spPr.unsetSolidFill();
+ if(spPr.isSetSolidFill()) {
+ spPr.unsetSolidFill();
+ }
} else {
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
@@ -409,10 +422,11 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public PaintStyle getFillPaint() {
XSLFSheet sheet = getSheet();
XSLFTheme theme = sheet.getTheme();
+ final boolean hasPlaceholder = getPlaceholder() != null;
XmlObject props = getCellProperties(false);
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
if (fp != null) {
- PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme);
+ PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme, hasPlaceholder);
if (paint != null) {
return paint;
}
@@ -438,7 +452,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, fp = XSLFPropertiesDelegate.getFillDelegate(props);
if (fp != null) {
- PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme);
+ PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme, hasPlaceholder);
if (paint != null) {
return paint;
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index 38c298275b..0944d542ee 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -72,23 +72,20 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr _runs = new ArrayList<XSLFTextRun>(); _shape = shape; - for(XmlObject ch : _p.selectPath("*")){ - if(ch instanceof CTRegularTextRun){ - CTRegularTextRun r = (CTRegularTextRun)ch; - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextLineBreak){ - CTTextLineBreak br = (CTTextLineBreak)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(br.getRPr()); - r.setT("\n"); - _runs.add(newTextRun(r)); - } else if (ch instanceof CTTextField){ - CTTextField f = (CTTextField)ch; - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(f.getRPr()); - r.setT(f.getT()); - _runs.add(newTextRun(r)); + XmlCursor c = _p.newCursor(); + try { + if (c.toFirstChild()) { + do { + XmlObject r = c.getObject(); + if (r instanceof CTTextLineBreak) { + _runs.add(new XSLFLineBreak((CTTextLineBreak)r, this)); + } else if (r instanceof CTRegularTextRun || r instanceof CTTextField) { + _runs.add(new XSLFTextRun(r, this)); + } + } while (c.toNextSibling()); } + } finally { + c.dispose(); } } @@ -147,17 +144,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr * @return text run representing this line break ('\n') */ public XSLFTextRun addLineBreak(){ - CTTextLineBreak br = _p.addNewBr(); - CTTextCharacterProperties brProps = br.addNewRPr(); + XSLFLineBreak run = new XSLFLineBreak(_p.addNewBr(), this); + CTTextCharacterProperties brProps = run.getRPr(true); if(_runs.size() > 0){ // by default line break has the font size of the last text run CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true); brProps.set(prevRun); } - CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); - r.setRPr(brProps); - r.setT("\n"); - XSLFTextRun run = new XSLFLineBreak(r, this, brProps); _runs.add(run); return run; } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java index b0bbd45570..7bf2a6c6ef 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java @@ -18,6 +18,7 @@ package org.apache.poi.xslf.usermodel; import java.awt.Color;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle;
@@ -26,13 +27,16 @@ import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.util.Beta;
import org.apache.poi.xslf.model.CharacterPropertyFetcher;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
+import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
@@ -45,12 +49,15 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; */
@Beta
public class XSLFTextRun implements TextRun {
- private final CTRegularTextRun _r;
+ private final XmlObject _r;
private final XSLFTextParagraph _p;
- protected XSLFTextRun(CTRegularTextRun r, XSLFTextParagraph p){
+ protected XSLFTextRun(XmlObject r, XSLFTextParagraph p){
_r = r;
_p = p;
+ if (!(r instanceof CTRegularTextRun || r instanceof CTTextLineBreak || r instanceof CTTextField)) {
+ throw new OpenXML4JRuntimeException("unsupported text run of type "+r.getClass());
+ }
}
XSLFTextParagraph getParentParagraph(){
@@ -58,11 +65,28 @@ public class XSLFTextRun implements TextRun { }
public String getRawText(){
- return _r.getT();
+ if (_r instanceof CTTextField) {
+ return ((CTTextField)_r).getT();
+ } else if (_r instanceof CTTextLineBreak) {
+ return "\n";
+ }
+ return ((CTRegularTextRun)_r).getT();
}
String getRenderableText(){
- String txt = _r.getT();
+ if (_r instanceof CTTextField) {
+ CTTextField tf = (CTTextField)_r;
+ XSLFSheet sheet = _p.getParentShape().getSheet();
+ if ("slidenum".equals(tf.getType()) && sheet instanceof XSLFSlide) {
+ return Integer.toString(((XSLFSlide)sheet).getSlideNumber());
+ }
+ return tf.getT();
+ } else if (_r instanceof CTTextLineBreak) {
+ return "\n";
+ }
+
+
+ String txt = ((CTRegularTextRun)_r).getT();
TextCap cap = getTextCap();
StringBuffer buf = new StringBuffer();
for(int i = 0; i < txt.length(); i++) {
@@ -88,10 +112,24 @@ public class XSLFTextRun implements TextRun { }
public void setText(String text){
- _r.setT(text);
+ if (_r instanceof CTTextField) {
+ ((CTTextField)_r).setT(text);
+ } else if (_r instanceof CTTextLineBreak) {
+ // ignored
+ return;
+ } else {
+ ((CTRegularTextRun)_r).setT(text);
+ }
}
- public CTRegularTextRun getXmlObject(){
+ /**
+ * Return the text run xmlbeans object.
+ * Depending on the type of text run, this can be {@link CTTextField},
+ * {@link CTTextLineBreak} or usually a {@link CTRegularTextRun}
+ *
+ * @return the xmlbeans object
+ */
+ public XmlObject getXmlObject(){
return _r;
}
@@ -117,6 +155,7 @@ public class XSLFTextRun implements TextRun { @Override
public PaintStyle getFontColor(){
+ final boolean hasPlaceholder = getParentParagraph().getParentShape().getPlaceholder() != null;
CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
if (props == null) {
@@ -134,7 +173,7 @@ public class XSLFTextRun implements TextRun { XSLFSheet sheet = shape.getSheet();
PackagePart pp = sheet.getPackagePart();
XSLFTheme theme = sheet.getTheme();
- PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme);
+ PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme, hasPlaceholder);
if (ps != null) {
setValue(ps);
@@ -459,13 +498,29 @@ public class XSLFTextRun implements TextRun { * @return the character properties or null if create was false and the properties haven't exist
*/
protected CTTextCharacterProperties getRPr(boolean create) {
- if (_r.isSetRPr()) {
- return _r.getRPr();
- } else if (create) {
- return _r.addNewRPr();
+ if (_r instanceof CTTextField) {
+ CTTextField tf = (CTTextField)_r;
+ if (tf.isSetRPr()) {
+ return tf.getRPr();
+ } else if (create) {
+ return tf.addNewRPr();
+ }
+ } else if (_r instanceof CTTextLineBreak) {
+ CTTextLineBreak tlb = (CTTextLineBreak)_r;
+ if (tlb.isSetRPr()) {
+ return tlb.getRPr();
+ } else if (create) {
+ return tlb.addNewRPr();
+ }
} else {
- return null;
+ CTRegularTextRun tr = (CTRegularTextRun)_r;
+ if (tr.isSetRPr()) {
+ return tr.getRPr();
+ } else if (create) {
+ return tr.addNewRPr();
+ }
}
+ return null;
}
@Override
@@ -476,15 +531,17 @@ public class XSLFTextRun implements TextRun { @Override
public XSLFHyperlink createHyperlink(){
XSLFHyperlink hl = getHyperlink();
- if (hl == null) {
- hl = new XSLFHyperlink(_r.getRPr().addNewHlinkClick(), _p.getParentShape().getSheet());
+ if (hl != null) {
+ return hl;
}
- return hl;
+
+ CTTextCharacterProperties rPr = getRPr(true);
+ return new XSLFHyperlink(rPr.addNewHlinkClick(), _p.getParentShape().getSheet());
}
@Override
public XSLFHyperlink getHyperlink(){
- CTTextCharacterProperties rPr = _r.getRPr();
+ CTTextCharacterProperties rPr = getRPr(false);
if (rPr == null) {
return null;
}
@@ -498,33 +555,33 @@ public class XSLFTextRun implements TextRun { private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
XSLFTextShape shape = _p.getParentShape();
XSLFSheet sheet = shape.getSheet();
- boolean ok = false;
- if (_r.isSetRPr()) ok = fetcher.fetch(getRPr(false));
- if (ok) return true;
+ CTTextCharacterProperties rPr = getRPr(false);
+ if (rPr != null && fetcher.fetch(rPr)) {
+ return true;
+ }
- ok = shape.fetchShapeProperty(fetcher);
- if (ok) return true;
+ if (shape.fetchShapeProperty(fetcher)) {
+ return true;
+ }
CTPlaceholder ph = shape.getCTPlaceholder();
if (ph == null){
// if it is a plain text box then take defaults from presentation.xml
@SuppressWarnings("resource")
XMLSlideShow ppt = sheet.getSlideShow();
+ // TODO: determine master shape
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
- if (themeProps != null) {
- // TODO: determine master shape
- ok = fetcher.fetch(themeProps);
+ if (themeProps != null && fetcher.fetch(themeProps)) {
+ return true;
}
}
- if (ok) return true;
+ // TODO: determine master shape
CTTextParagraphProperties defaultProps = _p.getDefaultMasterStyle();
- if(defaultProps != null) {
- // TODO: determine master shape
- ok = fetcher.fetch(defaultProps);
+ if(defaultProps != null && fetcher.fetch(defaultProps)) {
+ return true;
}
- if (ok) return true;
return false;
}
@@ -557,4 +614,16 @@ public class XSLFTextRun implements TextRun { boolean strike = r.isStrikethrough();
if(strike != isStrikethrough()) setStrikethrough(strike);
}
+
+
+ @Override
+ public FieldType getFieldType() {
+ if (_r instanceof CTTextField) {
+ CTTextField tf = (CTTextField)_r;
+ if ("slidenum".equals(tf.getType())) {
+ return FieldType.SLIDE_NUMBER;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java index 809f745c42..d3bd3a847c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTheme.java @@ -169,5 +169,4 @@ public class XSLFTheme extends POIXMLDocumentPart { } return null; } - } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java index 95dd57d154..31b116f949 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java @@ -108,7 +108,8 @@ public class TestXSLFSlideShow { // And again for the master CTSlideMasterIdListEntry[] masters = xml.getSlideMasterReferences().getSldMasterIdArray(); - assertEquals(2147483648l, masters[0].getId()); + // see SlideAtom.USES_MASTER_SLIDE_ID + assertEquals(0x80000000L, masters[0].getId()); assertEquals("rId1", masters[0].getId2()); assertNotNull(xml.getSlideMaster(masters[0])); diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java index 0e58d410c3..3ef1988b28 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java @@ -105,7 +105,8 @@ public class TestXMLSlideShow extends BaseTestSlideShow { // Next up look for the slide master CTSlideMasterIdListEntry[] masters = xml.getCTPresentation().getSldMasterIdLst().getSldMasterIdArray(); - assertEquals(2147483648l, masters[0].getId()); + // see SlideAtom.USES_MASTER_SLIDE_ID + assertEquals(0x80000000L, masters[0].getId()); assertEquals("rId1", masters[0].getId2()); assertNotNull(xml.getSlideMasters().get(0)); diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java index 798dc472aa..3104cbb677 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java @@ -16,22 +16,26 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+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.assertSame;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.TextShape.TextAutofit;
import org.apache.poi.sl.usermodel.TextShape.TextDirection;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Units;
import org.junit.Test;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
-/**
- * @author Yegor Kozlov
- */
public class TestXSLFAutoShape {
@Test
public void testTextBodyProperies() throws IOException {
@@ -222,56 +226,58 @@ public class TestXSLFAutoShape { assertEquals(1, shape.getTextParagraphs().size());
assertEquals(0, p.getTextRuns().size());
XSLFTextRun r = p.addNewTextRun();
+ CTTextCharacterProperties rPr = r.getRPr(false);
+ assertNotNull(rPr);
assertEquals(1, p.getTextRuns().size());
assertSame(r, p.getTextRuns().get(0));
+
assertEquals(18.0, r.getFontSize(), 0); // default font size for text boxes
- assertFalse(r.getXmlObject().getRPr().isSetSz());
+ assertFalse(rPr.isSetSz());
r.setFontSize(10.0);
- assertTrue(r.getXmlObject().isSetRPr());
- assertEquals(1000, r.getXmlObject().getRPr().getSz());
+ assertEquals(1000, rPr.getSz());
r.setFontSize(12.5);
- assertEquals(1250, r.getXmlObject().getRPr().getSz());
+ assertEquals(1250, rPr.getSz());
r.setFontSize(null);
- assertFalse(r.getXmlObject().getRPr().isSetSz());
+ assertFalse(rPr.isSetSz());
- assertFalse(r.getXmlObject().getRPr().isSetLatin());
+ assertFalse(rPr.isSetLatin());
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master
r.setFontFamily(null);
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master
r.setFontFamily("Arial");
assertEquals("Arial", r.getFontFamily());
- assertEquals("Arial", r.getXmlObject().getRPr().getLatin().getTypeface());
+ assertEquals("Arial", rPr.getLatin().getTypeface());
r.setFontFamily("Symbol");
assertEquals("Symbol", r.getFontFamily());
- assertEquals("Symbol", r.getXmlObject().getRPr().getLatin().getTypeface());
+ assertEquals("Symbol", rPr.getLatin().getTypeface());
r.setFontFamily(null);
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master
- assertFalse(r.getXmlObject().getRPr().isSetLatin());
+ assertFalse(rPr.isSetLatin());
assertFalse(r.isStrikethrough());
- assertFalse(r.getXmlObject().getRPr().isSetStrike());
+ assertFalse(rPr.isSetStrike());
r.setStrikethrough(true);
assertTrue(r.isStrikethrough());
- assertEquals(STTextStrikeType.SNG_STRIKE, r.getXmlObject().getRPr().getStrike());
+ assertEquals(STTextStrikeType.SNG_STRIKE, rPr.getStrike());
assertFalse(r.isBold());
- assertFalse(r.getXmlObject().getRPr().isSetB());
+ assertFalse(rPr.isSetB());
r.setBold(true);
assertTrue(r.isBold());
- assertEquals(true, r.getXmlObject().getRPr().getB());
+ assertEquals(true, rPr.getB());
assertFalse(r.isItalic());
- assertFalse(r.getXmlObject().getRPr().isSetI());
+ assertFalse(rPr.isSetI());
r.setItalic(true);
assertTrue(r.isItalic());
- assertEquals(true, r.getXmlObject().getRPr().getI());
+ assertEquals(true, rPr.getI());
assertFalse(r.isUnderlined());
- assertFalse(r.getXmlObject().getRPr().isSetU());
+ assertFalse(rPr.isSetU());
r.setUnderlined(true);
assertTrue(r.isUnderlined());
- assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU());
+ assertEquals(STTextUnderlineType.SNG, rPr.getU());
r.setText("Apache");
assertEquals("Apache", r.getRawText());
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java index 0ff02d0853..a705bfbbe2 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java @@ -123,10 +123,11 @@ public class TestXSLFHyperlink { XSLFTextBox tb3 = sl3.createTextBox();
tb3.setAnchor(anchor);
tb3.setText("text1 ");
- XSLFTextRun r3 = tb3.appendText("lin\u000bk", false);
+ tb3.appendText("lin\u000bk", false);
tb3.appendText(" text2", false);
- XSLFHyperlink hl3 = r3.createHyperlink();
- hl3.linkToSlide(slide1);
+ List<XSLFTextRun> tb3runs = tb3.getTextParagraphs().get(0).getTextRuns();
+ tb3runs.get(1).createHyperlink().linkToSlide(slide1); // "lin"
+ tb3runs.get(3).createHyperlink().linkToSlide(slide1); // "k"
XSLFTextBox tb4 = ppt1.createSlide().createTextBox();
tb4.setAnchor(anchor);
XSLFTextRun r4 = tb4.setText("page4");
@@ -155,6 +156,8 @@ public class TestXSLFHyperlink { assertEquals(HyperlinkType.DOCUMENT, hl2.getTypeEnum());
tb3 = (XSLFTextBox)slides.get(2).getShapes().get(0);
+ XSLFHyperlink hl3 = tb3.getTextParagraphs().get(0).getTextRuns().get(1).getHyperlink();
+ assertNotNull(hl3);
hl3 = tb3.getTextParagraphs().get(0).getTextRuns().get(3).getHyperlink();
assertNotNull(hl3);
assertEquals("/ppt/slides/slide1.xml", hl3.getAddress());
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java index fa56117893..403ccb6790 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java @@ -16,18 +16,17 @@ ==================================================================== */
package org.apache.poi.xslf.usermodel;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * @author Yegor Kozlov
- */
public class TestXSLFShape {
@Test
@@ -63,7 +62,7 @@ public class TestXSLFShape { assertEquals("PPTX ", r2.get(0).getRawText());
assertEquals("Title", r2.get(1).getRawText());
// Title is underlined
- assertEquals(STTextUnderlineType.SNG, r2.get(1).getXmlObject().getRPr().getU());
+ assertEquals(STTextUnderlineType.SNG, r2.get(1).getRPr(false).getU());
assertTrue(shapes2.get(1) instanceof XSLFAutoShape);
@@ -78,7 +77,7 @@ public class TestXSLFShape { assertEquals(1, paragraphs2.get(1).getTextRuns().size());
assertEquals("Subtitle", paragraphs2.get(0).getTextRuns().get(0).getRawText());
- assertTrue(paragraphs2.get(0).getTextRuns().get(0).getXmlObject().getRPr().getB());
+ assertTrue(paragraphs2.get(0).getTextRuns().get(0).getRPr(false).getB());
assertEquals("And second line", paragraphs2.get(1).getTextRuns().get(0).getRawText());
ppt.close();
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java index 0af1347aba..fad3f82a00 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java @@ -111,7 +111,7 @@ public class TestXSLFSlide { assertEquals(0, ppt.getSlides().size());
XSLFSlide slide = ppt.createSlide();
- assertFalse(slide.getFollowMasterGraphics());
+ assertTrue(slide.getFollowMasterGraphics());
slide.setFollowMasterGraphics(false);
assertFalse(slide.getFollowMasterGraphics());
slide.setFollowMasterGraphics(true);
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 771fd9d915..13024e6fdb 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -714,7 +714,7 @@ public class TestXSLFTextShape { // level 5: text properties are defined in the text run
CTTextParagraphProperties lv5PPr = paragraph.getXmlObject().addNewPPr();
- CTTextCharacterProperties lv5CPr = textRun.getXmlObject().getRPr();
+ CTTextCharacterProperties lv5CPr = textRun.getRPr(false);
lv5CPr.setSz(3600);
assertEquals(36.0, textRun.getFontSize(), 0);
lv5CPr.addNewLatin().setTypeface("Calibri");
@@ -899,11 +899,11 @@ public class TestXSLFTextShape { // level 5: text properties are defined in the text run
lv1PPr = p1.getXmlObject().isSetPPr() ? p1.getXmlObject().getPPr() : p1.getXmlObject().addNewPPr();
- lv1CPr = r1.getXmlObject().getRPr();
+ lv1CPr = r1.getRPr(false);
lv2PPr = p2.getXmlObject().isSetPPr() ? p2.getXmlObject().getPPr() : p2.getXmlObject().addNewPPr();
- lv2CPr = r2.getXmlObject().getRPr();
+ lv2CPr = r2.getRPr(false);
lv3PPr = p3.getXmlObject().isSetPPr() ? p3.getXmlObject().getPPr() : p3.getXmlObject().addNewPPr();
- lv3CPr = r3.getXmlObject().getRPr();
+ lv3CPr = r3.getRPr(false);
lv1CPr.setSz(3600);
assertEquals(36.0, r1.getFontSize(), 0);
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java index 912ecc0f3d..a181e4f8ff 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java @@ -17,12 +17,15 @@ package org.apache.poi.xslf.usermodel;
import static org.apache.poi.sl.TestCommonSL.sameColor;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.util.List;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
@@ -54,7 +57,9 @@ public class TestXSLFTheme { private XSLFShape getShape(XSLFSheet sheet, String name){
for(XSLFShape sh : sheet.getShapes()){
- if(sh.getShapeName().equals(name)) return sh;
+ if(sh.getShapeName().equals(name)) {
+ return sh;
+ }
}
throw new IllegalArgumentException("Shape not found: " + name);
}
@@ -99,7 +104,7 @@ public class TestXSLFTheme { assertTrue(sameColor(new Color(148, 198, 0), run2.getFontColor()));
assertNull(sh2.getFillColor()); // no fill
- assertFalse(slide.getSlideLayout().getFollowMasterGraphics());
+ assertTrue(slide.getSlideLayout().getFollowMasterGraphics());
}
void slide5(XSLFSlide slide){
@@ -113,7 +118,7 @@ public class TestXSLFTheme { // font size is 40pt and scale factor is 90%
assertEquals(36.0, run2.getFontSize(), 0);
- assertFalse(slide.getSlideLayout().getFollowMasterGraphics());
+ assertTrue(slide.getSlideLayout().getFollowMasterGraphics());
}
void slide6(XSLFSlide slide){
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java index 9bfa5f3254..ab96c7dbe6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HeadersFooters.java @@ -21,13 +21,14 @@ import org.apache.poi.hslf.record.CString; import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.record.HeadersFootersAtom; import org.apache.poi.hslf.record.HeadersFootersContainer; -import org.apache.poi.hslf.record.OEPlaceholderAtom; import org.apache.poi.hslf.record.Record; import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.SheetContainer; import org.apache.poi.hslf.usermodel.HSLFSheet; +import org.apache.poi.hslf.usermodel.HSLFSimpleShape; import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hslf.usermodel.HSLFTextShape; +import org.apache.poi.sl.usermodel.Placeholder; /** * Header / Footer settings. @@ -87,7 +88,7 @@ public final class HeadersFooters { */ public String getHeaderText(){ CString cs = _container == null ? null : _container.getHeaderAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterHeader, cs); + return getPlaceholderText(Placeholder.HEADER, cs); } /** @@ -112,7 +113,7 @@ public final class HeadersFooters { */ public String getFooterText(){ CString cs = _container == null ? null : _container.getFooterAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterFooter, cs); + return getPlaceholderText(Placeholder.FOOTER, cs); } /** @@ -137,7 +138,7 @@ public final class HeadersFooters { */ public String getDateTimeText(){ CString cs = _container == null ? null : _container.getUserDateAtom(); - return getPlaceholderText(OEPlaceholderAtom.MasterDate, cs); + return getPlaceholderText(Placeholder.DATETIME, cs); } /** @@ -160,7 +161,7 @@ public final class HeadersFooters { * whether the footer text is displayed. */ public boolean isFooterVisible(){ - return isVisible(HeadersFootersAtom.fHasFooter, OEPlaceholderAtom.MasterFooter); + return isVisible(HeadersFootersAtom.fHasFooter, Placeholder.FOOTER); } /** @@ -174,7 +175,7 @@ public final class HeadersFooters { * whether the header text is displayed. */ public boolean isHeaderVisible(){ - return isVisible(HeadersFootersAtom.fHasHeader, OEPlaceholderAtom.MasterHeader); + return isVisible(HeadersFootersAtom.fHasHeader, Placeholder.HEADER); } /** @@ -188,7 +189,7 @@ public final class HeadersFooters { * whether the date is displayed in the footer. */ public boolean isDateTimeVisible(){ - return isVisible(HeadersFootersAtom.fHasDate, OEPlaceholderAtom.MasterDate); + return isVisible(HeadersFootersAtom.fHasDate, Placeholder.DATETIME); } /** @@ -202,7 +203,7 @@ public final class HeadersFooters { * whether the custom user date is used instead of today's date. */ public boolean isUserDateVisible(){ - return isVisible(HeadersFootersAtom.fHasUserDate, OEPlaceholderAtom.MasterDate); + return isVisible(HeadersFootersAtom.fHasUserDate, Placeholder.DATETIME); } /** @@ -216,7 +217,7 @@ public final class HeadersFooters { * whether the slide number is displayed in the footer. */ public boolean isSlideNumberVisible(){ - return isVisible(HeadersFootersAtom.fHasSlideNumber, OEPlaceholderAtom.MasterSlideNumber); + return isVisible(HeadersFootersAtom.fHasSlideNumber, Placeholder.SLIDE_NUMBER); } /** @@ -244,31 +245,29 @@ public final class HeadersFooters { _container.getHeadersFootersAtom().setFormatId(formatId); } - private boolean isVisible(int flag, int placeholderId){ + private boolean isVisible(int flag, Placeholder placeholderId){ boolean visible; if(_ppt2007){ - HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); - visible = placeholder != null && placeholder.getText() != null; + HSLFSimpleShape ss = _sheet.getPlaceholder(placeholderId); + visible = ss instanceof HSLFTextShape && ((HSLFTextShape)ss).getText() != null; } else { visible = _container.getHeadersFootersAtom().getFlag(flag); } return visible; } - private String getPlaceholderText(int placeholderId, CString cs){ - String text = null; + private String getPlaceholderText(Placeholder ph, CString cs) { + String text; if (_ppt2007) { - HSLFTextShape placeholder = _sheet.getPlaceholder(placeholderId); - if (placeholder != null) { - text = placeholder.getText(); - } + HSLFSimpleShape ss = _sheet.getPlaceholder(ph); + text = (ss instanceof HSLFTextShape) ? ((HSLFTextShape)ss).getText() : null; // default text in master placeholders is not visible if("*".equals(text)) { text = null; } } else { - text = cs == null ? null : cs.getText(); + text = (cs == null) ? null : cs.getText(); } return text; } 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 54d5d86221..3bdea4e4b2 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java @@ -17,17 +17,18 @@ package org.apache.poi.hslf.record; -import org.apache.poi.util.LittleEndian; import java.io.IOException; import java.io.OutputStream; +import org.apache.poi.sl.usermodel.Placeholder; +import org.apache.poi.util.LittleEndian; + /** - * OEPlaceholderAtom (3011). - * <p> - * An atom record that specifies whether a shape is a placeholder shape. - * </p> + * OEPlaceholderAtom (3011).<p> + * + * An atom record that specifies whether a shape is a placeholder shape. * - * @author Yegor Kozlov + * @see Placeholder */ public final class OEPlaceholderAtom extends RecordAtom{ @@ -47,155 +48,6 @@ public final class OEPlaceholderAtom extends RecordAtom{ */ public static final int PLACEHOLDER_QUARTSIZE = 2; - /** - * MUST NOT be used for this field. - */ - public static final byte None = 0; - - /** - * The corresponding shape contains the master title text. - * The corresponding slide MUST be a main master slide. - */ - public static final byte MasterTitle = 1; - - /** - * The corresponding shape contains the master body text. - * The corresponding slide MUST be a main master slide. - */ - public static final byte MasterBody = 2; - - /** - * The corresponding shape contains the master center title text. - * The corresponding slide MUST be a title master slide. - */ - public static final byte MasterCenteredTitle = 3; - - /** - * The corresponding shape contains the master sub-title text. - * The corresponding slide MUST be a title master slide. - */ - public static final byte MasterSubTitle = 4; - - /** - * The corresponding shape contains the shared properties for slide image shapes. - * The corresponding slide MUST be a notes master slide. - */ - public static final byte MasterNotesSlideImage = 5; - - /** - * The corresponding shape contains the master body text. - * The corresponding slide MUST be a notes master slide. - */ - public static final byte MasterNotesBody = 6; - - /** - * The corresponding shape contains the date text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterDate = 7; - - /** - * The corresponding shape contains a slide number text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterSlideNumber = 8; - - /** - * The corresponding shape contains a footer text field. - * The corresponding slide MUST be a main master slide, title master slide, notes master slide, or handout master slide. - */ - public static final byte MasterFooter = 9; - - /** - * The corresponding shape contains a header text field. - * The corresponding slide must be a notes master slide or handout master slide. - */ - public static final byte MasterHeader = 10; - - /** - * The corresponding shape contains a presentation slide image. - * The corresponding slide MUST be a notes slide. - */ - public static final byte NotesSlideImage = 11; - - /** - * The corresponding shape contains the notes text. - * The corresponding slide MUST be a notes slide. - */ - public static final byte NotesBody = 12; - - /** - * The corresponding shape contains the title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Title = 13; - - /** - * The corresponding shape contains the body text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Body = 14; - - /** - * The corresponding shape contains the title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte CenteredTitle = 15; - - /** - * The corresponding shape contains the sub-title text. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Subtitle = 16; - - /** - * The corresponding shape contains the title text with vertical text flow. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte VerticalTextTitle = 17; - - /** - * The corresponding shape contains the body text with vertical text flow. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte VerticalTextBody = 18; - - /** - * The corresponding shape contains a generic object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Object = 19; - - /** - * The corresponding shape contains a chart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Graph = 20; - - /** - * The corresponding shape contains a table object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte Table = 21; - - /** - * The corresponding shape contains a clipart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte ClipArt = 22; - - /** - * The corresponding shape contains an organization chart object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte OrganizationChart = 23; - - /** - * The corresponding shape contains a media object. - * The corresponding slide MUST be a presentation slide. - */ - public static final byte MediaClip = 24; - private byte[] _header; private int placementId; @@ -205,7 +57,7 @@ public final class OEPlaceholderAtom extends RecordAtom{ /** - * Create a new instance of <code>OEPlaceholderAtom</code> + * Create a new instance of {@code OEPlaceholderAtom} */ public OEPlaceholderAtom(){ _header = new byte[8]; @@ -219,7 +71,7 @@ public final class OEPlaceholderAtom extends RecordAtom{ } /** - * Build an instance of <code>OEPlaceholderAtom</code> from on-disk data + * Build an instance of {@code OEPlaceholderAtom} from on-disk data */ protected OEPlaceholderAtom(byte[] source, int start, int len) { _header = new byte[8]; @@ -236,15 +88,15 @@ public final class OEPlaceholderAtom extends RecordAtom{ /** * @return type of this record {@link RecordTypes#OEPlaceholderAtom}. */ - public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; } + @Override + public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; } /** - * Returns the placement Id. - * <p> + * Returns the placement Id.<p> + * * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders. * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide. * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape. - * </p> * * @return the placement Id. */ @@ -253,12 +105,11 @@ public final class OEPlaceholderAtom extends RecordAtom{ } /** - * Sets the placement Id. - * <p> + * Sets the placement Id.<p> + * * The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders. * It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide. * The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape. - * </p> * * @param id the placement Id. */ @@ -267,12 +118,10 @@ public final class OEPlaceholderAtom extends RecordAtom{ } /** - * Returns the placeholder Id. + * Returns the placeholder Id.<p> * - * <p> * placeholder Id specifies the type of the placeholder shape. * The value MUST be one of the static constants defined in this class - * </p> * * @return the placeholder Id. */ @@ -281,12 +130,11 @@ public final class OEPlaceholderAtom extends RecordAtom{ } /** - * Sets the placeholder Id. + * Sets the placeholder Id.<p> * - * <p> * placeholder Id specifies the type of the placeholder shape. * The value MUST be one of the static constants defined in this class - * </p> + * * @param id the placeholder Id. */ public void setPlaceholderId(byte id){ @@ -314,10 +162,10 @@ public final class OEPlaceholderAtom extends RecordAtom{ } /** - * Write the contents of the record back, so it can be written - * to disk + * Write the contents of the record back, so it can be written to disk */ - public void writeOut(OutputStream out) throws IOException { + @Override + public void writeOut(OutputStream out) throws IOException { out.write(_header); byte[] recdata = new byte[8]; diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java index 16be0c6a80..9d553740bf 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtom.java @@ -20,23 +20,21 @@ package org.apache.poi.hslf.record; import java.io.IOException; import java.io.OutputStream; -import org.apache.poi.hslf.exceptions.HSLFException; +import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType; import org.apache.poi.util.LittleEndian; /** * A Slide Atom (type 1007). Holds information on the parent Slide, what - * Master Slide it uses, what Notes is attached to it, that sort of thing. - * It also has a SSlideLayoutAtom embeded in it, but without the Atom header - * - * @author Nick Burch + * Master Slide it uses, what Notes is attached to it, that sort of thing. + * It also has a SSlideLayoutAtom embedded in it, but without the Atom header */ -public final class SlideAtom extends RecordAtom -{ - private byte[] _header; +public final class SlideAtom extends RecordAtom { + public static final int USES_MASTER_SLIDE_ID = 0x80000000; + // private static final int MASTER_SLIDE_ID = 0x00000000; + + private byte[] _header; private static long _type = 1007l; - public static final int MASTER_SLIDE_ID = 0; - public static final int USES_MASTER_SLIDE_ID = -2147483648; private int masterID; private int notesID; @@ -44,7 +42,7 @@ public final class SlideAtom extends RecordAtom private boolean followMasterObjects; private boolean followMasterScheme; private boolean followMasterBackground; - private SSlideLayoutAtom layoutAtom; + private SlideAtomLayout layoutAtom; private byte[] reserved; @@ -54,8 +52,8 @@ public final class SlideAtom extends RecordAtom public void setMasterID(int id) { masterID = id; } /** Get the ID of the notes for this slide. 0 if doesn't have one */ public int getNotesID() { return notesID; } - /** Get the embeded SSlideLayoutAtom */ - public SSlideLayoutAtom getSSlideLayoutAtom() { return layoutAtom; } + /** Get the embedded SSlideLayoutAtom */ + public SlideAtomLayout getSSlideLayoutAtom() { return layoutAtom; } /** Change the ID of the notes for this slide. 0 if it no longer has one */ public void setNotesID(int id) { notesID = id; } @@ -85,7 +83,7 @@ public final class SlideAtom extends RecordAtom byte[] SSlideLayoutAtomData = new byte[12]; System.arraycopy(source,start+8,SSlideLayoutAtomData,0,12); // Use them to build up the SSlideLayoutAtom - layoutAtom = new SSlideLayoutAtom(SSlideLayoutAtomData); + layoutAtom = new SlideAtomLayout(SSlideLayoutAtomData); // Get the IDs of the master and notes masterID = LittleEndian.getInt(source,start+12+8); @@ -125,13 +123,13 @@ public final class SlideAtom extends RecordAtom LittleEndian.putInt(_header, 4, 24); byte[] ssdate = new byte[12]; - layoutAtom = new SSlideLayoutAtom(ssdate); - layoutAtom.setGeometryType(SSlideLayoutAtom.BLANK_SLIDE); + layoutAtom = new SlideAtomLayout(ssdate); + layoutAtom.setGeometryType(SlideLayoutType.BLANK_SLIDE); followMasterObjects = true; followMasterScheme = true; followMasterBackground = true; - masterID = -2147483648; + masterID = USES_MASTER_SLIDE_ID; // -2147483648; notesID = 0; reserved = new byte[2]; } @@ -168,70 +166,4 @@ public final class SlideAtom extends RecordAtom // Reserved data out.write(reserved); } - - - /** - * Holds the geometry of the Slide, and the ID of the placeholders - * on the slide. - * (Embeded inside SlideAtom is a SSlideLayoutAtom, without the - * usual record header. Since it's a fixed size and tied to - * the SlideAtom, we'll hold it here.) - */ - public static class SSlideLayoutAtom { - // The different kinds of geometry - public static final int TITLE_SLIDE = 0; - public static final int TITLE_BODY_SLIDE = 1; - public static final int TITLE_MASTER_SLIDE = 2; - public static final int MASTER_SLIDE = 3; - public static final int MASTER_NOTES = 4; - public static final int NOTES_TITLE_BODY = 5; - public static final int HANDOUT = 6; // Only header, footer and date placeholders - public static final int TITLE_ONLY = 7; - public static final int TITLE_2_COLUMN_BODY = 8; - public static final int TITLE_2_ROW_BODY = 9; - public static final int TITLE_2_COLUNM_RIGHT_2_ROW_BODY = 10; - public static final int TITLE_2_COLUNM_LEFT_2_ROW_BODY = 11; - public static final int TITLE_2_ROW_BOTTOM_2_COLUMN_BODY = 12; - public static final int TITLE_2_ROW_TOP_2_COLUMN_BODY = 13; - public static final int FOUR_OBJECTS = 14; - public static final int BIG_OBJECT = 15; - public static final int BLANK_SLIDE = 16; - public static final int VERTICAL_TITLE_BODY_LEFT = 17; - public static final int VERTICAL_TITLE_2_ROW_BODY_LEFT = 17; - - /** What geometry type we are */ - private int geometry; - /** What placeholder IDs we have */ - private byte[] placeholderIDs; - - /** Retrieve the geometry type */ - public int getGeometryType() { return geometry; } - /** Set the geometry type */ - public void setGeometryType(int geom) { geometry = geom; } - - /** - * Create a new Embeded SSlideLayoutAtom, from 12 bytes of data - */ - public SSlideLayoutAtom(byte[] data) { - if(data.length != 12) { - throw new HSLFException("SSlideLayoutAtom created with byte array not 12 bytes long - was " + data.length + " bytes in size"); - } - - // Grab out our data - geometry = LittleEndian.getInt(data,0); - placeholderIDs = new byte[8]; - System.arraycopy(data,4,placeholderIDs,0,8); - } - - /** - * Write the contents of the record back, so it can be written - * to disk. Skips the record header - */ - public void writeOut(OutputStream out) throws IOException { - // Write the geometry - writeLittleEndian(geometry,out); - // Write the placeholder IDs - out.write(placeholderIDs); - } - } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java new file mode 100644 index 0000000000..c6bd795757 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SlideAtomLayout.java @@ -0,0 +1,133 @@ +/* ==================================================================== + 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.hslf.exceptions.HSLFException; +import org.apache.poi.util.Internal; +import org.apache.poi.util.LittleEndian; + +/** + * Holds the geometry of the Slide, and the ID of the placeholders on the slide. + * Embedded inside a SlideAtom is a SlideAtomLayout, without the usual record header. + * Since it's a fixed size and tied to the SlideAtom, we'll hold it here.<p> + * + * This might eventually merged with the XSLF counterpart + */ +@Internal +public class SlideAtomLayout { + // The different kinds of geometry + public enum SlideLayoutType { + /** One title and one subtitle placeholder shapes. */ + TITLE_SLIDE(0x0000), + /** Presentation slide or main master slide layout with one title and one body placeholder shape. */ + TITLE_BODY(0x0001), + /** Title master slide layout with one title and one subtitle placeholder shape. */ + MASTER_TITLE(0x0002), + /** ??? (not documented in spec) */ + MASTER_SLIDE(0x0003), + /** ??? (not documented in spec) */ + MASTER_NOTES(0x0004), + /** ??? (not documented in spec) */ + NOTES_TITLE_BODY(0x0005), + /** Only header, footer and date placeholders */ + HANDOUT(0x0006), + /** Presentation slide layout with one title placeholder shape. */ + TITLE_ONLY(0x0007), + /** Presentation slide layout with one title and two body placeholder shapes stacked horizontally. */ + TWO_COLUMNS(0x0008), + /** Presentation slide layout with one title and two body placeholder shapes stacked vertically. */ + TWO_ROWS(0x0009), + /** Presentation slide layout with one title and three body placeholder shapes split into two columns. The right column has two rows. */ + COLUMN_TWO_ROWS(0x000A), + /** Presentation slide layout with one title and three body placeholder shapes split into two columns. The left column has two rows. */ + TWO_ROWS_COLUMN(0x000B), + /** ??? (not documented in spec) */ + TITLE_2_ROW_BOTTOM_2_COLUMN_BODY(0x000C), + /** Presentation slide layout with one title and three body placeholder shapes split into two rows. The top row has two columns. */ + TWO_COLUMNS_ROW(0x000D), + /** Presentation slide layout with one title and four body placeholder shapes. */ + FOUR_OBJECTS(0x000E), + /** Presentation slide layout with one body placeholder shape. */ + BIG_OBJECT(0x000F), + /** Presentation slide layout with no placeholder shape. */ + BLANK_SLIDE(0x0010), + /** Presentation slide layout with a vertical title placeholder shape on the right and a body placeholder shape on the left. */ + VERTICAL_TITLE_BODY(0x0011), + /** Presentation slide layout with a vertical title placeholder shape on the right and two body placeholder shapes in two columns on the left. */ + VERTICAL_TWO_ROWS(0x0012); + + private int nativeId; + SlideLayoutType(int nativeId) { + this.nativeId = nativeId; + } + + public int getNativeId() { + return nativeId; + } + + public static SlideLayoutType forNativeID(int nativeId) { + for (SlideLayoutType ans : values()) { + if (ans.nativeId == nativeId) { + return ans; + } + } + return null; + } + } + + /** What geometry type we are */ + private SlideLayoutType geometry; + /** What placeholder IDs we have */ + private byte[] placeholderIDs; + + /** Retrieve the geometry type */ + public SlideLayoutType getGeometryType() { return geometry; } + /** Set the geometry type */ + public void setGeometryType(SlideLayoutType geom) { geometry = geom; } + + /** + * Create a new Embedded SSlideLayoutAtom, from 12 bytes of data + */ + public SlideAtomLayout(byte[] data) { + if(data.length != 12) { + throw new HSLFException("SSlideLayoutAtom created with byte array not 12 bytes long - was " + data.length + " bytes in size"); + } + + // Grab out our data + geometry = SlideLayoutType.forNativeID(LittleEndian.getInt(data,0)); + placeholderIDs = new byte[8]; + System.arraycopy(data,4,placeholderIDs,0,8); + } + + /** + * Write the contents of the record back, so it can be written + * to disk. Skips the record header + */ + public void writeOut(OutputStream out) throws IOException { + // Write the geometry + byte[] buf = new byte[4]; + LittleEndian.putInt(buf, 0, geometry.getNativeId()); + out.write(buf); + // Write the placeholder IDs + out.write(placeholderIDs); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java index 238385b684..5291eb2fe3 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java @@ -42,15 +42,11 @@ import org.apache.poi.util.POILogger; * the style applies to, and what style elements make up the style (another * list, this time of TextProps). Each TextProp has a value, which somehow * encapsulates a property of the style - * - * @author Nick Burch - * @author Yegor Kozlov */ -public final class StyleTextPropAtom extends RecordAtom -{ +public final class StyleTextPropAtom extends RecordAtom { + public static final long _type = RecordTypes.StyleTextPropAtom.typeID; private byte[] _header; - private static final long _type = RecordTypes.StyleTextPropAtom.typeID; private byte[] reserved; private byte[] rawContents; // Holds the contents between write-outs diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java index 43a5abf8aa..0badc3e31d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java @@ -17,25 +17,23 @@ package org.apache.poi.hslf.record; +import java.io.IOException; +import java.io.OutputStream; + import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; -import java.io.IOException; -import java.io.OutputStream; /** * A TextBytesAtom (type 4008). Holds text in ascii form (unknown * code page, for now assumed to be the default of * org.apache.poi.util.StringUtil, which is the Excel default). * The trailing return character is always stripped from this - * - * @author Nick Burch */ -public final class TextBytesAtom extends RecordAtom -{ +public final class TextBytesAtom extends RecordAtom { + public static final long _type = RecordTypes.TextBytesAtom.typeID; private byte[] _header; - private static long _type = RecordTypes.TextBytesAtom.typeID; /** The bytes that make up the text */ private byte[] _text; @@ -87,13 +85,15 @@ public final class TextBytesAtom extends RecordAtom /** * We are of type 4008 */ - public long getRecordType() { return _type; } + @Override + public long getRecordType() { return _type; } /** * Write the contents of the record back, so it can be written * to disk */ - public void writeOut(OutputStream out) throws IOException { + @Override + public void writeOut(OutputStream out) throws IOException { // Header - size or type unchanged out.write(_header); @@ -105,7 +105,8 @@ public final class TextBytesAtom extends RecordAtom * dump debug info; use getText() to return a string * representation of the atom */ - public String toString() { + @Override + public String toString() { StringBuffer out = new StringBuffer(); out.append( "TextBytesAtom:\n"); out.append( HexDump.dump(_text, 0, 0) ); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java index 3449250ada..fa8ff836d1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextCharsAtom.java @@ -17,23 +17,21 @@ package org.apache.poi.hslf.record; +import java.io.IOException; +import java.io.OutputStream; + import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; -import java.io.IOException; -import java.io.OutputStream; /** * A TextCharsAtom (type 4000). Holds text in byte swapped unicode form. * The trailing return character is always stripped from this - * - * @author Nick Burch */ -public final class TextCharsAtom extends RecordAtom -{ +public final class TextCharsAtom extends RecordAtom { + public static final long _type = RecordTypes.TextCharsAtom.typeID; private byte[] _header; - private static long _type = RecordTypes.TextCharsAtom.typeID; /** The bytes that make up the text */ private byte[] _text; @@ -83,13 +81,15 @@ public final class TextCharsAtom extends RecordAtom /** * We are of type 4000 */ - public long getRecordType() { return _type; } + @Override + public long getRecordType() { return _type; } /** * Write the contents of the record back, so it can be written * to disk */ - public void writeOut(OutputStream out) throws IOException { + @Override + public void writeOut(OutputStream out) throws IOException { // Header - size or type unchanged out.write(_header); @@ -101,7 +101,8 @@ public final class TextCharsAtom extends RecordAtom * dump debug info; use getText() to return a string * representation of the atom */ - public String toString() { + @Override + public String toString() { StringBuffer out = new StringBuffer(); out.append( "TextCharsAtom:\n"); out.append( HexDump.dump(_text, 0, 0) ); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java index 2d4f41bddc..05c61a667d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java @@ -27,14 +27,11 @@ import org.apache.poi.util.LittleEndian; * A TextHeaderAtom (type 3999). Holds information on what kind of * text is contained in the TextBytesAtom / TextCharsAtom that follows * straight after - * - * @author Nick Burch */ -public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord -{ +public final class TextHeaderAtom extends RecordAtom implements ParentAwareRecord { + public static final long _type = RecordTypes.TextHeaderAtom.typeID; private byte[] _header; - private static long _type = RecordTypes.TextHeaderAtom.typeID; private RecordContainer parentRecord; public static final int TITLE_TYPE = 0; 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 5bfd3bbc9c..cc41706347 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java @@ -30,15 +30,14 @@ import org.apache.poi.ddf.EscherRecord; import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.record.CString; import org.apache.poi.hslf.record.ColorSchemeAtom; -import org.apache.poi.hslf.record.OEPlaceholderAtom; import org.apache.poi.hslf.record.PPDrawing; import org.apache.poi.hslf.record.RecordContainer; import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; import org.apache.poi.hslf.record.SheetContainer; import org.apache.poi.sl.draw.DrawFactory; 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.ShapeType; import org.apache.poi.sl.usermodel.Sheet; import org.apache.poi.util.Internal; @@ -108,6 +107,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H /** * Fetch the SlideShow we're attached to */ + @Override public HSLFSlideShow getSlideShow() { return _slideShow; } @@ -131,7 +131,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H _slideShow = ss; List<List<HSLFTextParagraph>> trs = getTextParagraphs(); - if (trs == null) return; + if (trs == null) { + return; + } for (List<HSLFTextParagraph> ltp : trs) { HSLFTextParagraph.supplySheet(ltp, this); HSLFTextParagraph.applyHyperlinks(ltp); @@ -192,6 +194,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H * * @param shape - the Shape to add */ + @Override public void addShape(HSLFShape shape) { PPDrawing ppdrawing = getPPDrawing(); @@ -226,8 +229,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H c.incrementShapeId(); dg.setNumShapes( dg.getNumShapes() + 1 ); dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) + if (result >= dgg.getShapeIdMax()) { dgg.setShapeIdMax( result + 1 ); + } return result; } } @@ -238,8 +242,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H dg.setNumShapes( dg.getNumShapes() + 1 ); int result = (1024 * dgg.getFileIdClusters().length); dg.setLastMSOSPID( result ); - if (result >= dgg.getShapeIdMax()) + if (result >= dgg.getShapeIdMax()) { dgg.setShapeIdMax( result + 1 ); + } return result; } @@ -249,6 +254,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H * @param shape shape to be removed from this sheet, if present. * @return <tt>true</tt> if the shape was deleted. */ + @Override public boolean removeShape(HSLFShape shape) { PPDrawing ppdrawing = getPPDrawing(); @@ -274,6 +280,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H /** * Return the master sheet . */ + @Override public abstract HSLFMasterSheet getMasterSheet(); /** @@ -288,6 +295,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H * * @return the background shape for this sheet. */ + @Override public HSLFBackground getBackground() { if (_background == null) { PPDrawing ppdrawing = getPPDrawing(); @@ -335,26 +343,17 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H } /** - * Search text placeholer by its type + * Search placeholder by its type * * @param type type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom} - * @return <code>TextShape</code> or <code>null</code> + * @return {@code SimpleShape} or {@code null} */ - public HSLFTextShape getPlaceholder(int type){ + public HSLFSimpleShape getPlaceholder(Placeholder type){ for (HSLFShape shape : getShapes()) { - if(shape instanceof HSLFTextShape){ - HSLFTextShape tx = (HSLFTextShape)shape; - int placeholderId = 0; - OEPlaceholderAtom oep = tx.getPlaceholderAtom(); - if(oep != null) { - placeholderId = oep.getPlaceholderId(); - } else { - //special case for files saved in Office 2007 - RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID); - if(hldr != null) placeholderId = hldr.getPlaceholderId(); - } - if(placeholderId == type){ - return tx; + if (shape instanceof HSLFSimpleShape) { + HSLFSimpleShape ss = (HSLFSimpleShape)shape; + if (type == ss.getPlaceholder()) { + return ss; } } } @@ -382,7 +381,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H progBinaryTag.findFirstOfType( RecordTypes.CString.typeID ); - if(binaryTag != null) tag = binaryTag.getText(); + if(binaryTag != null) { + tag = binaryTag.getText(); + } } } @@ -390,6 +391,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H } + @Override public Iterator<HSLFShape> iterator() { return getShapes().iterator(); } @@ -400,6 +402,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H * Sheets that support the notion of master (slide, slideLayout) should override it and * check this setting */ + @Override public boolean getFollowMasterGraphics() { return false; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java index 8618dbeb0e..dd98a017bf 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java @@ -42,6 +42,7 @@ import org.apache.poi.sl.draw.geom.PresetGeometries; 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.MasterSheet; import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.Placeholder; @@ -546,13 +547,40 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H if (clRecords == null) { return null; } + int phSource; + HSLFSheet sheet = getSheet(); + if (sheet instanceof HSLFSlideMaster) { + phSource = 1; + } else if (sheet instanceof HSLFNotes) { + phSource = 2; + } else if (sheet instanceof MasterSheet) { + // notes master aren't yet supported ... + phSource = 3; + } else { + phSource = 0; + } + for (Record r : clRecords) { + int phId; if (r instanceof OEPlaceholderAtom) { - OEPlaceholderAtom oep = (OEPlaceholderAtom)r; - return Placeholder.lookupNative(oep.getPlaceholderId()); + phId = ((OEPlaceholderAtom)r).getPlaceholderId(); } else if (r instanceof RoundTripHFPlaceholder12) { - RoundTripHFPlaceholder12 rtp = (RoundTripHFPlaceholder12)r; - return Placeholder.lookupNative(rtp.getPlaceholderId()); + //special case for files saved in Office 2007 + phId = ((RoundTripHFPlaceholder12)r).getPlaceholderId(); + } else { + continue; + } + + switch (phSource) { + case 0: + return Placeholder.lookupNativeSlide(phId); + default: + case 1: + return Placeholder.lookupNativeSlideMaster(phId); + case 2: + return Placeholder.lookupNativeNotes(phId); + case 3: + return Placeholder.lookupNativeNotesMaster(phId); } } 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 a37b7abbca..2a3e4fae1b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlide.java @@ -36,6 +36,7 @@ import org.apache.poi.hslf.record.RecordContainer; import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.SSSlideInfoAtom; import org.apache.poi.hslf.record.SlideAtom; +import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.StyleTextProp9Atom; import org.apache.poi.hslf.record.TextHeaderAtom; @@ -501,4 +502,27 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTe public boolean getFollowMasterGraphics() { return getFollowMasterObjects(); } + + @Override + public boolean getDisplayPlaceholder(Placeholder placeholder) { + HeadersFooters hf = getHeadersFooters(); + SlideLayoutType slt = getSlideRecord().getSlideAtom().getSSlideLayoutAtom().getGeometryType(); + boolean isTitle = + (slt == SlideLayoutType.TITLE_SLIDE || slt == SlideLayoutType.TITLE_ONLY || slt == SlideLayoutType.MASTER_TITLE); + if (hf != null) { + switch (placeholder) { + case DATETIME: + return hf.isDateTimeVisible() && !isTitle; + case SLIDE_NUMBER: + return hf.isSlideNumberVisible() && !isTitle; + case HEADER: + return hf.isHeaderVisible() && !isTitle; + case FOOTER: + return hf.isFooterVisible() && !isTitle; + default: + break; + } + } + return false; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java index 9b5668ffee..7919dc2c06 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java @@ -23,7 +23,9 @@ import java.util.List; import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.model.textproperties.TextProp; import org.apache.poi.hslf.model.textproperties.TextPropCollection; -import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.record.MainMaster; +import org.apache.poi.hslf.record.TextHeaderAtom; +import org.apache.poi.hslf.record.TxMasterStyleAtom; import org.apache.poi.util.Internal; /** @@ -49,13 +51,16 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { super(record, sheetNo); for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); + if (!_paragraphs.contains(l)) { + _paragraphs.add(l); + } } } /** * Returns an array of all the TextRuns found */ + @Override public List<List<HSLFTextParagraph>> getTextParagraphs() { return _paragraphs; } @@ -63,6 +68,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { /** * Returns <code>null</code> since SlideMasters doen't have master sheet. */ + @Override public HSLFMasterSheet getMasterSheet() { return null; } @@ -71,8 +77,11 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { * Pickup a style attribute from the master. * This is the "workhorse" which returns the default style attributes. */ + @Override public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { - if (_txmaster.length <= txtype) return null; + if (_txmaster.length <= txtype) { + return null; + } TxMasterStyleAtom t = _txmaster[txtype]; List<TextPropCollection> styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles(); @@ -81,7 +90,9 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { prop = styles.get(i).findByName(name); } - if (prop != null) return prop; + if (prop != null) { + return prop; + } switch (txtype) { case TextHeaderAtom.CENTRE_BODY_TYPE: @@ -146,6 +157,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet { } } + @Override protected void onAddTextShape(HSLFTextShape shape) { List<HSLFTextParagraph> runs = shape.getTextParagraphs(); _paragraphs.add(runs); 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 60232d50a7..afe5d71264 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java @@ -36,14 +36,35 @@ import org.apache.poi.hslf.model.textproperties.TextPFException9; import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.record.EscherTextboxWrapper;
+import org.apache.poi.hslf.record.FontCollection;
+import org.apache.poi.hslf.record.InteractiveInfo;
+import org.apache.poi.hslf.record.MasterTextPropAtom;
+import org.apache.poi.hslf.record.OutlineTextRefAtom;
+import org.apache.poi.hslf.record.PPDrawing;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordContainer;
+import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
+import org.apache.poi.hslf.record.SlideListWithText;
+import org.apache.poi.hslf.record.SlidePersistAtom;
+import org.apache.poi.hslf.record.StyleTextProp9Atom;
+import org.apache.poi.hslf.record.StyleTextPropAtom;
+import org.apache.poi.hslf.record.TextBytesAtom;
+import org.apache.poi.hslf.record.TextCharsAtom;
+import org.apache.poi.hslf.record.TextHeaderAtom;
+import org.apache.poi.hslf.record.TextRulerAtom;
+import org.apache.poi.hslf.record.TextSpecInfoAtom;
+import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
+import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.util.Internal;
-import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;
@@ -53,8 +74,6 @@ import org.apache.poi.util.Units; * This class represents a run of text in a powerpoint document. That
* run could be text on a sheet, or text in a note.
* It is only a very basic class for now
- *
- * @author Nick Burch
*/
public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFTextParagraph,HSLFTextRun> {
@@ -74,6 +93,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText private TextBytesAtom _byteAtom;
private TextCharsAtom _charAtom;
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
+ private TextPropCollection _masterStyle;
protected TextRulerAtom _ruler;
protected final List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
@@ -139,7 +159,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText public void setParagraphStyle(TextPropCollection paragraphStyle) {
_paragraphStyle.copy(paragraphStyle);
}
-
+
/**
* Setting a master style reference
*
@@ -148,8 +168,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * @since POI 3.14-Beta1
*/
@Internal
- /* package */ void setMasterStyleReference(TextPropCollection paragraphStyle) {
- _paragraphStyle = paragraphStyle;
+ /* package */ void setMasterStyleReference(TextPropCollection masterStyle) {
+ _masterStyle = masterStyle;
}
/**
@@ -321,8 +341,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText @Override
public Double getLeftMargin() {
- TextProp val = getPropVal(_paragraphStyle, "text.offset", this);
- return (val == null) ? null : Units.masterToPoints(val.getValue());
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "text.offset");
+ return (tp == null) ? null : Units.masterToPoints(tp.getValue());
}
@Override
@@ -344,8 +364,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText @Override
public Double getIndent() {
- TextProp val = getPropVal(_paragraphStyle, "bullet.offset", this);
- return (val == null) ? null : Units.masterToPoints(val.getValue());
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.offset");
+ return (tp == null) ? null : Units.masterToPoints(tp.getValue());
}
@Override
@@ -393,7 +413,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText @Override
public TextAlign getTextAlign() {
- TextProp tp = getPropVal(_paragraphStyle, "alignment", this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "alignment");
if (tp == null) {
return null;
}
@@ -411,7 +431,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText @Override
public FontAlign getFontAlign() {
- TextProp tp = getPropVal(_paragraphStyle, FontAlignmentProp.NAME, this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, FontAlignmentProp.NAME);
if (tp == null) {
return null;
}
@@ -577,7 +597,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * Returns the bullet character
*/
public Character getBulletChar() {
- TextProp tp = getPropVal(_paragraphStyle, "bullet.char", this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.char");
return (tp == null) ? null : (char)tp.getValue();
}
@@ -608,7 +628,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * Returns the bullet color
*/
public Color getBulletColor() {
- TextProp tp = getPropVal(_paragraphStyle, "bullet.color", this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.color");
boolean hasColor = getFlag(ParagraphFlagsTextProp.BULLET_HARDCOLOR_IDX);
if (tp == null || !hasColor) {
// if bullet color is undefined, return color of first run
@@ -632,8 +652,9 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText */
public void setBulletFont(String typeface) {
if (typeface == null) {
- setPropVal(_paragraphStyle, "bullet.font", null);
+ setPropVal(_paragraphStyle, _masterStyle, "bullet.font", null);
setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, false);
+ return;
}
FontCollection fc = getSheet().getSlideShow().getFontCollection();
@@ -647,7 +668,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * Returns the bullet font
*/
public String getBulletFont() {
- TextProp tp = getPropVal(_paragraphStyle, "bullet.font", this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.font");
boolean hasFont = getFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX);
if (tp == null || !hasFont) {
return getDefaultFontFamily();
@@ -694,7 +715,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText }
private Double getPctOrPoints(String propName) {
- TextProp tp = getPropVal(_paragraphStyle, propName, this);
+ TextProp tp = getPropVal(_paragraphStyle, _masterStyle, propName);
if (tp == null) {
return null;
}
@@ -711,7 +732,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText }
private boolean getFlag(int index) {
- BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, ParagraphFlagsTextProp.NAME, this);
+ BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, _masterStyle, ParagraphFlagsTextProp.NAME);
return (tp == null) ? false : tp.getSubValue(index);
}
@@ -729,7 +750,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * The propName can be a comma-separated list, in case multiple equivalent values
* are queried
*/
- protected static TextProp getPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) {
+ protected TextProp getPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {
String propNames[] = propName.split(",");
for (String pn : propNames) {
TextProp prop = props.findByName(pn);
@@ -740,41 +761,52 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText // Font properties (maybe other too???) can have an index of -1
// so we check the master for this font index then
if (pn.contains("font") && prop.getValue() == -1) {
- return getMasterPropVal(props, pn, paragraph);
+ return getMasterPropVal(props, masterProps, pn);
}
return prop;
}
- return getMasterPropVal(props, propName, paragraph);
+ return getMasterPropVal(props, masterProps, propName);
}
- private static TextProp getMasterPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) {
- String propNames[] = propName.split(",");
-
- BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);
- boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
- if (hardAttribute) {
- return null;
- }
+ private TextProp getMasterPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {
+ boolean isChar = props.getTextPropType() == TextPropType.character;
- HSLFSheet sheet = paragraph.getSheet();
- int txtype = paragraph.getRunType();
- HSLFMasterSheet master = sheet.getMasterSheet();
- if (master == null) {
- logger.log(POILogger.WARN, "MasterSheet is not available");
- return null;
+ // check if we can delegate to master for the property
+ if (!isChar) {
+ BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);
+ boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
+ if (hardAttribute) {
+ return null;
+ }
}
- boolean isChar = props.getTextPropType() == TextPropType.character;
+ String propNames[] = propName.split(",");
+ if (masterProps == null) {
+ HSLFSheet sheet = getSheet();
+ int txtype = getRunType();
+ HSLFMasterSheet master = sheet.getMasterSheet();
+ if (master == null) {
+ logger.log(POILogger.WARN, "MasterSheet is not available");
+ return null;
+ }
- for (String pn : propNames) {
- TextProp prop = master.getStyleAttribute(txtype, paragraph.getIndentLevel(), pn, isChar);
- if (prop != null) {
- return prop;
+ for (String pn : propNames) {
+ TextProp prop = master.getStyleAttribute(txtype, getIndentLevel(), pn, isChar);
+ if (prop != null) {
+ return prop;
+ }
+ }
+ } else {
+ for (String pn : propNames) {
+ TextProp prop = masterProps.findByName(pn);
+ if (prop != null) {
+ return prop;
+ }
}
}
-
+
return null;
}
@@ -786,14 +818,19 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * @param name the name of the TextProp to fetch/add
* @param val the value, null if unset
*/
- protected static void setPropVal(TextPropCollection props, String name, Integer val) {
+ protected void setPropVal(TextPropCollection props, TextPropCollection masterProps, String name, Integer val) {
+ TextPropCollection pc = props;
+ if (getSheet() instanceof MasterSheet && masterProps != null) {
+ pc = masterProps;
+ }
+
if (val == null) {
- props.removeByName(name);
+ pc.removeByName(name);
return;
}
// Fetch / Add the TextProp
- TextProp tp = props.addWithName(name);
+ TextProp tp = pc.addWithName(name);
tp.setValue(val);
}
@@ -1517,38 +1554,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText }
}
- protected static List<HSLFTextParagraph> createEmptyParagraph() {
- EscherTextboxWrapper wrapper = new EscherTextboxWrapper();
- return createEmptyParagraph(wrapper);
- }
-
- protected static List<HSLFTextParagraph> createEmptyParagraph(EscherTextboxWrapper wrapper) {
- TextHeaderAtom tha = new TextHeaderAtom();
- tha.setParentRecord(wrapper);
- wrapper.appendChildRecord(tha);
-
- TextBytesAtom tba = new TextBytesAtom();
- tba.setText("".getBytes(LocaleUtil.CHARSET_1252));
- wrapper.appendChildRecord(tba);
-
- StyleTextPropAtom sta = new StyleTextPropAtom(1);
- TextPropCollection paraStyle = sta.addParagraphTextPropCollection(1);
- TextPropCollection charStyle = sta.addCharacterTextPropCollection(1);
- wrapper.appendChildRecord(sta);
-
- List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>(1);
- HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, paragraphs);
- htp.setParagraphStyle(paraStyle);
- paragraphs.add(htp);
-
- HSLFTextRun htr = new HSLFTextRun(htp);
- htr.setCharacterStyle(charStyle);
- htr.setText("");
- htp.addTextRun(htr);
-
- return paragraphs;
- }
-
public EscherTextboxWrapper getTextboxWrapper() {
return (EscherTextboxWrapper) _headerAtom.getParentRecord();
}
@@ -1583,7 +1588,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText * @param val The value to set for the TextProp
*/
public void setParagraphTextPropVal(String propName, Integer val) {
- setPropVal(_paragraphStyle, propName, val);
+ setPropVal(_paragraphStyle, _masterStyle, propName, val);
setDirty();
}
@@ -1624,21 +1629,19 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText */
@Override
public boolean isHeaderOrFooter() {
- HSLFShape s = getParentShape();
+ HSLFTextShape s = getParentShape();
if (s == null) {
return false;
}
- RoundTripHFPlaceholder12 hfPl = s.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
- if (hfPl == null) {
+ Placeholder ph = s.getPlaceholder();
+ if (ph == null) {
return false;
}
-
- int plId = hfPl.getPlaceholderId();
- switch (plId) {
- case OEPlaceholderAtom.MasterDate:
- case OEPlaceholderAtom.MasterSlideNumber:
- case OEPlaceholderAtom.MasterFooter:
- case OEPlaceholderAtom.MasterHeader:
+ switch (ph) {
+ case DATETIME:
+ case SLIDE_NUMBER:
+ case FOOTER:
+ case HEADER:
return true;
default:
return false;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java index 427e2d2c5e..fb0b60e44a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java @@ -17,8 +17,6 @@ package org.apache.poi.hslf.usermodel; -import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.getPropVal; - import java.awt.Color; import org.apache.poi.hslf.exceptions.HSLFException; @@ -30,6 +28,7 @@ import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; 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.Placeholder; import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; @@ -54,6 +53,8 @@ public final class HSLFTextRun implements TextRun { * Note - we may share these styles with other RichTextRuns */ private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character); + + private TextPropCollection masterStyle; /** * Create a new wrapper around a rich text string @@ -80,8 +81,8 @@ public final class HSLFTextRun implements TextRun { * @since POI 3.14-Beta1 */ @Internal - /* package */ void setMasterStyleReference(TextPropCollection characterStyle) { - this.characterStyle = characterStyle; + /* package */ void setMasterStyleReference(TextPropCollection masterStyle) { + this.masterStyle = masterStyle; } @@ -105,14 +106,16 @@ public final class HSLFTextRun implements TextRun { /** * Fetch the text, in raw storage form */ - public String getRawText() { + @Override + public String getRawText() { return _runText; } /** * Change the text */ - public void setText(String text) { + @Override + public void setText(String text) { if (text == null) { throw new HSLFException("text must not be null"); } @@ -137,7 +140,9 @@ public final class HSLFTextRun implements TextRun { } protected boolean getFlag(int index) { - if (characterStyle == null) return false; + if (characterStyle == null) { + return false; + } BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME); @@ -175,8 +180,8 @@ public final class HSLFTextRun implements TextRun { * @param val The value to set for the TextProp */ public void setCharTextPropVal(String propName, Integer val) { - HSLFTextParagraph.setPropVal(characterStyle, propName, val); - parentParagraph.setDirty(); + getTextParagraph().setPropVal(characterStyle, masterStyle, propName, val); + getTextParagraph().setDirty(); } @@ -256,7 +261,7 @@ public final class HSLFTextRun implements TextRun { * @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript */ public int getSuperscript() { - TextProp tp = getPropVal(characterStyle, "superscript", parentParagraph); + TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "superscript"); return tp == null ? 0 : tp.getValue(); } @@ -271,7 +276,7 @@ public final class HSLFTextRun implements TextRun { @Override public Double getFontSize() { - TextProp tp = getPropVal(characterStyle, "font.size", parentParagraph); + TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.size"); return tp == null ? null : (double)tp.getValue(); } @@ -286,7 +291,7 @@ public final class HSLFTextRun implements TextRun { * Gets the font index */ public int getFontIndex() { - TextProp tp = getPropVal(characterStyle, "font.index", parentParagraph); + TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.index"); return tp == null ? -1 : tp.getValue(); } @@ -320,7 +325,7 @@ public final class HSLFTextRun implements TextRun { if (sheet == null || slideShow == null) { return _fontFamily; } - TextProp tp = getPropVal(characterStyle, "font.index,asian.font.index,ansi.font.index,symbol.font.index", parentParagraph); + TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.index,asian.font.index,ansi.font.index,symbol.font.index"); if (tp == null) { return null; } return slideShow.getFontCollection().getFontWithId(tp.getValue()); } @@ -330,8 +335,10 @@ public final class HSLFTextRun implements TextRun { */ @Override public SolidPaint getFontColor() { - TextProp tp = getPropVal(characterStyle, "font.color", parentParagraph); - if (tp == null) return null; + TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.color"); + if (tp == null) { + return null; + } Color color = HSLFTextParagraph.getColorFromColorIndexStruct(tp.getValue(), parentParagraph.getSheet()); SolidPaint ps = DrawPaint.createSolidPaint(color); return ps; @@ -374,6 +381,7 @@ public final class HSLFTextRun implements TextRun { return parentParagraph; } + @Override public TextCap getTextCap() { return TextCap.NONE; } @@ -388,6 +396,7 @@ public final class HSLFTextRun implements TextRun { return getSuperscript() > 0; } + @Override public byte getPitchAndFamily() { return 0; } @@ -414,4 +423,20 @@ public final class HSLFTextRun implements TextRun { } return link; } + + @Override + public FieldType getFieldType() { + Placeholder ph = getTextParagraph().getParentShape().getPlaceholder(); + if (ph != null) { + switch (ph) { + case SLIDE_NUMBER: + return FieldType.SLIDE_NUMBER; + case DATETIME: + return FieldType.DATE_TIME; + default: + break; + } + } + return null; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java index 2af4c07887..4992d1bd45 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java @@ -20,7 +20,6 @@ package org.apache.poi.hslf.usermodel; import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom; import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12; -import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.ArrayList; @@ -34,10 +33,14 @@ import org.apache.poi.ddf.EscherSimpleProperty; import org.apache.poi.ddf.EscherTextboxRecord; import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.model.HSLFMetroShape; +import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.record.EscherTextboxWrapper; import org.apache.poi.hslf.record.OEPlaceholderAtom; import org.apache.poi.hslf.record.PPDrawing; import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; +import org.apache.poi.hslf.record.StyleTextPropAtom; +import org.apache.poi.hslf.record.TextBytesAtom; +import org.apache.poi.hslf.record.TextCharsAtom; import org.apache.poi.hslf.record.TextHeaderAtom; import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawTextShape; @@ -71,12 +74,12 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { BOTTOM_BASELINE (7, VerticalAlignment.BOTTOM, false, true), TOP_CENTER_BASELINE (8, VerticalAlignment.TOP, true, true), BOTTOM_CENTER_BASELINE(9, VerticalAlignment.BOTTOM, true, true); - + public final int nativeId; public final VerticalAlignment vAlign; public final boolean centered; public final Boolean baseline; - + HSLFTextAnchor(int nativeId, VerticalAlignment vAlign, boolean centered, Boolean baseline) { this.nativeId = nativeId; this.vAlign = vAlign; @@ -86,7 +89,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { static HSLFTextAnchor fromNativeId(int nativeId) { for (HSLFTextAnchor ta : values()) { - if (ta.nativeId == nativeId) return ta; + if (ta.nativeId == nativeId) { + return ta; + } } return null; } @@ -125,13 +130,13 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { /** * TextRun object which holds actual text and format data */ - protected List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>(); + private List<HSLFTextParagraph> _paragraphs = new ArrayList<HSLFTextParagraph>(); /** * Escher container which holds text attributes such as - * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc. + * TextHeaderAtom, TextBytesAtom or TextCharsAtom, StyleTextPropAtom etc. */ - protected EscherTextboxWrapper _txtbox; + private EscherTextboxWrapper _txtbox; /** * This setting is used for supporting a deprecated alignment @@ -141,11 +146,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { // boolean alignToBaseline = false; /** - * Used to calculate text bounds - */ - protected static final FontRenderContext _frc = new FontRenderContext(null, true, true); - - /** * Create a TextBox object and initialize it from the supplied Record container. * * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape @@ -222,10 +222,14 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { } protected EscherTextboxWrapper getEscherTextboxWrapper(){ - if(_txtbox != null) return _txtbox; + if(_txtbox != null) { + return _txtbox; + } EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID); - if (textRecord == null) return null; + if (textRecord == null) { + return null; + } HSLFSheet sheet = getSheet(); if (sheet != null) { @@ -248,6 +252,66 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { return _txtbox; } + private void createEmptyParagraph() { + TextHeaderAtom tha = (TextHeaderAtom)_txtbox.findFirstOfType(TextHeaderAtom._type); + if (tha == null) { + tha = new TextHeaderAtom(); + tha.setParentRecord(_txtbox); + _txtbox.appendChildRecord(tha); + } + + TextBytesAtom tba = (TextBytesAtom)_txtbox.findFirstOfType(TextBytesAtom._type); + TextCharsAtom tca = (TextCharsAtom)_txtbox.findFirstOfType(TextCharsAtom._type); + if (tba == null && tca == null) { + tba = new TextBytesAtom(); + tba.setText(new byte[0]); + _txtbox.appendChildRecord(tba); + } + + final String text = ((tba != null) ? tba.getText() : tca.getText()); + + StyleTextPropAtom sta = (StyleTextPropAtom)_txtbox.findFirstOfType(StyleTextPropAtom._type); + TextPropCollection paraStyle = null, charStyle = null; + if (sta == null) { + int parSiz = text.length(); + sta = new StyleTextPropAtom(parSiz+1); + if (_paragraphs.isEmpty()) { + paraStyle = sta.addParagraphTextPropCollection(parSiz+1); + charStyle = sta.addCharacterTextPropCollection(parSiz+1); + } else { + for (HSLFTextParagraph htp : _paragraphs) { + int runsLen = 0; + for (HSLFTextRun htr : htp.getTextRuns()) { + runsLen += htr.getLength(); + charStyle = sta.addCharacterTextPropCollection(htr.getLength()); + htr.setCharacterStyle(charStyle); + } + paraStyle = sta.addParagraphTextPropCollection(runsLen); + htp.setParagraphStyle(paraStyle); + } + assert (paraStyle != null && charStyle != null); + } + _txtbox.appendChildRecord(sta); + } else { + paraStyle = sta.getParagraphStyles().get(0); + charStyle = sta.getCharacterStyles().get(0); + } + + if (_paragraphs.isEmpty()) { + HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, tca, _paragraphs); + htp.setParagraphStyle(paraStyle); + htp.setParentShape(this); + _paragraphs.add(htp); + + HSLFTextRun htr = new HSLFTextRun(htp); + htr.setCharacterStyle(charStyle); + htr.setText(text); + htp.addTextRun(htr); + } + } + + + /** * Adjust the size of the shape so it encompasses the text inside it. * @@ -276,7 +340,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { */ public int getRunType() { getEscherTextboxWrapper(); - if (_txtbox == null) return -1; + if (_txtbox == null) { + return -1; + } List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); return (paras.isEmpty()) ? -1 : paras.get(0).getRunType(); } @@ -289,7 +355,9 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { */ public void setRunType(int type) { getEscherTextboxWrapper(); - if (_txtbox == null) return; + if (_txtbox == null) { + return; + } List<HSLFTextParagraph> paras = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); if (!paras.isEmpty()) { paras.get(0).setRunType(type); @@ -562,19 +630,23 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { @Override public List<HSLFTextParagraph> getTextParagraphs(){ - if (!_paragraphs.isEmpty()) return _paragraphs; + if (!_paragraphs.isEmpty()) { + return _paragraphs; + } _txtbox = getEscherTextboxWrapper(); if (_txtbox == null) { - _paragraphs.addAll(HSLFTextParagraph.createEmptyParagraph()); - _txtbox = _paragraphs.get(0).getTextboxWrapper(); + _txtbox = new EscherTextboxWrapper(); + createEmptyParagraph(); } else { - _paragraphs = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); - if (_paragraphs == null) { + List<HSLFTextParagraph> pList = HSLFTextParagraph.findTextParagraphs(_txtbox, getSheet()); + if (pList == null) { // there are actually TextBoxRecords without extra data - see #54722 - _paragraphs = HSLFTextParagraph.createEmptyParagraph(_txtbox); + createEmptyParagraph(); + } else { + _paragraphs = pList; } - + if (_paragraphs.isEmpty()) { LOG.log(POILogger.WARN, "TextRecord didn't contained any text lines"); } @@ -587,6 +659,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { return _paragraphs; } + @Override public void setSheet(HSLFSheet sheet) { super.setSheet(sheet); @@ -611,26 +684,30 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { /** * 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 + * {@link Placeholder#HEADER} or {@link Placeholder#FOOTER}, 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); } - + @Override public boolean isPlaceholder() { OEPlaceholderAtom oep = getPlaceholderAtom(); - if (oep != null) return true; + if (oep != null) { + return true; + } //special case for files saved in Office 2007 RoundTripHFPlaceholder12 hldr = getHFPlaceholderAtom(); - if (hldr != null) return true; + if (hldr != null) { + return true; + } return false; } @@ -710,7 +787,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { } setEscherProperty(opt, EscherProperties.TEXT__TEXTFLOW, msotxfl); } - + @Override public Double getTextRotation() { // see 2.4.6 MSOCDIR @@ -718,7 +795,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__FONTROTATION); return (prop == null) ? null : (90. * prop.getPropertyValue()); } - + @Override public void setTextRotation(Double rotation) { AbstractEscherOptRecord opt = getEscherOptRecord(); @@ -729,7 +806,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { setEscherProperty(EscherProperties.TEXT__FONTROTATION, rot); } } - + /** * Returns the raw text content of the shape. This hasn't had any * changes applied to it, and so is probably unlikely to print @@ -751,7 +828,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { List<HSLFTextParagraph> paras = getTextParagraphs(); HSLFTextRun htr = HSLFTextParagraph.appendText(paras, text, newParagraph); setTextId(getRawText().hashCode()); - return htr; + return htr; } @Override diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java index b1e38d977b..2dfd3b05b6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java @@ -25,8 +25,6 @@ import org.apache.poi.hslf.record.SlideAtom; /** * Title masters define the design template for slides with a Title Slide layout. - * - * @author Yegor Kozlov */ public final class HSLFTitleMaster extends HSLFMasterSheet { private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>(); @@ -39,13 +37,16 @@ public final class HSLFTitleMaster extends HSLFMasterSheet { super(record, sheetNo); for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { - if (!_paragraphs.contains(l)) _paragraphs.add(l); + if (!_paragraphs.contains(l)) { + _paragraphs.add(l); + } } } /** * Returns an array of all the TextRuns found */ + @Override public List<List<HSLFTextParagraph>> getTextParagraphs() { return _paragraphs; } @@ -53,20 +54,23 @@ public final class HSLFTitleMaster extends HSLFMasterSheet { /** * Delegate the call to the underlying slide master. */ + @Override public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { HSLFMasterSheet master = getMasterSheet(); - return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter); + return (master == null) ? null : master.getStyleAttribute(txtype, level, name, isCharacter); } /** * Returns the slide master for this title master. */ + @Override public HSLFMasterSheet getMasterSheet(){ - List<HSLFSlideMaster> master = getSlideShow().getSlideMasters(); SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom(); int masterId = sa.getMasterID(); - for (HSLFSlideMaster sm : master) { - if (masterId == sm._getSheetNumber()) return sm; + for (HSLFSlideMaster sm : getSlideShow().getSlideMasters()) { + if (masterId == sm._getSheetNumber()) { + return sm; + } } return null; } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java index 7e6137ba47..c32d37bd65 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSlideAtom.java @@ -17,36 +17,43 @@ package org.apache.poi.hslf.record; -import java.io.ByteArrayInputStream; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayOutputStream; +import java.io.IOException; -import org.apache.poi.hslf.record.SlideAtom.SSlideLayoutAtom; +import org.apache.poi.hslf.HSLFTestDataSamples; +import org.apache.poi.hslf.record.SlideAtomLayout.SlideLayoutType; +import org.apache.poi.hslf.usermodel.HSLFSlide; import org.apache.poi.hslf.usermodel.HSLFSlideShow; - -import junit.framework.TestCase; +import org.junit.Test; /** * Tests that SlideAtom works properly - * - * @author Nick Burch (nick at torchbox dot com) */ -public final class TestSlideAtom extends TestCase { +public final class TestSlideAtom { // From a real file - private final byte[] data_a = new byte[] { 1, 0, 0xEF-256, 3, 0x18, 0, 0, 0, + private static final byte[] data_a = new byte[] { 1, 0, 0xEF-256, 3, 0x18, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80-256, 0, 1, 0, 0, 7, 0, 0x0C, 0x30 }; - public void testRecordType() { + @Test + public void testRecordType() { SlideAtom sa = new SlideAtom(data_a, 0, data_a.length); assertEquals(1007l, sa.getRecordType()); } + + @Test public void testFlags() { SlideAtom sa = new SlideAtom(data_a, 0, data_a.length); // First 12 bytes are a SSlideLayoutAtom, checked elsewhere // Check the IDs - assertEquals(0x80000000, sa.getMasterID()); + assertEquals(SlideAtom.USES_MASTER_SLIDE_ID, sa.getMasterID()); assertEquals(256, sa.getNotesID()); // Check the flags @@ -54,39 +61,37 @@ public final class TestSlideAtom extends TestCase { assertEquals(true, sa.getFollowMasterScheme()); assertEquals(true, sa.getFollowMasterBackground()); } - public void testSSlideLayoutAtom() { + + @Test + public void testSSlideLayoutAtom() { SlideAtom sa = new SlideAtom(data_a, 0, data_a.length); - SSlideLayoutAtom ssla = sa.getSSlideLayoutAtom(); + SlideAtomLayout ssla = sa.getSSlideLayoutAtom(); - assertEquals(0, ssla.getGeometryType()); + assertEquals(SlideLayoutType.TITLE_SLIDE, ssla.getGeometryType()); - // Should also check the placehold IDs at some point + // Should also check the placeholder IDs at some point } - public void testWrite() throws Exception { + @Test + public void testWrite() throws IOException { SlideAtom sa = new SlideAtom(data_a, 0, data_a.length); ByteArrayOutputStream baos = new ByteArrayOutputStream(); sa.writeOut(baos); - byte[] b = baos.toByteArray(); - - assertEquals(data_a.length, b.length); - for(int i=0; i<data_a.length; i++) { - assertEquals(data_a[i],b[i]); - } + assertArrayEquals(data_a, baos.toByteArray()); } - public void testSSSlideInfoAtom() throws Exception { - HSLFSlideShow ss = new HSLFSlideShow(); - org.apache.poi.hslf.usermodel.HSLFSlide slide1 = ss.createSlide(), slide2 = ss.createSlide(); + @Test + public void testSSSlideInfoAtom() throws IOException { + HSLFSlideShow ss1 = new HSLFSlideShow(); + HSLFSlide slide1 = ss1.createSlide(), slide2 = ss1.createSlide(); slide2.setHidden(true); - ByteArrayOutputStream bos = new ByteArrayOutputStream(4096); - ss.write(bos); - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - ss = new HSLFSlideShow(bis); - slide1 = ss.getSlides().get(0); - slide2 = ss.getSlides().get(1); + HSLFSlideShow ss2 = HSLFTestDataSamples.writeOutAndReadBack(ss1); + slide1 = ss2.getSlides().get(0); + slide2 = ss2.getSlides().get(1); assertFalse(slide1.getHidden()); assertTrue(slide2.getHidden()); + ss2.close(); + ss1.close(); } } 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 8b340079d3..df99363dcc 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -38,6 +38,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator.Attribute; +import java.text.CharacterIterator; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -466,12 +467,16 @@ public final class TestBugs { // get slides for (HSLFSlide slide : ppt.getSlides()) { for (HSLFShape shape : slide.getShapes()) { - if (!(shape instanceof HSLFTextBox)) continue; + if (!(shape instanceof HSLFTextBox)) { + continue; + } HSLFTextBox tb = (HSLFTextBox) shape; // work with TextBox String str = tb.getText(); - if (!str.contains("$$DATE$$")) continue; + if (!str.contains("$$DATE$$")) { + continue; + } str = str.replace("$$DATE$$", new Date().toString()); tb.setText(str); @@ -512,7 +517,9 @@ public final class TestBugs { int tha = 0; for (Record r : s1.getSlideRecords()) { - if (r instanceof TextHeaderAtom) tha++; + if (r instanceof TextHeaderAtom) { + tha++; + } } assertEquals(2, tha); @@ -525,7 +532,9 @@ public final class TestBugs { // Will have skipped the empty one int str = 0; for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) { - if (! tr.get(0).isDrawingBased()) str++; + if (! tr.get(0).isDrawingBased()) { + str++; + } } assertEquals(2, str); @@ -758,7 +767,7 @@ public final class TestBugs { public void bug47904() throws IOException { HSLFSlideShow ppt1 = new HSLFSlideShow(); HSLFSlideMaster sm = ppt1.getSlideMasters().get(0); - HSLFAutoShape as = (HSLFAutoShape)sm.getShapes().get(0); + HSLFAutoShape as = (HSLFAutoShape)sm.getPlaceholder(Placeholder.TITLE); HSLFTextParagraph tp = as.getTextParagraphs().get(0); HSLFTextRun tr = tp.getTextRuns().get(0); tr.setFontFamily("Tahoma"); @@ -766,8 +775,9 @@ public final class TestBugs { tr.setFontSize(44.); tr.setFontColor(Color.red); tp.setTextAlign(TextAlign.RIGHT); - ppt1.createSlide().addTitle().setText("foobaa"); - + HSLFTextBox tb = ppt1.createSlide().addTitle(); + tb.setText("foobaa"); + HSLFSlideShow ppt2 = HSLFTestDataSamples.writeOutAndReadBack(ppt1); ppt1.close(); @@ -877,7 +887,7 @@ public final class TestBugs { StringBuffer sb = new StringBuffer(); for (char c = iterator.first(); - c != AttributedCharacterIterator.DONE; + c != CharacterIterator.DONE; c = iterator.next()) { sb.append(c); attributes = iterator.getAttributes(); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestCounts.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestCounts.java index a52cee4129..baed0386d3 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestCounts.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestCounts.java @@ -18,29 +18,23 @@ package org.apache.poi.hslf.usermodel; -import java.util.List; +import static org.junit.Assert.assertEquals; -import junit.framework.TestCase; +import java.io.IOException; +import java.util.List; -import org.apache.poi.POIDataSamples; +import org.apache.poi.hslf.HSLFTestDataSamples; +import org.junit.Test; /** * Tests that SlideShow returns the right number of Sheets and MetaSheets - * - * @author Nick Burch (nick at torchbox dot com) */ -public final class TestCounts extends TestCase { - // SlideShow primed on the test data - private final HSLFSlideShow ss; - - public TestCounts() throws Exception { - POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); - HSLFSlideShowImpl hss = new HSLFSlideShowImpl(slTests.openResourceAsStream("basic_test_ppt_file.ppt")); - ss = new HSLFSlideShow(hss); - } - - public void testSheetsCount() { - List<HSLFSlide> slides = ss.getSlides(); +public final class TestCounts { + @Test + public void testSheetsCount() throws IOException { + HSLFSlideShow ppt = HSLFTestDataSamples.getSlideShow("basic_test_ppt_file.ppt"); + + List<HSLFSlide> slides = ppt.getSlides(); // Two sheets - master sheet is separate assertEquals(2, slides.size()); @@ -55,10 +49,15 @@ public final class TestCounts extends TestCase { // These are slides 1+2 -> 256+257 assertEquals(256, slides.get(0)._getSheetNumber()); assertEquals(257, slides.get(1)._getSheetNumber()); + + ppt.close(); } - public void testNotesCount() { - List<HSLFNotes> notes = ss.getNotes(); + @Test + public void testNotesCount() throws IOException { + HSLFSlideShow ppt = HSLFTestDataSamples.getSlideShow("basic_test_ppt_file.ppt"); + + List<HSLFNotes> notes = ppt.getNotes(); // Two sheets -> two notes // Note: there are also notes on the slide master //assertEquals(3, notes.length); // When we do slide masters @@ -74,5 +73,7 @@ public final class TestCounts extends TestCase { // They happen to go between the two slides in Ref terms assertEquals(5, notes.get(0)._getSheetRefId()); assertEquals(7, notes.get(1)._getSheetRefId()); + + ppt.close(); } } |