#61589 - Importing content does not copy hyperlink address

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1837909 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2018-08-12 22:35:02 +00:00
parent d896bb9e30
commit 1c4b3c24af
13 changed files with 269 additions and 92 deletions

View File

@ -29,7 +29,9 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Objects;
import org.apache.poi.sl.usermodel.AbstractColorStyle;
import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
@ -66,7 +68,7 @@ public class DrawPaint {
if (color == null) { if (color == null) {
throw new NullPointerException("Color needs to be specified"); throw new NullPointerException("Color needs to be specified");
} }
this.solidColor = new ColorStyle(){ this.solidColor = new AbstractColorStyle(){
@Override @Override
public Color getColor() { public Color getColor() {
return new Color(color.getRed(), color.getGreen(), color.getBlue()); return new Color(color.getRed(), color.getGreen(), color.getBlue());
@ -89,6 +91,8 @@ public class DrawPaint {
public int getShade() { return -1; } public int getShade() { return -1; }
@Override @Override
public int getTint() { return -1; } public int getTint() { return -1; }
}; };
} }
@ -103,6 +107,22 @@ public class DrawPaint {
public ColorStyle getSolidColor() { public ColorStyle getSolidColor() {
return solidColor; return solidColor;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SolidPaint)) {
return false;
}
return Objects.equals(getSolidColor(), ((SolidPaint) o).getSolidColor());
}
@Override
public int hashCode() {
return Objects.hash(solidColor);
}
} }
public static SolidPaint createSolidPaint(final Color color) { public static SolidPaint createSolidPaint(final Color color) {
@ -131,9 +151,10 @@ public class DrawPaint {
return null; return null;
} }
@SuppressWarnings({"WeakerAccess", "unused"})
protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics, final PaintModifier modifier) { protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics, final PaintModifier modifier) {
final ColorStyle orig = fill.getSolidColor(); final ColorStyle orig = fill.getSolidColor();
ColorStyle cs = new ColorStyle() { ColorStyle cs = new AbstractColorStyle() {
@Override @Override
public Color getColor() { public Color getColor() {
return orig.getColor(); return orig.getColor();
@ -204,6 +225,7 @@ public class DrawPaint {
return applyColorTransform(cs); return applyColorTransform(cs);
} }
@SuppressWarnings("WeakerAccess")
protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) { protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) {
switch (fill.getGradientType()) { switch (fill.getGradientType()) {
case linear: case linear:
@ -217,6 +239,7 @@ public class DrawPaint {
} }
} }
@SuppressWarnings("WeakerAccess")
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) { protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
InputStream is = fill.getImageData(); InputStream is = fill.getImageData();
if (is == null) { if (is == null) {
@ -320,8 +343,6 @@ public class DrawPaint {
* @param hslPart the hsl part to modify [0..2] * @param hslPart the hsl part to modify [0..2]
* @param mod the modulation adjustment * @param mod the modulation adjustment
* @param off the offset adjustment * @param off the offset adjustment
* @return the modified hsl value
*
*/ */
private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) { private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {
if (mod == -1) { if (mod == -1) {
@ -370,6 +391,7 @@ public class DrawPaint {
hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct)); hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct));
} }
@SuppressWarnings("WeakerAccess")
protected Paint createLinearGradientPaint(GradientPaint fill, Graphics2D graphics) { protected Paint createLinearGradientPaint(GradientPaint fill, Graphics2D graphics) {
// TODO: we need to find the two points for gradient - the problem is, which point at the outline // TODO: we need to find the two points for gradient - the problem is, which point at the outline
// do you take? My solution would be to apply the gradient rotation to the shape in reverse // do you take? My solution would be to apply the gradient rotation to the shape in reverse
@ -412,6 +434,7 @@ public class DrawPaint {
return new LinearGradientPaint(p1, p2, fractions, colors); return new LinearGradientPaint(p1, p2, fractions, colors);
} }
@SuppressWarnings("WeakerAccess")
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) { protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
@ -431,6 +454,7 @@ public class DrawPaint {
return new RadialGradientPaint(pCenter, radius, fractions, colors); return new RadialGradientPaint(pCenter, radius, fractions, colors);
} }
@SuppressWarnings({"WeakerAccess", "unused"})
protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) { protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) {
// currently we ignore an eventually center setting // currently we ignore an eventually center setting
@ -445,20 +469,6 @@ public class DrawPaint {
return new PathGradientPaint(colors, fractions); return new PathGradientPaint(colors, fractions);
} }
protected void snapToAnchor(Point2D p, Rectangle2D anchor) {
if (p.getX() < anchor.getX()) {
p.setLocation(anchor.getX(), p.getY());
} else if (p.getX() > (anchor.getX() + anchor.getWidth())) {
p.setLocation(anchor.getX() + anchor.getWidth(), p.getY());
}
if (p.getY() < anchor.getY()) {
p.setLocation(p.getX(), anchor.getY());
} else if (p.getY() > (anchor.getY() + anchor.getHeight())) {
p.setLocation(p.getX(), anchor.getY() + anchor.getHeight());
}
}
/** /**
* Convert HSL values to a RGB Color. * Convert HSL values to a RGB Color.
* *
@ -568,7 +578,7 @@ public class DrawPaint {
// Calculate the Saturation // Calculate the Saturation
double s = 0; final double s;
if (max == min) { if (max == min) {
s = 0; s = 0;

View File

@ -0,0 +1,47 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.sl.usermodel;
import java.util.Objects;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.util.Internal;
/**
* Helper class for ColorStyle - not part of the API / implementation may change any time
*/
@Internal
public abstract class AbstractColorStyle implements ColorStyle {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ColorStyle)) {
return false;
}
return Objects.equals(DrawPaint.applyColorTransform(this), DrawPaint.applyColorTransform((ColorStyle)o));
}
@Override
public int hashCode() {
return DrawPaint.applyColorTransform(this).hashCode();
}
}

