#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
1691c2372a
commit
1407ace4f7
@ -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;
|
||||||
|
47
src/java/org/apache/poi/sl/usermodel/AbstractColorStyle.java
Normal file
47
src/java/org/apache/poi/sl/usermodel/AbstractColorStyle.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user