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;
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());
public int getShade() { return -1; }
@Override
public int getTint() { return -1; }
+
+
};
}
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) {
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();
return applyColorTransform(cs);
}
+ @SuppressWarnings("WeakerAccess")
protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) {
switch (fill.getGradientType()) {
case linear:
}
}
+ @SuppressWarnings("WeakerAccess")
protected Paint getTexturePaint(TexturePaint fill, Graphics2D graphics) {
InputStream is = fill.getImageData();
if (is == null) {
* @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) {
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
return new LinearGradientPaint(p1, p2, fractions, colors);
}
+ @SuppressWarnings("WeakerAccess")
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
return new RadialGradientPaint(pCenter, radius, fractions, colors);
}
+ @SuppressWarnings({"WeakerAccess", "unused"})
protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) {
// currently we ignore an eventually center setting
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.
*
// Calculate the Saturation
- double s = 0;
+ final double s;
if (max == min) {
s = 0;
--- /dev/null
+/* ====================================================================
+ 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();
+ }
+
+}
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;
private Color _color;
private CTSchemeColor _phClr;
+ @SuppressWarnings("WeakerAccess")
public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) {
_xmlObject = obj;
_phClr = phClr;
return DrawPaint.applyColorTransform(getColorStyle());
}
+ @SuppressWarnings("WeakerAccess")
public ColorStyle getColorStyle() {
- return new ColorStyle() {
+ return new AbstractColorStyle() {
@Override
public Color getColor() {
return _color;
};
}
- 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) {
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());
}
}
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
*
}
+ @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");
}
* @return luminance in percents in the range [0..100]
* or -1 if the value is not set
*/
+ @SuppressWarnings("unused")
int getLum(){
return getPercentageValue("lum");
}
return getPercentageValue("red");
}
+ @SuppressWarnings("unused")
int getRedMod(){
return getPercentageValue("redMod");
}
+ @SuppressWarnings("unused")
int getRedOff(){
return getPercentageValue("redOff");
}
return getPercentageValue("green");
}
+ @SuppressWarnings("unused")
int getGreenMod(){
return getPercentageValue("greenMod");
}
+ @SuppressWarnings("unused")
int getGreenOff(){
return getPercentageValue("greenOff");
}
return getPercentageValue("blue");
}
+ @SuppressWarnings("unused")
int getBlueMod(){
return getPercentageValue("blueMod");
}
+ @SuppressWarnings("unused")
int getBlueOff(){
return getPercentageValue("blueOff");
}
* 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");
}
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;
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);
}
}
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
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;
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");
}
return _nvPr;
}
+ @SuppressWarnings("WeakerAccess")
protected CTShapeStyle getSpStyle() {
if (_spStyle == null) {
_spStyle = getChild(CTShapeStyle.class, PML_NS, "style");
* @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();
/**
* @see SimpleShape#getPlaceholderDetails()
*/
+ @SuppressWarnings("WeakerAccess")
public XSLFPlaceholderDetails getPlaceholderDetails() {
return new XSLFPlaceholderDetails(this);
}
* @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;
* @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)) {
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;
*
* @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;
}
}
+ @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,
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() {
}
};
}
-
+
+ @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];
};
}
+ @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
if (fillRef == null) return null;
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;
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);
}
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();
/**
* Merge cells of a table
*/
+ @SuppressWarnings("unused")
public void mergeCells(int firstRow, int lastRow, int firstCol, int lastCol) {
if(firstRow > lastRow) {
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();
}
}
}
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;
return cell;
}
+ @SuppressWarnings("WeakerAccess")
protected CTTableCellProperties getCellProperties(boolean create) {
if (_tcPr == null) {
CTTableCell cell = getCell();
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());
c.setColor(color);
}
+ @SuppressWarnings("WeakerAccess")
public Color getBorderColor(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) {
return c.getColor();
}
+ @SuppressWarnings("WeakerAccess")
public LineCompound getBorderCompound(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) {
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()) {
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()) {
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.");
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
/**
* @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);
}
}
/**
* @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);
}
/*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) {
* @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) {
_cells.get(firstCol).setGridSpan(colSpan);
for (final XSLFTableCell cell : _cells.subList(firstCol+1, lastCol+1)) {
- cell.setHMerge(true);
+ cell.setHMerge();
}
}
// 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;
*
* @param align font align
*/
+ @SuppressWarnings("unused")
public void setFontAlign(FontAlign align){
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
if(align == null) {
* @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()) {
// 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;
(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();
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) {
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();
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));
}
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);
*
* @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);
+ }
}
if(strike != isStrikethrough()) {
setStrikethrough(strike);
}
+
+ XSLFHyperlink hyperSrc = r.getHyperlink();
+ if (hyperSrc != null) {
+ XSLFHyperlink hyperDst = getHyperlink();
+ hyperDst.copy(hyperSrc);
+ }
}
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;
/**
initialize();
}
+ @SuppressWarnings("WeakerAccess")
public void importTheme(XSLFTheme theme) {
_theme = theme.getXmlObject();
_schemeColors = theme._schemeColors;
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();
* Typically the major font is used for heading areas of a document.
*
*/
+ @SuppressWarnings("WeakerAccess")
public String getMajorFont(){
return _theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface();
}
* 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;
- }
}
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;
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();