mirror of https://github.com/apache/poi.git
#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:
parent
d896bb9e30
commit
1c4b3c24af
|
@ -29,7 +29,9 @@ import java.awt.geom.Rectangle2D;
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
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.PaintStyle;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
|
||||
|
@ -66,7 +68,7 @@ public class DrawPaint {
|
|||
if (color == null) {
|
||||
throw new NullPointerException("Color needs to be specified");
|
||||
}
|
||||
this.solidColor = new ColorStyle(){
|
||||
this.solidColor = new AbstractColorStyle(){
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return new Color(color.getRed(), color.getGreen(), color.getBlue());
|
||||
|
@ -89,6 +91,8 @@ public class DrawPaint {
|
|||
public int getShade() { return -1; }
|
||||
@Override
|
||||
public int getTint() { return -1; }
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,6 +107,22 @@ public class DrawPaint {
|
|||
public ColorStyle getSolidColor() {
|
||||
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) {
|
||||
|
@ -131,9 +151,10 @@ public class DrawPaint {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics, final PaintModifier modifier) {
|
||||
final ColorStyle orig = fill.getSolidColor();
|
||||
ColorStyle cs = new ColorStyle() {
|
||||
ColorStyle cs = new AbstractColorStyle() {
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return orig.getColor();
|
||||
|
@ -204,6 +225,7 @@ public class DrawPaint {
|
|||
return applyColorTransform(cs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) {
|
||||
switch (fill.getGradientType()) {
|
||||
case linear:
|
||||
|
@ -217,6 +239,7 @@ public class DrawPaint {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
|
||||
InputStream is = fill.getImageData();
|
||||
if (is == null) {
|
||||
|
@ -320,8 +343,6 @@ public class DrawPaint {
|
|||
* @param hslPart the hsl part to modify [0..2]
|
||||
* @param mod the modulation adjustment
|
||||
* @param off the offset adjustment
|
||||
* @return the modified hsl value
|
||||
*
|
||||
*/
|
||||
private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) {
|
||||
if (mod == -1) {
|
||||
|
@ -370,6 +391,7 @@ public class DrawPaint {
|
|||
hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct));
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
|
||||
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
|
||||
|
||||
|
@ -431,6 +454,7 @@ public class DrawPaint {
|
|||
return new RadialGradientPaint(pCenter, radius, fractions, colors);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) {
|
||||
// currently we ignore an eventually center setting
|
||||
|
||||
|
@ -445,20 +469,6 @@ public class DrawPaint {
|
|||
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.
|
||||
*
|
||||
|
@ -568,7 +578,7 @@ public class DrawPaint {
|
|||
|
||||
// Calculate the Saturation
|
||||
|
||||
double s = 0;
|
||||
final double s;
|
||||
|
||||
if (max == min) {
|
||||
s = 0;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ package org.apache.poi.xslf.usermodel;
|
|||
import java.awt.Color;
|
||||
|
||||
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.PresetColor;
|
||||
import org.apache.poi.util.Beta;
|
||||
|
@ -52,6 +53,7 @@ public class XSLFColor {
|
|||
private Color _color;
|
||||
private CTSchemeColor _phClr;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) {
|
||||
_xmlObject = obj;
|
||||
_phClr = phClr;
|
||||
|
@ -72,8 +74,9 @@ public class XSLFColor {
|
|||
return DrawPaint.applyColorTransform(getColorStyle());
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public ColorStyle getColorStyle() {
|
||||
return new ColorStyle() {
|
||||
return new AbstractColorStyle() {
|
||||
@Override
|
||||
public Color getColor() {
|
||||
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;
|
||||
for (XmlObject ch : obj.selectPath("*")) {
|
||||
if (ch instanceof CTHslColor) {
|
||||
|
@ -178,10 +181,7 @@ public class XSLFColor {
|
|||
color = Color.black;
|
||||
}
|
||||
}
|
||||
} else if (ch instanceof CTFontReference) {
|
||||
// try next ...
|
||||
continue;
|
||||
} else {
|
||||
} else if (!(ch instanceof CTFontReference)) {
|
||||
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
|
||||
}
|
||||
}
|
||||
|
@ -298,11 +298,6 @@ public class XSLFColor {
|
|||
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
|
||||
*
|
||||
|
@ -336,14 +331,18 @@ public class XSLFColor {
|
|||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getHue(){
|
||||
return getAngleValue("hue");
|
||||
int val = getRawValue("hue");
|
||||
return (val == -1) ? val : (val / 60000);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getHueMod(){
|
||||
return getPercentageValue("hueMod");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getHueOff(){
|
||||
return getPercentageValue("hueOff");
|
||||
}
|
||||
|
@ -355,6 +354,7 @@ public class XSLFColor {
|
|||
* @return luminance in percents in the range [0..100]
|
||||
* or -1 if the value is not set
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
int getLum(){
|
||||
return getPercentageValue("lum");
|
||||
}
|
||||
|
@ -422,10 +422,12 @@ public class XSLFColor {
|
|||
return getPercentageValue("red");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getRedMod(){
|
||||
return getPercentageValue("redMod");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getRedOff(){
|
||||
return getPercentageValue("redOff");
|
||||
}
|
||||
|
@ -442,10 +444,12 @@ public class XSLFColor {
|
|||
return getPercentageValue("green");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getGreenMod(){
|
||||
return getPercentageValue("greenMod");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getGreenOff(){
|
||||
return getPercentageValue("greenOff");
|
||||
}
|
||||
|
@ -462,10 +466,12 @@ public class XSLFColor {
|
|||
return getPercentageValue("blue");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getBlueMod(){
|
||||
return getPercentageValue("blueMod");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int getBlueOff(){
|
||||
return getPercentageValue("blueOff");
|
||||
}
|
||||
|
@ -478,6 +484,7 @@ public class XSLFColor {
|
|||
* percentage with 0% indicating minimal shade and 100% indicating maximum
|
||||
* or -1 if the value is not set
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public int getShade(){
|
||||
return getPercentageValue("shade");
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.xslf.usermodel;
|
|||
import java.net.URI;
|
||||
|
||||
import org.apache.poi.common.usermodel.HyperlinkType;
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart;
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
@ -155,13 +156,45 @@ public class XSLFHyperlink implements Hyperlink<XSLFShape,XSLFTextParagraph> {
|
|||
public void linkToLastSlide() {
|
||||
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) {
|
||||
PackagePart thisPP = _sheet.getPackagePart();
|
||||
if (_link.isSetId() && !_link.getId().isEmpty()) {
|
||||
thisPP.removeRelationship(_link.getId());
|
||||
}
|
||||
_link.setId("");
|
||||
_link.setAction("ppaction://hlinkshowjump?jump="+jump);
|
||||
_link.setAction((jump.startsWith("ppaction") ? "" : "ppaction://hlinkshowjump?jump=") + jump);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@ import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
|||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
@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
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.awt.geom.Rectangle2D;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
@ -178,10 +177,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
return fetcher.getValue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected CTBackgroundProperties getBgPr() {
|
||||
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected CTStyleMatrixReference getBgRef() {
|
||||
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
|
||||
}
|
||||
|
@ -198,6 +199,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
return _nvPr;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected CTShapeStyle getSpStyle() {
|
||||
if (_spStyle == null) {
|
||||
_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
|
||||
* @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) {
|
||||
XmlCursor cur = getXmlObject().newCursor();
|
||||
T child = null;
|
||||
if (cur.toChild(namespace, nodename)) {
|
||||
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();
|
||||
}
|
||||
cur.dispose();
|
||||
|
@ -248,6 +250,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
/**
|
||||
* @see SimpleShape#getPlaceholderDetails()
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public XSLFPlaceholderDetails getPlaceholderDetails() {
|
||||
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
|
||||
* @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) {
|
||||
XmlObject[] rs = getXmlObject().selectPath(xquery);
|
||||
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
|
||||
* @return true if the property was fetched
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
|
||||
// try shape properties in slide
|
||||
if (visitor.fetch(this)) {
|
||||
|
@ -311,9 +315,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
XSLFSlideMaster master = (XSLFSlideMaster)sm;
|
||||
int textType = getPlaceholderType(ph);
|
||||
XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
|
||||
if (masterShape != null && visitor.fetch(masterShape)) {
|
||||
return true;
|
||||
}
|
||||
return masterShape != null && visitor.fetch(masterShape);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -348,6 +350,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
*
|
||||
* @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) {
|
||||
if (fp == null || fp.isSetNoFill()) {
|
||||
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) {
|
||||
if (solidFill.isSetSchemeClr()) {
|
||||
// if there's a reference to the placeholder color,
|
||||
|
@ -379,7 +383,8 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
|
||||
return DrawPaint.createSolidPaint(c.getColorStyle());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
|
||||
final CTBlip blip = blipFill.getBlip();
|
||||
return new TexturePaint() {
|
||||
|
@ -413,17 +418,17 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
|
||||
|
||||
Arrays.sort(gs, new Comparator<CTGradientStop>() {
|
||||
public int compare(CTGradientStop o1, CTGradientStop o2) {
|
||||
Integer pos1 = o1.getPos();
|
||||
Integer pos2 = o2.getPos();
|
||||
return pos1.compareTo(pos2);
|
||||
}
|
||||
Arrays.sort(gs, (o1, o2) -> {
|
||||
Integer pos1 = o1.getPos();
|
||||
Integer pos2 = o2.getPos();
|
||||
return pos1.compareTo(pos2);
|
||||
});
|
||||
|
||||
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) {
|
||||
if (fillRef == null) return null;
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFra
|
|||
public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow>,
|
||||
TableShape<XSLFShape,XSLFTextParagraph> {
|
||||
/* 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 List<XSLFTableRow> _rows;
|
||||
|
@ -60,7 +59,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
|||
CTGraphicalObjectData god = shape.getGraphic().getGraphicData();
|
||||
XmlCursor xc = god.newCursor();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -174,7 +173,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
|||
CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData();
|
||||
XmlCursor grCur = gr.newCursor();
|
||||
grCur.toNextToken();
|
||||
grCur.beginElement(new QName(DRAWINGML_URI, "tbl"));
|
||||
grCur.beginElement(new QName(XSLFRelation.NS_DRAWINGML, "tbl"));
|
||||
|
||||
CTTable tbl = CTTable.Factory.newInstance();
|
||||
tbl.addNewTblPr();
|
||||
|
@ -191,6 +190,7 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
|||
/**
|
||||
* Merge cells of a table
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
|
||||
if(firstRow > lastRow) {
|
||||
|
@ -225,14 +225,14 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
|||
if(i == firstRow) {
|
||||
cell.setRowSpan(rowSpan);
|
||||
} else {
|
||||
cell.setVMerge(true);
|
||||
cell.setVMerge();
|
||||
}
|
||||
}
|
||||
if(mergeColumnRequired) {
|
||||
if(colPos == firstCol) {
|
||||
cell.setGridSpan(colSpan);
|
||||
} else {
|
||||
cell.setHMerge(true);
|
||||
cell.setHMerge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.CTPoint2D;
|
||||
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.CTSolidColorFillProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
|
||||
|
@ -104,6 +103,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
|
|||
return cell;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected CTTableCellProperties getCellProperties(boolean create) {
|
||||
if (_tcPr == null) {
|
||||
CTTableCell cell = getCell();
|
||||
|
@ -251,6 +251,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
|
|||
setBorderWidth(edge, width);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public Double getBorderWidth(BorderEdge edge) {
|
||||
CTLineProperties ln = getCTLine(edge, false);
|
||||
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);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public Color getBorderColor(BorderEdge edge) {
|
||||
CTLineProperties ln = getCTLine(edge, false);
|
||||
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) {
|
||||
|
@ -331,6 +333,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
|
|||
return c.getColor();
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public LineCompound getBorderCompound(BorderEdge edge) {
|
||||
CTLineProperties ln = getCTLine(edge, false);
|
||||
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));
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public LineDash getBorderDash(BorderEdge edge) {
|
||||
CTLineProperties ln = getCTLine(edge, false);
|
||||
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));
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public LineCap getBorderCap(BorderEdge edge) {
|
||||
CTLineProperties ln = getCTLine(edge, false);
|
||||
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());
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public void setBorderCap(BorderEdge edge, LineCap cap) {
|
||||
if (cap == null) {
|
||||
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;
|
||||
}
|
||||
|
||||
void setHMerge(boolean merge_) {
|
||||
getCell().setHMerge(merge_);
|
||||
void setHMerge() {
|
||||
getCell().setHMerge(true);
|
||||
}
|
||||
|
||||
void setVMerge(boolean merge_) {
|
||||
getCell().setVMerge(merge_);
|
||||
void setVMerge() {
|
||||
getCell().setVMerge(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -715,13 +721,13 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
|
|||
/**
|
||||
* @since POI 3.15-beta2
|
||||
*/
|
||||
private class XSLFCellTextParagraph extends XSLFTextParagraph {
|
||||
protected XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) {
|
||||
private final class XSLFCellTextParagraph extends XSLFTextParagraph {
|
||||
private XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) {
|
||||
super(p, shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XSLFCellTextRun newTextRun(CTRegularTextRun r) {
|
||||
protected XSLFCellTextRun newTextRun(XmlObject r) {
|
||||
return new XSLFCellTextRun(r, this);
|
||||
}
|
||||
}
|
||||
|
@ -729,8 +735,8 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
|
|||
/**
|
||||
* @since POI 3.15-beta2
|
||||
*/
|
||||
private class XSLFCellTextRun extends XSLFTextRun {
|
||||
protected XSLFCellTextRun(CTRegularTextRun r, XSLFTextParagraph p) {
|
||||
private final class XSLFCellTextRun extends XSLFTextRun {
|
||||
private XSLFCellTextRun(XmlObject r, XSLFTextParagraph p) {
|
||||
super(r, p);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
|
|||
/*package*/ XSLFTableRow(CTTableRow row, XSLFTable table){
|
||||
_row = row;
|
||||
_table = table;
|
||||
@SuppressWarnings("deprecation")
|
||||
CTTableCell[] tcArray = _row.getTcArray();
|
||||
_cells = new ArrayList<>(tcArray.length);
|
||||
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 lastCol 0-based index of last column to merge, inclusive
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public void mergeCells(int firstCol, int lastCol)
|
||||
{
|
||||
if (firstCol >= lastCol) {
|
||||
|
@ -99,7 +101,7 @@ public class XSLFTableRow implements Iterable<XSLFTableCell> {
|
|||
|
||||
_cells.get(firstCol).setGridSpan(colSpan);
|
||||
for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) {
|
||||
cell.setHMerge(true);
|
||||
cell.setHMerge();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
// 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);
|
||||
// don't copy hlink properties
|
||||
if (brProps.isSetHlinkClick()) {
|
||||
brProps.unsetHlinkClick();
|
||||
}
|
||||
if (brProps.isSetHlinkMouseOver()) {
|
||||
brProps.unsetHlinkMouseOver();
|
||||
}
|
||||
}
|
||||
_runs.add(run);
|
||||
return run;
|
||||
|
@ -188,6 +195,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
*
|
||||
* @param align font align
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void setFontAlign(FontAlign align){
|
||||
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
|
||||
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
|
||||
* 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);
|
||||
String defaultStyleSelector;
|
||||
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
|
||||
final String nsPML = "http://schemas.openxmlformats.org/presentationml/2006/main";
|
||||
final String nsDML = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
||||
XSLFSheet masterSheet = _shape.getSheet();
|
||||
for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
|
||||
masterSheet = m;
|
||||
|
@ -752,7 +759,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
(cur.pop() && cur.toChild(nsPML, "notesStyle"))) {
|
||||
while (level >= 0) {
|
||||
cur.push();
|
||||
if (cur.toChild(nsDML, "lvl" +(level+1)+ "pPr")) {
|
||||
if (cur.toChild(XSLFRelation.NS_DRAWINGML, "lvl" +(level+1)+ "pPr")) {
|
||||
return (CTTextParagraphProperties)cur.getObject();
|
||||
}
|
||||
cur.pop();
|
||||
|
@ -788,11 +795,13 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
fetchMasterProperty(visitor);
|
||||
}
|
||||
|
||||
boolean fetchMasterProperty(final ParagraphPropertyFetcher<?> visitor) {
|
||||
void fetchMasterProperty(final ParagraphPropertyFetcher<?> visitor) {
|
||||
// defaults for placeholders are defined in the slide master
|
||||
final CTTextParagraphProperties defaultProps = getDefaultMasterStyle();
|
||||
// TODO: determine master shape
|
||||
return defaultProps != null && visitor.fetch(defaultProps);
|
||||
if (defaultProps != null) {
|
||||
visitor.fetch(defaultProps);
|
||||
}
|
||||
}
|
||||
|
||||
boolean fetchThemeProperty(final ParagraphPropertyFetcher<?> visitor) {
|
||||
|
@ -836,15 +845,15 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
otherC.dispose();
|
||||
thisC.dispose();
|
||||
|
||||
List<XSLFTextRun> otherRs = other.getTextRuns();
|
||||
int i=0;
|
||||
for(CTRegularTextRun rtr : thisP.getRList()) {
|
||||
XSLFTextRun run = newTextRun(rtr);
|
||||
run.copy(otherRs.get(i++));
|
||||
for (XSLFTextRun tr : other.getTextRuns()) {
|
||||
XmlObject xo = tr.getXmlObject();
|
||||
XSLFTextRun run = (xo instanceof CTTextLineBreak)
|
||||
? newTextRun((CTTextLineBreak)xo)
|
||||
: newTextRun(xo);
|
||||
run.copy(tr);
|
||||
_runs.add(run);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set properties again, in case we are based on a different
|
||||
// template
|
||||
TextAlign srcAlign = other.getTextAlign();
|
||||
|
@ -998,6 +1007,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
public boolean fetch(CTTextParagraphProperties props) {
|
||||
if (props.isSetTabLst()) {
|
||||
final List<XSLFTabStop> list = new ArrayList<>();
|
||||
//noinspection deprecation
|
||||
for (final CTTextTabStop ta : props.getTabLst().getTabArray()) {
|
||||
list.add(new XSLFTabStop(ta));
|
||||
}
|
||||
|
@ -1021,6 +1031,10 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
final CTTextParagraph xo = getXmlObject();
|
||||
tpp = (xo.isSetPPr()) ? xo.getPPr() : xo.addNewPPr();
|
||||
}
|
||||
|
||||
if (tpp == null) {
|
||||
return;
|
||||
}
|
||||
final CTTextTabStopList stl = (tpp.isSetTabLst()) ? tpp.getTabLst() : tpp.addNewTabLst();
|
||||
XSLFTabStop tab = new XSLFTabStop(stl.addNewTab());
|
||||
tab.setPositionInPoints(positionInPoints);
|
||||
|
@ -1090,7 +1104,12 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
|
|||
*
|
||||
* @since POI 3.15-beta2
|
||||
*/
|
||||
protected XSLFTextRun newTextRun(CTRegularTextRun r) {
|
||||
protected XSLFTextRun newTextRun(XmlObject r) {
|
||||
return new XSLFTextRun(r, this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected XSLFTextRun newTextRun(CTTextLineBreak r) {
|
||||
return new XSLFLineBreak(r, this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -581,6 +581,12 @@ public class XSLFTextRun implements TextRun {
|
|||
if(strike != isStrikethrough()) {
|
||||
setStrikethrough(strike);
|
||||
}
|
||||
|
||||
XSLFHyperlink hyperSrc = r.getHyperlink();
|
||||
if (hyperSrc != null) {
|
||||
XSLFHyperlink hyperDst = getHyperlink();
|
||||
hyperDst.copy(hyperSrc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.CTColorScheme;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
|
||||
|
||||
/**
|
||||
|
@ -66,6 +65,7 @@ public class XSLFTheme extends POIXMLDocumentPart {
|
|||
initialize();
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public void importTheme(XSLFTheme theme) {
|
||||
_theme = theme.getXmlObject();
|
||||
_schemeColors = theme._schemeColors;
|
||||
|
@ -134,7 +134,7 @@ public class XSLFTheme extends POIXMLDocumentPart {
|
|||
protected final void commit() throws IOException {
|
||||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
xmlOptions.setSaveSyntheticDocumentElement(
|
||||
new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "theme"));
|
||||
new QName(XSLFRelation.NS_DRAWINGML, "theme"));
|
||||
|
||||
PackagePart part = getPackagePart();
|
||||
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.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public String getMajorFont(){
|
||||
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.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public String getMinorFont(){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.apache.poi.xslf.usermodel.XSLFSlideMaster;
|
|||
import org.apache.poi.xslf.usermodel.XSLFTable;
|
||||
import org.apache.poi.xslf.usermodel.XSLFTableCell;
|
||||
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.XSLFTextRun;
|
||||
import org.junit.Ignore;
|
||||
|
@ -92,6 +93,54 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
|||
public class TestXSLFBugs {
|
||||
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
|
||||
public void bug62587() throws IOException {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
|
Loading…
Reference in New Issue