View File

@ -21,6 +21,7 @@ package org.apache.poi.xslf.usermodel;
import java.awt.Color; import java.awt.Color;
import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AbstractColorStyle;
import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PresetColor; import org.apache.poi.sl.usermodel.PresetColor;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
@ -52,6 +53,7 @@ public class XSLFColor {
private Color _color; private Color _color;
private CTSchemeColor _phClr; private CTSchemeColor _phClr;
@SuppressWarnings("WeakerAccess")
public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) { public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) {
_xmlObject = obj; _xmlObject = obj;
_phClr = phClr; _phClr = phClr;
@ -72,8 +74,9 @@ public class XSLFColor {
return DrawPaint.applyColorTransform(getColorStyle()); return DrawPaint.applyColorTransform(getColorStyle());
} }
@SuppressWarnings("WeakerAccess")
public ColorStyle getColorStyle() { public ColorStyle getColorStyle() {
return new ColorStyle() { return new AbstractColorStyle() {
@Override @Override
public Color getColor() { public Color getColor() {
return _color; return _color;
@ -126,7 +129,7 @@ public class XSLFColor {
}; };
} }
Color toColor(XmlObject obj, XSLFTheme theme) { private Color toColor(XmlObject obj, XSLFTheme theme) {
Color color = null; Color color = null;
for (XmlObject ch : obj.selectPath("*")) { for (XmlObject ch : obj.selectPath("*")) {
if (ch instanceof CTHslColor) { if (ch instanceof CTHslColor) {
@ -178,10 +181,7 @@ public class XSLFColor {
color = Color.black; color = Color.black;
} }
} }
} else if (ch instanceof CTFontReference) { } else if (!(ch instanceof CTFontReference)) {
// try next ...
continue;
} else {
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass()); throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
} }
} }
@ -298,11 +298,6 @@ public class XSLFColor {
return (val == -1) ? val : (val / 1000); return (val == -1) ? val : (val / 1000);
} }
private int getAngleValue(String elem){
int val = getRawValue(elem);
return (val == -1) ? val : (val / 60000);
}
/** /**
* the opacity as expressed by a percentage value * the opacity as expressed by a percentage value
* *
@ -336,14 +331,18 @@ public class XSLFColor {
} }
@SuppressWarnings("unused")
int getHue(){ int getHue(){
return getAngleValue("hue"); int val = getRawValue("hue");
return (val == -1) ? val : (val / 60000);
} }
@SuppressWarnings("unused")
int getHueMod(){ int getHueMod(){
return getPercentageValue("hueMod"); return getPercentageValue("hueMod");
} }
@SuppressWarnings("unused")
int getHueOff(){ int getHueOff(){
return getPercentageValue("hueOff"); return getPercentageValue("hueOff");
} }
@ -355,6 +354,7 @@ public class XSLFColor {
* @return luminance in percents in the range [0..100] * @return luminance in percents in the range [0..100]
* or -1 if the value is not set * or -1 if the value is not set
*/ */
@SuppressWarnings("unused")
int getLum(){ int getLum(){
return getPercentageValue("lum"); return getPercentageValue("lum");
} }
@ -422,10 +422,12 @@ public class XSLFColor {
return getPercentageValue("red"); return getPercentageValue("red");
} }
@SuppressWarnings("unused")
int getRedMod(){ int getRedMod(){
return getPercentageValue("redMod"); return getPercentageValue("redMod");
} }
@SuppressWarnings("unused")
int getRedOff(){ int getRedOff(){
return getPercentageValue("redOff"); return getPercentageValue("redOff");
} }
@ -442,10 +444,12 @@ public class XSLFColor {
return getPercentageValue("green"); return getPercentageValue("green");
} }
@SuppressWarnings("unused")
int getGreenMod(){ int getGreenMod(){
return getPercentageValue("greenMod"); return getPercentageValue("greenMod");
} }
@SuppressWarnings("unused")
int getGreenOff(){ int getGreenOff(){
return getPercentageValue("greenOff"); return getPercentageValue("greenOff");
} }
@ -462,10 +466,12 @@ public class XSLFColor {
return getPercentageValue("blue"); return getPercentageValue("blue");
} }
@SuppressWarnings("unused")
int getBlueMod(){ int getBlueMod(){
return getPercentageValue("blueMod"); return getPercentageValue("blueMod");
} }
@SuppressWarnings("unused")
int getBlueOff(){ int getBlueOff(){
return getPercentageValue("blueOff"); return getPercentageValue("blueOff");
} }
@ -478,6 +484,7 @@ public class XSLFColor {
* percentage with 0% indicating minimal shade and 100% indicating maximum * percentage with 0% indicating minimal shade and 100% indicating maximum
* or -1 if the value is not set * or -1 if the value is not set
*/ */
@SuppressWarnings("WeakerAccess")
public int getShade(){ public int getShade(){
return getPercentageValue("shade"); return getPercentageValue("shade");
} }

View File

@ -19,6 +19,7 @@ package org.apache.poi.xslf.usermodel;
import java.net.URI; import java.net.URI;
import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart; import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
@ -156,12 +157,44 @@ public class XSLFHyperlink implements Hyperlink<XSLFShape,XSLFTextParagraph> {
linkToRelativeSlide("lastslide"); linkToRelativeSlide("lastslide");
} }
void copy(XSLFHyperlink src) {
switch (src.getType()) {
case EMAIL:
case URL:
linkToExternal(src.getAddress());
break;
case DOCUMENT:
final String idSrc = src._link.getId();
if (idSrc == null || idSrc.isEmpty()) {
// link to slide - relative reference
linkToRelativeSlide(src.getAddress());
} else {
// link to slide . absolute reference
// this is kind of a hack, as we might link to pages not yet imported,
// but the underlying implementation is based only on package part names,
// so this actually works ...
POIXMLDocumentPart pp = src._sheet.getRelationById(idSrc);
if (pp != null) {
RelationPart rp = _sheet.addRelation(null, XSLFRelation.SLIDE, pp);
_link.setId(rp.getRelationship().getId());
_link.setAction(src._link.getAction());
}
}
break;
default:
case FILE:
case NONE:
return;
}
setLabel(src.getLabel());
}
private void linkToRelativeSlide(String jump) { private void linkToRelativeSlide(String jump) {
PackagePart thisPP = _sheet.getPackagePart(); PackagePart thisPP = _sheet.getPackagePart();
if (_link.isSetId() && !_link.getId().isEmpty()) { if (_link.isSetId() && !_link.getId().isEmpty()) {
thisPP.removeRelationship(_link.getId()); thisPP.removeRelationship(_link.getId());
} }
_link.setId(""); _link.setId("");
_link.setAction("ppaction://hlinkshowjump?jump="+jump); _link.setAction((jump.startsWith("ppaction") ? "" : "ppaction://hlinkshowjump?jump=") + jump);
} }
} }

View File

@ -26,8 +26,10 @@ import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@SuppressWarnings({"unused", "WeakerAccess"})
@Beta @Beta
public class XSLFRelation extends POIXMLRelation { public final class XSLFRelation extends POIXMLRelation {
/* package */ static final String NS_DRAWINGML = "http://schemas.openxmlformats.org/drawingml/2006/main";
/** /**
* A map to lookup POIXMLRelation by its relation type * A map to lookup POIXMLRelation by its relation type

View File

@ -24,7 +24,6 @@ import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
@ -178,10 +177,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return fetcher.getValue(); return fetcher.getValue();
} }
@SuppressWarnings("unused")
protected CTBackgroundProperties getBgPr() { protected CTBackgroundProperties getBgPr() {
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr"); return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
} }
@SuppressWarnings("unused")
protected CTStyleMatrixReference getBgRef() { protected CTStyleMatrixReference getBgRef() {
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef"); return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
} }
@ -198,6 +199,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return _nvPr; return _nvPr;
} }
@SuppressWarnings("WeakerAccess")
protected CTShapeStyle getSpStyle() { protected CTShapeStyle getSpStyle() {
if (_spStyle == null) { if (_spStyle == null) {
_spStyle = getChild(CTShapeStyle.class, PML_NS, "style"); _spStyle = getChild(CTShapeStyle.class, PML_NS, "style");
@ -213,14 +215,14 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* @param nodename the node name, without prefix * @param nodename the node name, without prefix
* @return the properties object or null if it can't be found * @return the properties object or null if it can't be found
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "WeakerAccess", "unused", "SameParameterValue"})
protected <T extends XmlObject> T getChild(Class<T> childClass, String namespace, String nodename) { protected <T extends XmlObject> T getChild(Class<T> childClass, String namespace, String nodename) {
XmlCursor cur = getXmlObject().newCursor(); XmlCursor cur = getXmlObject().newCursor();
T child = null; T child = null;
if (cur.toChild(namespace, nodename)) { if (cur.toChild(namespace, nodename)) {
child = (T)cur.getObject(); child = (T)cur.getObject();
} }
if (cur.toChild("http://schemas.openxmlformats.org/drawingml/2006/main", nodename)) { if (cur.toChild(XSLFRelation.NS_DRAWINGML, nodename)) {
child = (T)cur.getObject(); child = (T)cur.getObject();
} }
cur.dispose(); cur.dispose();
@ -248,6 +250,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
/** /**
* @see SimpleShape#getPlaceholderDetails() * @see SimpleShape#getPlaceholderDetails()
*/ */
@SuppressWarnings("WeakerAccess")
public XSLFPlaceholderDetails getPlaceholderDetails() { public XSLFPlaceholderDetails getPlaceholderDetails() {
return new XSLFPlaceholderDetails(this); return new XSLFPlaceholderDetails(this);
} }
@ -262,7 +265,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* @param xquery the simple (xmlbean) xpath expression to the property * @param xquery the simple (xmlbean) xpath expression to the property
* @return the xml object at the xpath location, or null if not found * @return the xml object at the xpath location, or null if not found
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "WeakerAccess"})
protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) { protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
XmlObject[] rs = getXmlObject().selectPath(xquery); XmlObject[] rs = getXmlObject().selectPath(xquery);
if (rs.length == 0) return null; if (rs.length == 0) return null;
@ -284,6 +287,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* @param visitor the object that collects the desired property * @param visitor the object that collects the desired property
* @return true if the property was fetched * @return true if the property was fetched
*/ */
@SuppressWarnings("WeakerAccess")
protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) { protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
// try shape properties in slide // try shape properties in slide
if (visitor.fetch(this)) { if (visitor.fetch(this)) {
@ -311,9 +315,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
XSLFSlideMaster master = (XSLFSlideMaster)sm; XSLFSlideMaster master = (XSLFSlideMaster)sm;
int textType = getPlaceholderType(ph); int textType = getPlaceholderType(ph);
XSLFSimpleShape masterShape = master.getPlaceholderByType(textType); XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
if (masterShape != null && visitor.fetch(masterShape)) { return masterShape != null && visitor.fetch(masterShape);
return true;
}
} }
return false; return false;
@ -348,6 +350,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* *
* @return the applied Paint or null if none was applied * @return the applied Paint or null if none was applied
*/ */
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) { protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) {
if (fp == null || fp.isSetNoFill()) { if (fp == null || fp.isSetNoFill()) {
return null; return null;
@ -364,6 +367,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
} }
} }
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) { protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
if (solidFill.isSetSchemeClr()) { if (solidFill.isSetSchemeClr()) {
// if there's a reference to the placeholder color, // if there's a reference to the placeholder color,
@ -380,6 +384,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return DrawPaint.createSolidPaint(c.getColorStyle()); return DrawPaint.createSolidPaint(c.getColorStyle());
} }
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) { protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
final CTBlip blip = blipFill.getBlip(); final CTBlip blip = blipFill.getBlip();
return new TexturePaint() { return new TexturePaint() {
@ -414,16 +419,16 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
}; };
} }
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) { protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
@SuppressWarnings("deprecation")
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
Arrays.sort(gs, new Comparator<CTGradientStop>() { Arrays.sort(gs, (o1, o2) -> {
public int compare(CTGradientStop o1, CTGradientStop o2) {
Integer pos1 = o1.getPos(); Integer pos1 = o1.getPos();
Integer pos2 = o2.getPos(); Integer pos2 = o2.getPos();
return pos1.compareTo(pos2); return pos1.compareTo(pos2);
}
}); });
final ColorStyle cs[] = new ColorStyle[gs.length]; final ColorStyle cs[] = new ColorStyle[gs.length];
@ -480,6 +485,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
}; };
} }
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) { protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
if (fillRef == null) return null; if (fillRef == null) return null;

View File

@ -49,7 +49,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFra
public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow>, public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow>,
TableShape<XSLFShape,XSLFTextParagraph> { TableShape<XSLFShape,XSLFTextParagraph> {
/* package */ static final String TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table"; /* package */ static final String TABLE_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
/* package */ static final String DRAWINGML_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
private CTTable _table; private CTTable _table;
private List<XSLFTableRow> _rows; private List<XSLFTableRow> _rows;
@ -60,7 +59,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
CTGraphicalObjectData god = shape.getGraphic().getGraphicData(); CTGraphicalObjectData god = shape.getGraphic().getGraphicData();
XmlCursor xc = god.newCursor(); XmlCursor xc = god.newCursor();
try { try {
if (!xc.toChild(DRAWINGML_URI, "tbl")) { if (!xc.toChild(XSLFRelation.NS_DRAWINGML, "tbl")) {
throw new IllegalStateException("a:tbl element was not found in\n " + god); throw new IllegalStateException("a:tbl element was not found in\n " + god);
} }
@ -174,7 +173,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData(); CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData();
XmlCursor grCur = gr.newCursor(); XmlCursor grCur = gr.newCursor();
grCur.toNextToken(); grCur.toNextToken();
grCur.beginElement(new QName(DRAWINGML_URI, "tbl")); grCur.beginElement(new QName(XSLFRelation.NS_DRAWINGML, "tbl"));
CTTable tbl = CTTable.Factory.newInstance(); CTTable tbl = CTTable.Factory.newInstance();
tbl.addNewTblPr(); tbl.addNewTblPr();
@ -191,6 +190,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
/** /**
* Merge cells of a table * Merge cells of a table
*/ */
@SuppressWarnings("unused")
public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) { public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) {
if(firstRow > lastRow) { if(firstRow > lastRow) {
@ -225,14 +225,14 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
if(i == firstRow) { if(i == firstRow) {
cell.setRowSpan(rowSpan); cell.setRowSpan(rowSpan);
} else { } else {
cell.setVMerge(true); cell.setVMerge();
} }
} }
if(mergeColumnRequired) { if(mergeColumnRequired) {
if(colPos == firstCol) { if(colPos == firstCol) {
cell.setGridSpan(colSpan); cell.setGridSpan(colSpan);
} else { } else {
cell.setHMerge(true); cell.setHMerge();
} }
} }
} }

View File

@ -41,7 +41,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable; import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
@ -104,6 +103,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return cell; return cell;
} }
@SuppressWarnings("WeakerAccess")
protected CTTableCellProperties getCellProperties(boolean create) { protected CTTableCellProperties getCellProperties(boolean create) {
if (_tcPr == null) { if (_tcPr == null) {
CTTableCell cell = getCell(); CTTableCell cell = getCell();
@ -251,6 +251,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
setBorderWidth(edge, width); setBorderWidth(edge, width);
} }
@SuppressWarnings("WeakerAccess")
public Double getBorderWidth(BorderEdge edge) { public Double getBorderWidth(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false); CTLineProperties ln = getCTLine(edge, false);
return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW()); return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW());
@ -320,6 +321,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
c.setColor(color); c.setColor(color);
} }
@SuppressWarnings("WeakerAccess")
public Color getBorderColor(BorderEdge edge) { public Color getBorderColor(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) { if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) {
@ -331,6 +333,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return c.getColor(); return c.getColor();
} }
@SuppressWarnings("WeakerAccess")
public LineCompound getBorderCompound(BorderEdge edge) { public LineCompound getBorderCompound(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) { if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) {
@ -350,6 +353,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId)); ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId));
} }
@SuppressWarnings("WeakerAccess")
public LineDash getBorderDash(BorderEdge edge) { public LineDash getBorderDash(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) { if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) {
@ -372,6 +376,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId)); ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
} }
@SuppressWarnings("WeakerAccess")
public LineCap getBorderCap(BorderEdge edge) { public LineCap getBorderCap(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) { if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) {
@ -381,6 +386,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return LineCap.fromOoxmlId(ln.getCap().intValue()); return LineCap.fromOoxmlId(ln.getCap().intValue());
} }
@SuppressWarnings("WeakerAccess")
public void setBorderCap(BorderEdge edge, LineCap cap) { public void setBorderCap(BorderEdge edge, LineCap cap) {
if (cap == null) { if (cap == null) {
throw new IllegalArgumentException("LineCap need to be specified."); throw new IllegalArgumentException("LineCap need to be specified.");
@ -544,12 +550,12 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return (c.isSetRowSpan()) ? c.getRowSpan() : 1; return (c.isSetRowSpan()) ? c.getRowSpan() : 1;
} }
void setHMerge(boolean merge_) { void setHMerge() {
getCell().setHMerge(merge_); getCell().setHMerge(true);
} }
void setVMerge(boolean merge_) { void setVMerge() {
getCell().setVMerge(merge_); getCell().setVMerge(true);
} }
@Override @Override
@ -715,13 +721,13 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
/** /**
* @since POI 3.15-beta2 * @since POI 3.15-beta2
*/ */
private class XSLFCellTextParagraph extends XSLFTextParagraph { private final class XSLFCellTextParagraph extends XSLFTextParagraph {
protected XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) { private XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) {
super(p, shape); super(p, shape);
} }
@Override @Override
protected XSLFCellTextRun newTextRun(CTRegularTextRun r) { protected XSLFCellTextRun newTextRun(XmlObject r) {
return new XSLFCellTextRun(r, this); return new XSLFCellTextRun(r, this);
} }
} }
@ -729,8 +735,8 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
/** /**
* @since POI 3.15-beta2 * @since POI 3.15-beta2
*/ */
private class XSLFCellTextRun extends XSLFTextRun { private final class XSLFCellTextRun extends XSLFTextRun {
protected XSLFCellTextRun(CTRegularTextRun r, XSLFTextParagraph p) { private XSLFCellTextRun(XmlObject r, XSLFTextParagraph p) {
super(r, p); super(r, p);
} }

View File

@ -39,6 +39,7 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
/*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){ /*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){
_row = row; _row = row;
_table = table; _table = table;
@SuppressWarnings("deprecation")
CTTableCell[] tcArray = _row.getTcArray(); CTTableCell[] tcArray = _row.getTcArray();
_cells = new ArrayList<>(tcArray.length); _cells = new ArrayList<>(tcArray.length);
for(CTTableCell cell : tcArray) { for(CTTableCell cell : tcArray) {
@ -86,6 +87,7 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
* @param firstCol 0-based index of first column to merge, inclusive * @param firstCol 0-based index of first column to merge, inclusive
* @param lastCol 0-based index of last column to merge, inclusive * @param lastCol 0-based index of last column to merge, inclusive
*/ */
@SuppressWarnings("WeakerAccess")
public void mergeCells(int firstCol, int lastCol) public void mergeCells(int firstCol, int lastCol)
{ {
if (firstCol >= lastCol) { if (firstCol >= lastCol) {
@ -99,7 +101,7 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
_cells.get(firstCol).setGridSpan(colSpan); _cells.get(firstCol).setGridSpan(colSpan);
for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) { for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) {
cell.setHMerge(true); cell.setHMerge();
} }
} }

View File

@ -134,6 +134,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
// by default line break has the font size of the last text run // by default line break has the font size of the last text run
CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true); CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr(true);
brProps.set(prevRun); brProps.set(prevRun);
// don't copy hlink properties
if (brProps.isSetHlinkClick()) {
brProps.unsetHlinkClick();
}
if (brProps.isSetHlinkMouseOver()) {
brProps.unsetHlinkMouseOver();
}
} }
_runs.add(run); _runs.add(run);
return run; return run;
@ -188,6 +195,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
* *
* @param align font align * @param align font align
*/ */
@SuppressWarnings("unused")
public void setFontAlign(FontAlign align){ public void setFontAlign(FontAlign align){
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
if(align == null) { if(align == null) {
@ -718,7 +726,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
* @return master style text paragraph properties, or <code>null</code> if * @return master style text paragraph properties, or <code>null</code> if
* there are no master slides or the master slides do not contain a text paragraph * there are no master slides or the master slides do not contain a text paragraph
*/ */
/* package */ CTTextParagraphProperties getDefaultMasterStyle(){ private CTTextParagraphProperties getDefaultMasterStyle(){
CTPlaceholder ph = _shape.getPlaceholderDetails().getCTPlaceholder(false); CTPlaceholder ph = _shape.getPlaceholderDetails().getCTPlaceholder(false);
String defaultStyleSelector; String defaultStyleSelector;
switch(ph == null ? -1 : ph.getType().intValue()) { switch(ph == null ? -1 : ph.getType().intValue()) {
@ -740,7 +748,6 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
// wind up and find the root master sheet which must be slide master // wind up and find the root master sheet which must be slide master
final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main"; final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main";
final String nsDML = "http://schemas.openxmlformats.org/drawingml/2006/main";
XSLFSheet masterSheet = _shape.getSheet(); XSLFSheet masterSheet = _shape.getSheet();
for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) { for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
masterSheet = m; masterSheet = m;
@ -752,7 +759,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
(cur.pop() && cur.toChild(nsPML, "notesStyle"))) { (cur.pop() && cur.toChild(nsPML, "notesStyle"))) {
while (level >= 0) { while (level >= 0) {
cur.push(); cur.push();
if (cur.toChild(nsDML, "lvl" +(level+1)+ "pPr")) { if (cur.toChild(XSLFRelation.NS_DRAWINGML, "lvl" +(level+1)+ "pPr")) {
return (CTTextParagraphProperties)cur.getObject(); return (CTTextParagraphProperties)cur.getObject();
} }
cur.pop(); cur.pop();
@ -788,11 +795,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
fetchMasterProperty(visitor); fetchMasterProperty(visitor);
} }
boolean fetchMasterProperty(final ParagraphPropertyFetcher<?> visitor) { void fetchMasterProperty(final ParagraphPropertyFetcher<?> visitor) {
// defaults for placeholders are defined in the slide master // defaults for placeholders are defined in the slide master
final CTTextParagraphProperties defaultProps = getDefaultMasterStyle(); final CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
// TODO: determine master shape // TODO: determine master shape
return defaultProps != null && visitor.fetch(defaultProps); if (defaultProps != null) {
visitor.fetch(defaultProps);
}
} }
boolean fetchThemeProperty(final ParagraphPropertyFetcher<?> visitor) { boolean fetchThemeProperty(final ParagraphPropertyFetcher<?> visitor) {
@ -836,15 +845,15 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
otherC.dispose(); otherC.dispose();
thisC.dispose(); thisC.dispose();
List<XSLFTextRun> otherRs = other.getTextRuns(); for (XSLFTextRun tr : other.getTextRuns()) {
int i=0; XmlObject xo = tr.getXmlObject();
for(CTRegularTextRun rtr : thisP.getRList()) { XSLFTextRun run = (xo instanceof CTTextLineBreak)
XSLFTextRun run = newTextRun(rtr); ? newTextRun((CTTextLineBreak)xo)
run.copy(otherRs.get(i++)); : newTextRun(xo);
run.copy(tr);
_runs.add(run); _runs.add(run);
} }
// set properties again, in case we are based on a different // set properties again, in case we are based on a different
// template // template
TextAlign srcAlign = other.getTextAlign(); TextAlign srcAlign = other.getTextAlign();
@ -998,6 +1007,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
public boolean fetch(CTTextParagraphProperties props) { public boolean fetch(CTTextParagraphProperties props) {
if (props.isSetTabLst()) { if (props.isSetTabLst()) {
final List<XSLFTabStop> list = new ArrayList<>(); final List<XSLFTabStop> list = new ArrayList<>();
//noinspection deprecation
for (final CTTextTabStop ta : props.getTabLst().getTabArray()) { for (final CTTextTabStop ta : props.getTabLst().getTabArray()) {
list.add(new XSLFTabStop(ta)); list.add(new XSLFTabStop(ta));
} }
@ -1021,6 +1031,10 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
final CTTextParagraph xo = getXmlObject(); final CTTextParagraph xo = getXmlObject();
tpp = (xo.isSetPPr()) ? xo.getPPr() : xo.addNewPPr(); tpp = (xo.isSetPPr()) ? xo.getPPr() : xo.addNewPPr();
} }
if (tpp == null) {
return;
}
final CTTextTabStopList stl = (tpp.isSetTabLst()) ? tpp.getTabLst() : tpp.addNewTabLst(); final CTTextTabStopList stl = (tpp.isSetTabLst()) ? tpp.getTabLst() : tpp.addNewTabLst();
XSLFTabStop tab = new XSLFTabStop(stl.addNewTab()); XSLFTabStop tab = new XSLFTabStop(stl.addNewTab());
tab.setPositionInPoints(positionInPoints); tab.setPositionInPoints(positionInPoints);
@ -1090,7 +1104,12 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
* *
* @since POI 3.15-beta2 * @since POI 3.15-beta2
*/ */
protected XSLFTextRun newTextRun(CTRegularTextRun r) { protected XSLFTextRun newTextRun(XmlObject r) {
return new XSLFTextRun(r, this); return new XSLFTextRun(r, this);
} }
@SuppressWarnings("WeakerAccess")
protected XSLFTextRun newTextRun(CTTextLineBreak r) {
return new XSLFLineBreak(r, this);
}
} }

View File

@ -581,6 +581,12 @@ public class XSLFTextRun implements TextRun {
if(strike != isStrikethrough()) { if(strike != isStrikethrough()) {
setStrikethrough(strike); setStrikethrough(strike);
} }
XSLFHyperlink hyperSrc = r.getHyperlink();
if (hyperSrc != null) {
XSLFHyperlink hyperDst = getHyperlink();
hyperDst.copy(hyperSrc);
}
} }

View File

@ -37,7 +37,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
/** /**
@ -66,6 +65,7 @@ public class XSLFTheme extends POIXMLDocumentPart {
initialize(); initialize();
} }
@SuppressWarnings("WeakerAccess")
public void importTheme(XSLFTheme theme) { public void importTheme(XSLFTheme theme) {
_theme = theme.getXmlObject(); _theme = theme.getXmlObject();
_schemeColors = theme._schemeColors; _schemeColors = theme._schemeColors;
@ -134,7 +134,7 @@ public class XSLFTheme extends POIXMLDocumentPart {
protected final void commit() throws IOException { protected final void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
xmlOptions.setSaveSyntheticDocumentElement( xmlOptions.setSaveSyntheticDocumentElement(
new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "theme")); new QName(XSLFRelation.NS_DRAWINGML, "theme"));
PackagePart part = getPackagePart(); PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream(); OutputStream out = part.getOutputStream();
@ -147,6 +147,7 @@ public class XSLFTheme extends POIXMLDocumentPart {
* Typically the major font is used for heading areas of a document. * Typically the major font is used for heading areas of a document.
* *
*/ */
@SuppressWarnings("WeakerAccess")
public String getMajorFont(){ public String getMajorFont(){
return _theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface(); return _theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface();
} }
@ -156,19 +157,8 @@ public class XSLFTheme extends POIXMLDocumentPart {
* Typically the monor font is used for normal text or paragraph areas. * Typically the monor font is used for normal text or paragraph areas.
* *
*/ */
@SuppressWarnings("WeakerAccess")
public String getMinorFont(){ public String getMinorFont(){
return _theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface(); return _theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface();
} }
CTTextParagraphProperties getDefaultParagraphStyle(){
XmlObject[] o = _theme.selectPath(
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
"declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
".//a:objectDefaults/a:spDef/a:lstStyle/a:defPPr");
if(o.length == 1){
return (CTTextParagraphProperties)o[0];
}
return null;
}
} }

View File

@ -81,6 +81,7 @@ import org.apache.poi.xslf.usermodel.XSLFSlideMaster;
import org.apache.poi.xslf.usermodel.XSLFTable; import org.apache.poi.xslf.usermodel.XSLFTable;
import org.apache.poi.xslf.usermodel.XSLFTableCell; import org.apache.poi.xslf.usermodel.XSLFTableCell;
import org.apache.poi.xslf.usermodel.XSLFTableRow; import org.apache.poi.xslf.usermodel.XSLFTableRow;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph; import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun; import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.junit.Ignore; import org.junit.Ignore;
@ -92,6 +93,54 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
public class TestXSLFBugs { public class TestXSLFBugs {
private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
@Test
public void bug61589() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (XMLSlideShow src = new XMLSlideShow();
XMLSlideShow dest = new XMLSlideShow()) {
XSLFSlide slide = src.createSlide();
XSLFSlide slide2 = src.createSlide();
XSLFTextBox shape = slide.createTextBox();
shape.setAnchor(new Rectangle2D.Double(100,100,400,100));
XSLFTextParagraph p = shape.addNewTextParagraph();
XSLFTextRun r = p.addNewTextRun();
p.addLineBreak();
r.setText("Apache POI");
r.createHyperlink().setAddress("http://poi.apache.org");
// create hyperlink pointing to a page, which isn't available at the time of importing the content
r = p.addNewTextRun();
r.setText("Slide 2");
r.createHyperlink().linkToSlide(slide2);
shape = slide2.createTextBox();
shape.setAnchor(new Rectangle2D.Double(100,100,400,100));
shape.setText("slide 2");
dest.createSlide().importContent(slide);
dest.createSlide().importContent(slide2);
dest.write(bos);
}
try (XMLSlideShow ppt = new XMLSlideShow(new ByteArrayInputStream(bos.toByteArray()))) {
XSLFSlide slide = ppt.getSlides().get(0);
XSLFTextBox shape = (XSLFTextBox)slide.getShapes().get(0);
XSLFTextParagraph p = shape.getTextParagraphs().get(1);
XSLFHyperlink h1 = p.getTextRuns().get(0).getHyperlink();
assertNotNull(h1);
assertEquals("http://poi.apache.org", h1.getAddress());
XSLFHyperlink h2 = p.getTextRuns().get(2).getHyperlink();
assertNotNull(h2);
// relative url will be resolved to an absolute url, therefore this doesn't equals to "slide2.xml"
assertEquals("/ppt/slides/slide2.xml", h2.getAddress());
RelationPart sldRef = slide.getRelationPartById(h2.getXmlObject().getId());
assertTrue(sldRef.getDocumentPart() instanceof XSLFSlide);
}
}
@Test @Test
public void bug62587() throws IOException { public void bug62587() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();