aboutsummaryrefslogtreecommitdiffstats
path: root/src/ooxml/java
diff options
context:
space:
mode:
authorYegor Kozlov <yegor@apache.org>2011-08-11 08:38:19 +0000
committerYegor Kozlov <yegor@apache.org>2011-08-11 08:38:19 +0000
commitccad96e6d9e296958d03d90d44e70888f45ba8b9 (patch)
treebdb50d2be1e034bbbe951d8f6bd8e434ec773029 /src/ooxml/java
parenteb89ca36858a3aa86bf4a7db2a9c19081dbc69d9 (diff)
downloadpoi-ccad96e6d9e296958d03d90d44e70888f45ba8b9.tar.gz
poi-ccad96e6d9e296958d03d90d44e70888f45ba8b9.zip
initial support for XSLF usermodel API
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1156539 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/ooxml/java')
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/util/Units.java17
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java18
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java79
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java6
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java4
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java6
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java4
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/LineCap.java19
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/LineDash.java17
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java29
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java14
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java14
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java36
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/TextAlign.java47
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/TextAutofit.java59
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/TextDirection.java48
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/VerticalAlignment.java71
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java346
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java427
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java2
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java195
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java84
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java81
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java178
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java79
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java220
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java171
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java107
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java68
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java48
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java219
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java268
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java172
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java103
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java90
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java97
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java334
-rwxr-xr-xsrc/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java202
38 files changed, 3760 insertions, 219 deletions
diff --git a/src/ooxml/java/org/apache/poi/util/Units.java b/src/ooxml/java/org/apache/poi/util/Units.java
new file mode 100755
index 0000000000..59ce34cdfa
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/util/Units.java
@@ -0,0 +1,17 @@
+package org.apache.poi.util;
+
+/**
+ * @author Yegor Kozlov
+ */
+public class Units {
+ public static final int EMU_PER_PIXEL = 9525;
+ public static final int EMU_PER_POINT = 12700;
+
+ public static int toEMU(double value){
+ return (int)Math.round(EMU_PER_POINT*value);
+ }
+
+ public static double toPoints(long emu){
+ return (double)emu/EMU_PER_POINT;
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
index 05351c689c..d2986dc3fc 100644
--- a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
@@ -16,20 +16,16 @@
==================================================================== */
package org.apache.poi.xslf;
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-
import org.apache.poi.POIXMLDocument;
-import org.apache.poi.util.Internal;
-import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.util.Internal;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
@@ -46,6 +42,10 @@ import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument
import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
/**
* Experimental class to do low level processing of pptx files.
*
@@ -80,10 +80,10 @@ public class XSLFSlideShow extends POIXMLDocument {
for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdList()) {
PackagePart slidePart =
getTargetPart(getCorePart().getRelationship(ctSlide.getId2()));
-
+
for(PackageRelationship rel : slidePart.getRelationshipsByType(OLE_OBJECT_REL_TYPE))
embedds.add(getTargetPart(rel)); // TODO: Add this reference to each slide as well
-
+
for(PackageRelationship rel : slidePart.getRelationshipsByType(PACK_OBJECT_REL_TYPE))
embedds.add(getTargetPart(rel));
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java b/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
index d20a357964..773e0f458b 100644
--- a/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
+++ b/src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
@@ -26,7 +26,10 @@ import org.apache.poi.xslf.usermodel.XSLFCommonSlideData;
import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.presentationml.x2006.main.*;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTComment;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
import java.io.IOException;
@@ -42,11 +45,11 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
private boolean notesByDefault = false;
public XSLFPowerPointExtractor(XMLSlideShow slideshow) {
- super(slideshow._getXSLFSlideShow());
+ super(slideshow);
this.slideshow = slideshow;
}
public XSLFPowerPointExtractor(XSLFSlideShow slideshow) throws XmlException, IOException {
- this(new XMLSlideShow(slideshow));
+ this(new XMLSlideShow(slideshow.getPackage()));
}
public XSLFPowerPointExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
this(new XSLFSlideShow(container));
@@ -55,7 +58,7 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
public static void main(String[] args) throws Exception {
if(args.length < 1) {
System.err.println("Use:");
- System.err.println(" HXFPowerPointExtractor <filename.pptx>");
+ System.err.println(" XSLFPowerPointExtractor <filename.pptx>");
System.exit(1);
}
POIXMLTextExtractor extractor =
@@ -95,41 +98,41 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
StringBuffer text = new StringBuffer();
XSLFSlide[] slides = slideshow.getSlides();
- for(int i = 0; i < slides.length; i++) {
- CTSlide rawSlide = slides[i]._getCTSlide();
- CTSlideIdListEntry slideId = slides[i]._getCTSlideId();
-
- try {
- // For now, still very low level
- CTNotesSlide notes =
- slideshow._getXSLFSlideShow().getNotes(slideId);
- CTCommentList comments =
- slideshow._getXSLFSlideShow().getSlideComments(slideId);
-
- if(slideText) {
- extractText(slides[i].getCommonSlideData(), text);
-
- // Comments too for the slide
- if(comments != null) {
- for(CTComment comment : comments.getCmList()) {
- // TODO - comment authors too
- // (They're in another stream)
- text.append(
- comment.getText() + "\n"
- );
- }
- }
- }
+ try {
+ XSLFSlideShow xsl = new XSLFSlideShow(slideshow.getPackage());
+ for (int i = 0; i < slides.length; i++) {
+ CTSlideIdListEntry slideId = slideshow.getCTPresentation().getSldIdLst().getSldIdArray(i);
- if(notesText && notes != null) {
- extractText(new XSLFCommonSlideData(notes.getCSld()), text);
- }
- } catch(Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- return text.toString();
+ // For now, still very low level
+ CTNotesSlide notes =
+ xsl.getNotes(slideId);
+ CTCommentList comments =
+ xsl.getSlideComments(slideId);
+
+ if (slideText) {
+ extractText(new XSLFCommonSlideData(slides[i].getXmlObject().getCSld()), text);
+
+ // Comments too for the slide
+ if (comments != null) {
+ for (CTComment comment : comments.getCmList()) {
+ // TODO - comment authors too
+ // (They're in another stream)
+ text.append(
+ comment.getText() + "\n"
+ );
+ }
+ }
+ }
+
+ if (notesText && notes != null) {
+ extractText(new XSLFCommonSlideData(notes.getCSld()), text);
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return text.toString();
}
private void extractText(XSLFCommonSlideData data, StringBuffer text) {
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java
index f1e84ce6c1..2e755583bb 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingParagraph.java
@@ -17,11 +17,11 @@
package org.apache.poi.xslf.usermodel;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
public class DrawingParagraph {
private final CTTextParagraph p;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java
index e221cfa7cc..c6d7da9f2b 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTable.java
@@ -17,11 +17,11 @@
package org.apache.poi.xslf.usermodel;
-import java.util.List;
-
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
+import java.util.List;
+
public class DrawingTable {
private final CTTable table;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java
index 213dd638d6..27b79ea33e 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTableRow.java
@@ -17,10 +17,10 @@
package org.apache.poi.xslf.usermodel;
-import java.util.List;
-
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
+
+import java.util.List;
public class DrawingTableRow {
private final CTTableRow row;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java
index 68a12a4d1c..1f40841d35 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/DrawingTextBody.java
@@ -17,11 +17,11 @@
package org.apache.poi.xslf.usermodel;
-import java.util.List;
-
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
+import java.util.List;
+
public class DrawingTextBody {
private final CTTextBody textBody;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineCap.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineCap.java
new file mode 100755
index 0000000000..140f48bf0b
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineCap.java
@@ -0,0 +1,19 @@
+package org.apache.poi.xslf.usermodel;
+
+/**
+ */
+public enum LineCap {
+ /**
+ * Rounded ends - the default
+ */
+ ROUND,
+ /**
+ * Square protrudes by half line width
+ */
+ SQUARE,
+
+ /**
+ * Line ends at end point
+ */
+ FLAT;
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDash.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDash.java
new file mode 100755
index 0000000000..83b29be1c0
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDash.java
@@ -0,0 +1,17 @@
+package org.apache.poi.xslf.usermodel;
+
+/**
+ */
+public enum LineDash {
+ SOLID,
+ DOT,
+ DASH,
+ LG_DASH,
+ DASH_DOT,
+ LG_DASH_DOT,
+ LG_DASH_DOT_DOT,
+ SYS_DASH,
+ SYS_DOT,
+ SYS_DASH_DOT,
+ SYS_DASH_DOT_DOT;
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java
new file mode 100644
index 0000000000..72b28c0b34
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java
@@ -0,0 +1,29 @@
+/* ====================================================================
+ 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.xslf.usermodel;
+
+/**
+ * Represents the shape decoration that appears at the ends of lines.
+ */
+public enum LineDecoration {
+ NONE,
+ TRIANGLE,
+ STEALTH,
+ DIAMOND,
+ OVAL,
+ ARROW
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java
new file mode 100644
index 0000000000..a66623bca7
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java
@@ -0,0 +1,14 @@
+package org.apache.poi.xslf.usermodel;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: yegor
+ * Date: Aug 9, 2011
+ * Time: 9:39:26 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public enum LineEndLength {
+ SMALL,
+ MEDIUM,
+ LARGE
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java
new file mode 100644
index 0000000000..5d2d3b86a2
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java
@@ -0,0 +1,14 @@
+package org.apache.poi.xslf.usermodel;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: yegor
+ * Date: Aug 9, 2011
+ * Time: 9:39:26 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public enum LineEndWidth {
+ SMALL,
+ MEDIUM,
+ LARGE
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java
new file mode 100755
index 0000000000..0e958015ed
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/Placeholder.java
@@ -0,0 +1,36 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+/**
+ * @author Yegor Kozlov
+ */
+public enum Placeholder {
+ TITLE,
+ BODY,
+ CENTERED_TITLE,
+ SUBTITLE,
+ DATETIME,
+ SLIDE_NUMBER,
+ FOOTER,
+ HEADER,
+ OBJECT,
+ CHART,
+ TABLE
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAlign.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAlign.java
new file mode 100755
index 0000000000..c712dbacef
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAlign.java
@@ -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.xslf.usermodel;
+
+/**
+ * Specified a list of text alignment types
+ *
+ * @author Yegor Kozlov
+ */
+public enum TextAlign {
+ /**
+ * Align text to the left margin.
+ */
+ LEFT,
+ /**
+ * Align text in the center.
+ */
+ CENTER,
+
+ /**
+ * Align text to the right margin.
+ */
+ RIGHT,
+
+ /**
+ * Align text so that it is justified across the whole line. It
+ * is smart in the sense that it will not justify sentences
+ * which are short
+ */
+ JUSTIFY
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAutofit.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAutofit.java
new file mode 100644
index 0000000000..94d6b24358
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextAutofit.java
@@ -0,0 +1,59 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+/**
+ * Specifies alist of auto-fit types.
+ * <p>
+ * Autofit specofies that a shape should be auto-fit to fully contain the text described within it.
+ * Auto-fitting is when text within a shape is scaled in order to contain all the text inside
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public enum TextAutofit {
+ /**
+ * Specifies that text within the text body should not be auto-fit to the bounding box.
+ * Auto-fitting is when text within a text box is scaled in order to remain inside
+ * the text box.
+ */
+ NONE,
+ /**
+ * Specifies that text within the text body should be normally auto-fit to the bounding box.
+ * Autofitting is when text within a text box is scaled in order to remain inside the text box.
+ *
+ * <p>
+ * <em>Example:</em> Consider the situation where a user is building a diagram and needs
+ * to have the text for each shape that they are using stay within the bounds of the shape.
+ * An easy way this might be done is by using NORMAL autofit
+ * </p>
+ */
+ NORMAL,
+ /**
+ * Specifies that a shape should be auto-fit to fully contain the text described within it.
+ * Auto-fitting is when text within a shape is scaled in order to contain all the text inside.
+ *
+ * <p>
+ * <em>Example:</em> Consider the situation where a user is building a diagram and needs to have
+ * the text for each shape that they are using stay within the bounds of the shape.
+ * An easy way this might be done is by using SHAPE autofit
+ * </p>
+ */
+ SHAPE
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/TextDirection.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextDirection.java
new file mode 100644
index 0000000000..3f35ec23ac
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/TextDirection.java
@@ -0,0 +1,48 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+/**
+ * Vertical Text Types
+ */
+public enum TextDirection {
+ /**
+ * Horizontal text. This should be default.
+ */
+ HORIZONTAL,
+ /**
+ * Vertical orientation.
+ * (each line is 90 degrees rotated clockwise, so it goes
+ * from top to bottom; each next line is to the left from
+ * the previous one).
+ */
+ VERTICAL,
+ /**
+ * Vertical orientation.
+ * (each line is 270 degrees rotated clockwise, so it goes
+ * from bottom to top; each next line is to the right from
+ * the previous one).
+ */
+ VERTICAL_270,
+ /**
+ * Determines if all of the text is vertical
+ * ("one letter on top of another").
+ */
+ STACKED;
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/VerticalAlignment.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/VerticalAlignment.java
new file mode 100755
index 0000000000..fd00a64e26
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/VerticalAlignment.java
@@ -0,0 +1,71 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+/**
+ * Specifies a list of available anchoring types for text
+ *
+ * @author Yegor Kozlov
+ */
+public enum VerticalAlignment {
+ /**
+ * Anchor the text at the top of the bounding rectangle
+ */
+ TOP,
+
+ /**
+ * Anchor the text at the middle of the bounding rectangle
+ */
+ MIDDLE,
+
+ /**
+ * Anchor the text at the bottom of the bounding rectangle.
+ */
+ BOTTOM,
+
+ /**
+ * Anchor the text so that it is justified vertically.
+ * <p>
+ * When text is horizontal, this spaces out the actual lines of
+ * text and is almost always identical in behavior to
+ * {@link #DISTRIBUTED} (special case: if only 1 line, then anchored at top).
+ * </p>
+ * <p>
+ * When text is vertical, then it justifies the letters
+ * vertically. This is different than {@link #DISTRIBUTED},
+ * because in some cases such as very little text in a line,
+ * it will not justify.
+ * </p>
+ */
+ JUSTIFIED,
+
+ /**
+ * Anchor the text so that it is distributed vertically.
+ * <p>
+ * When text is horizontal, this spaces out the actual lines
+ * of text and is almost always identical in behavior to
+ * {@link #JUSTIFIED} (special case: if only 1 line, then anchored in middle).
+ * </p>
+ * <p>
+ * When text is vertical, then it distributes the letters vertically.
+ * This is different than {@link #JUSTIFIED}, because it always forces distribution
+ * of the words, even if there are only one or two words in a line.
+ */
+ DISTRIBUTED
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
index ab5c670b9f..7c2db9bb45 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
@@ -16,20 +16,42 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import java.io.IOException;
-
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.xslf.XSLFSlideShow;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
-import org.apache.poi.sl.usermodel.MasterSheet;
-import org.apache.poi.sl.usermodel.Resources;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
-import org.apache.poi.xslf.XSLFSlideShow;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.PackageHelper;
+import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideSize;
+import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument;
+
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
/**
* High level representation of a ooxml slideshow.
@@ -37,57 +59,261 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList;
* they are reading or writing a slideshow. It is also the
* top level object for creating new slides/etc.
*/
-public class XMLSlideShow implements SlideShow {
- private XSLFSlideShow slideShow;
- private XSLFSlide[] slides;
-
- public XMLSlideShow(XSLFSlideShow xml) throws XmlException, IOException {
- this.slideShow = xml;
-
- // Build the main masters list - TODO
- CTSlideMasterIdList masterIds = slideShow.getSlideMasterReferences();
-
- // Build the slides list
- CTSlideIdList slideIds = slideShow.getSlideReferences();
- slides = new XSLFSlide[slideIds.getSldIdList().size()];
- for(int i=0; i<slides.length; i++) {
- CTSlideIdListEntry slideId = slideIds.getSldIdArray(i);
- CTSlide slide = slideShow.getSlide(slideId);
- slides[i] = new XSLFSlide(slide, slideId, this);
- }
-
- // Build the notes list - TODO
- }
-
- public XMLSlideShow(OPCPackage pkg) throws XmlException, IOException, OpenXML4JException {
- this(new XSLFSlideShow(pkg));
- }
-
- public XSLFSlideShow _getXSLFSlideShow() {
- return slideShow;
- }
-
- public MasterSheet createMasterSheet() throws IOException {
- throw new IllegalStateException("Not implemented yet!");
- }
- public Slide createSlide() throws IOException {
- throw new IllegalStateException("Not implemented yet!");
- }
-
- public MasterSheet[] getMasterSheet() {
- // TODO Auto-generated method stub
- return null;
- }
-
- /**
- * Return all the slides in the slideshow
- */
- public XSLFSlide[] getSlides() {
- return slides;
- }
-
- public Resources getResources() {
- // TODO Auto-generated method stub
- return null;
- }
+@Beta
+public class XMLSlideShow extends POIXMLDocument {
+
+ private static POILogger _logger = POILogFactory.getLogger(XMLSlideShow.class);
+
+ private CTPresentation _presentation;
+ private List<XSLFSlide> _slides;
+ private Map<String, XSLFSlideMaster> _masters;
+ protected List<XSLFPictureData> _pictures;
+
+ public XMLSlideShow() {
+ this(empty());
+ }
+
+ public XMLSlideShow(OPCPackage pkg) {
+ super(pkg);
+
+ try {
+ if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) {
+ rebase(getPackage());
+ }
+
+ //build a tree of POIXMLDocumentParts, this presentation being the root
+ load(XSLFFactory.getInstance());
+ } catch (Exception e){
+ throw new POIXMLException(e);
+ }
+ }
+
+ public XMLSlideShow(InputStream is) throws IOException {
+ this(PackageHelper.open(is));
+ }
+
+ static final OPCPackage empty() {
+ InputStream is = XMLSlideShow.class.getResourceAsStream("empty.pptx");
+ if (is == null) {
+ throw new RuntimeException("Missing resource 'empty.pptx'");
+ }
+ try {
+ return OPCPackage.open(is);
+ } catch (Exception e){
+ throw new POIXMLException(e);
+ }
+ }
+
+ // TODO get rid of this method
+ @Deprecated
+ public XSLFSlideShow _getXSLFSlideShow() throws OpenXML4JException, IOException, XmlException{
+ return new XSLFSlideShow(getPackage());
+ }
+
+ @Override
+ protected void onDocumentRead() throws IOException {
+ try {
+ PresentationDocument doc =
+ PresentationDocument.Factory.parse(getCorePart().getInputStream());
+ _presentation = doc.getPresentation();
+ Map<String, XSLFSlide> shIdMap = new HashMap<String, XSLFSlide>();
+
+ _masters = new HashMap<String, XSLFSlideMaster>();
+ for (POIXMLDocumentPart p : getRelations()) {
+ if (p instanceof XSLFSlide) {
+ shIdMap.put(p.getPackageRelationship().getId(), (XSLFSlide) p);
+ } else if (p instanceof XSLFSlideMaster){
+ XSLFSlideMaster master = (XSLFSlideMaster)p;
+ _masters.put(p.getPackageRelationship().getId(), master);
+ }
+ }
+
+ _slides = new ArrayList<XSLFSlide>();
+ if (_presentation.isSetSldIdLst()) {
+ List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList();
+ for (CTSlideIdListEntry slId : slideIds) {
+ XSLFSlide sh = shIdMap.get(slId.getId2());
+ if (sh == null) {
+ _logger.log(POILogger.WARN, "Slide with r:id " + slId.getId() + " was defined, but didn't exist in package, skipping");
+ continue;
+ }
+ _slides.add(sh);
+ }
+ }
+ } catch (XmlException e) {
+ throw new POIXMLException(e);
+ }
+ }
+
+
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ _presentation.save(out, xmlOptions);
+ out.close();
+ }
+
+ /**
+ * Get the document's embedded files.
+ */
+ public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
+ return Collections.unmodifiableList(
+ getPackage().getPartsByName(Pattern.compile("/ppt/embeddings/.*?"))
+ );
+ }
+
+ /**
+ * Returns all Pictures, which are referenced from the document itself.
+ * @return a {@link List} of {@link PackagePart}.
+ * The returned {@link List} is unmodifiable.
+ */
+ public List<XSLFPictureData> getAllPictures() {
+ if(_pictures == null){
+ List<PackagePart> mediaParts = getPackage().getPartsByName(Pattern.compile("/ppt/media/.*?"));
+ _pictures = new ArrayList<XSLFPictureData>(mediaParts.size());
+ for(PackagePart part : mediaParts){
+ _pictures.add(new XSLFPictureData(part, null));
+ }
+ }
+ return Collections.unmodifiableList(_pictures);
+ }
+
+ public XSLFSlide createSlide() {
+ int slideNumber = 256, cnt = 1;
+ CTSlideIdList slideList;
+ if (!_presentation.isSetSldIdLst()) slideList = _presentation.addNewSldIdLst();
+ else {
+ slideList = _presentation.getSldIdLst();
+ for(CTSlideIdListEntry slideId : slideList.getSldIdList()){
+ slideNumber = (int)Math.max(slideId.getId() + 1, slideNumber);
+ cnt++;
+ }
+ }
+
+ XSLFSlide slide = (XSLFSlide)createRelationship(
+ XSLFRelation.SLIDE, XSLFFactory.getInstance(), cnt);
+
+ CTSlideIdListEntry slideId = slideList.addNewSldId();
+ slideId.setId(slideNumber);
+ slideId.setId2(slide.getPackageRelationship().getId());
+
+ String masterId = _presentation.getSldMasterIdLst().getSldMasterIdArray(0).getId2();
+ XSLFSlideMaster master = _masters.get(masterId);
+
+ XSLFSlideLayout layout = master.getLayout("blank");
+ if(layout == null) throw new IllegalArgumentException("Blank layout was not found");
+
+ slide.addRelation(layout.getPackageRelationship().getId(), layout);
+
+ PackagePartName ppName = layout.getPackagePart().getPartName();
+ slide.getPackagePart().addRelationship(ppName, TargetMode.INTERNAL,
+ layout.getPackageRelationship().getRelationshipType());
+
+ _slides.add(slide);
+ return slide;
+ }
+
+ public XSLFSlideMaster[] getSlideMasters() {
+ return _masters.values().toArray(new XSLFSlideMaster[_masters.size()]);
+ }
+
+ /**
+ * Return all the slides in the slideshow
+ */
+ public XSLFSlide[] getSlides() {
+ return _slides.toArray(new XSLFSlide[_slides.size()]);
+ }
+
+ /**
+ *
+ * @param newIndex 0-based index of the slide
+ */
+ public void setSlideOrder(XSLFSlide slide, int newIndex){
+ int oldIndex = _slides.indexOf(slide);
+ if(oldIndex == -1) throw new IllegalArgumentException("Slide not found");
+
+ // fix the usermodel container
+ _slides.add(newIndex, _slides.remove(oldIndex));
+
+ // fix ordering in the low-level xml
+ List<CTSlideIdListEntry> slideIds = _presentation.getSldIdLst().getSldIdList();
+ CTSlideIdListEntry oldEntry = slideIds.get(oldIndex);
+ slideIds.add(newIndex, oldEntry);
+ slideIds.remove(oldEntry);
+ }
+
+ public XSLFSlide removeSlide(int index){
+ XSLFSlide slide = _slides.remove(index);
+ removeRelation(slide);
+ _presentation.getSldIdLst().getSldIdList().remove(index);
+ return slide;
+ }
+
+ /**
+ * Returns the current page size
+ *
+ * @return the page size
+ */
+ public Dimension getPageSize(){
+ CTSlideSize sz = _presentation.getSldSz();
+ int cx = sz.getCx();
+ int cy = sz.getCy();
+ return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy));
+ }
+
+ /**
+ * Sets the page size to the given <code>Dimension</code> object.
+ *
+ * @param pgSize page size
+ */
+ public void setPageSize(Dimension pgSize){
+ CTSlideSize sz = CTSlideSize.Factory.newInstance();
+ sz.setCx(Units.toEMU(pgSize.getWidth()));
+ sz.setCy(Units.toEMU(pgSize.getHeight()));
+ _presentation.setSldSz(sz);
+ }
+
+
+ @Internal
+ public CTPresentation getCTPresentation(){
+ return _presentation;
+ }
+
+ /**
+ * Adds a picture to the workbook.
+ *
+ * @param pictureData The bytes of the picture
+ * @param format The format of the picture.
+ *
+ * @return the index to this picture (1 based).
+ * @see XSLFPictureData#PICTURE_TYPE_EMF
+ * @see XSLFPictureData#PICTURE_TYPE_WMF
+ * @see XSLFPictureData#PICTURE_TYPE_PICT
+ * @see XSLFPictureData#PICTURE_TYPE_JPEG
+ * @see XSLFPictureData#PICTURE_TYPE_PNG
+ * @see XSLFPictureData#PICTURE_TYPE_DIB
+ */
+ public int addPicture(byte[] pictureData, int format) {
+ getAllPictures();
+
+ int imageNumber = getPackage().getPartsByName(Pattern.compile("/ppt/media/.*?")).size() + 1;
+ XSLFPictureData img = (XSLFPictureData) createRelationship(
+ XSLFPictureData.RELATIONS[format], XSLFFactory.getInstance(), imageNumber, true);
+ _pictures.add(img);
+ try {
+ OutputStream out = img.getPackagePart().getOutputStream();
+ out.write(pictureData);
+ out.close();
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ }
+ return imageNumber - 1;
+ }
+
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
new file mode 100755
index 0000000000..1869749970
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java
@@ -0,0 +1,427 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Units;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
+import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a preset geometric shape.
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFAutoShape extends XSLFSimpleShape {
+ private final List<XSLFTextParagraph> _paragraphs;
+
+ /*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) {
+ super(shape, sheet);
+
+ _paragraphs = new ArrayList<XSLFTextParagraph>();
+ if (shape.isSetTxBody()) {
+ CTTextBody txBody = shape.getTxBody();
+ for (CTTextParagraph p : txBody.getPList()) {
+ _paragraphs.add(new XSLFTextParagraph(p));
+ }
+ }
+ }
+
+ /*package*/
+ static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) {
+ if (shape.getSpPr().isSetCustGeom()) {
+ return new XSLFFreeformShape(shape, sheet);
+ } else if (shape.getNvSpPr().getCNvSpPr().isSetTxBox()) {
+ return new XSLFTextBox(shape, sheet);
+ } else {
+ return new XSLFAutoShape(shape, sheet);
+ }
+ }
+
+ // textual properties
+ public String getText() {
+ StringBuilder out = new StringBuilder();
+ for (XSLFTextParagraph p : _paragraphs) {
+ if (out.length() > 0) out.append('\n');
+ out.append(p.getText());
+ }
+ return out.toString();
+ }
+
+ public List<XSLFTextParagraph> getTextParagraphs() {
+ return _paragraphs;
+ }
+
+ public XSLFTextParagraph addNewTextParagraph() {
+ CTShape shape = (CTShape) getXmlObject();
+ CTTextBody txBody;
+ if (!shape.isSetTxBody()) {
+ txBody = shape.addNewTxBody();
+ txBody.addNewBodyPr();
+ txBody.addNewLstStyle();
+ } else {
+ txBody = shape.getTxBody();
+ }
+ CTTextParagraph p = txBody.addNewP();
+ XSLFTextParagraph paragraph = new XSLFTextParagraph(p);
+ _paragraphs.add(paragraph);
+ return paragraph;
+ }
+
+ /**
+ * @param shapeId 1-based shapeId
+ */
+ static CTShape prototype(int shapeId) {
+ CTShape ct = CTShape.Factory.newInstance();
+ CTShapeNonVisual nvSpPr = ct.addNewNvSpPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("AutoShape " + shapeId);
+ cnv.setId(shapeId + 1);
+ nvSpPr.addNewCNvSpPr();
+ nvSpPr.addNewNvPr();
+ CTShapeProperties spPr = ct.addNewSpPr();
+ CTPresetGeometry2D prst = spPr.addNewPrstGeom();
+ prst.setPrst(STShapeType.RECT);
+ prst.addNewAvLst();
+ return ct;
+ }
+
+ /**
+ * Specifies a solid color fill. The shape is filled entirely with the specified color.
+ *
+ * @param color the solid color fill.
+ * The value of <code>null</code> unsets the solidFIll attribute from the underlying xml
+ */
+ public void setFillColor(Color color) {
+ CTShapeProperties spPr = getSpPr();
+ if (color == null) {
+ if(spPr.isSetSolidFill()) spPr.unsetSolidFill();
+ }
+ else {
+ CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
+
+ CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
+ rgb.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});
+
+ fill.setSrgbClr(rgb);
+ }
+ }
+
+ /**
+ *
+ * @return solid fill color of null if not set
+ */
+ public Color getFillColor(){
+ CTShapeProperties spPr = getSpPr();
+ if(!spPr.isSetSolidFill() ) return null;
+
+ CTSolidColorFillProperties fill = spPr.getSolidFill();
+ if(!fill.isSetSrgbClr()) {
+ // TODO for now return null for all colors except explicit RGB
+ return null;
+ }
+ byte[] val = fill.getSrgbClr().getVal();
+ return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+ }
+
+ /**
+ * Sets the type of vertical alignment for the text.
+ * One of the <code>Anchor*</code> constants defined in this class.
+ *
+ * @param anchor - the type of alignment. Default is {@link VerticalAlignment#TOP}
+ */
+ public void setVerticalAlignment(VerticalAlignment anchor){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(anchor == null) {
+ if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor();
+ } else {
+ bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
+ }
+ }
+ }
+
+ /**
+ * Returns the type of vertical alignment for the text.
+ *
+ * @return the type of alignment
+ */
+ public VerticalAlignment getVerticalAlignment(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ STTextAnchoringType.Enum val = shape.getTxBody().getBodyPr().getAnchor();
+ if(val != null){
+ return VerticalAlignment.values()[val.intValue() - 1];
+ }
+ }
+ return VerticalAlignment.TOP;
+ }
+
+ /**
+ *
+ * @param orientation vertical orientation of the text
+ */
+ public void setTextDirection(TextDirection orientation){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(orientation == null) {
+ if(bodyPr.isSetVert()) bodyPr.unsetVert();
+ } else {
+ bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
+ }
+ }
+ }
+
+ /**
+ * @return vertical orientation of the text
+ */
+ public TextDirection getTextDirection(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ STTextVerticalType.Enum val = shape.getTxBody().getBodyPr().getVert();
+ if(val != null){
+ return TextDirection.values()[val.intValue() - 1];
+ }
+ }
+ return TextDirection.HORIZONTAL;
+ }
+ /**
+ * Returns the distance (in points) between the bottom of the text frame
+ * and the bottom of the inscribed rectangle of the shape that contains the text.
+ *
+ * @return the bottom margin or -1 if not set
+ */
+ public double getMarginBottom(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ return bodyPr.isSetBIns() ? Units.toPoints(bodyPr.getBIns()) : -1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the distance (in points) between the left edge of the text frame
+ * and the left edge of the inscribed rectangle of the shape that contains
+ * the text.
+ *
+ * @return the left margin
+ */
+ public double getMarginLeft(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ return bodyPr.isSetLIns() ? Units.toPoints(bodyPr.getLIns()) : -1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the distance (in points) between the right edge of the
+ * text frame and the right edge of the inscribed rectangle of the shape
+ * that contains the text.
+ *
+ * @return the right margin
+ */
+ public double getMarginRight(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ return bodyPr.isSetRIns() ? Units.toPoints(bodyPr.getRIns()) : -1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the distance (in points) between the top of the text frame
+ * and the top of the inscribed rectangle of the shape that contains the text.
+ *
+ * @return the top margin
+ */
+ public double getMarginTop(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ return bodyPr.isSetTIns() ? Units.toPoints(bodyPr.getTIns()) : -1;
+ }
+ return -1;
+ }
+
+ /**
+ * Sets the botom margin.
+ * @see #getMarginBottom()
+ *
+ * @param margin the bottom margin
+ */
+ public void setMarginBottom(double margin){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(margin == -1) bodyPr.unsetBIns();
+ else bodyPr.setBIns(Units.toEMU(margin));
+ }
+ }
+
+ /**
+ * Sets the left margin.
+ * @see #getMarginLeft()
+ *
+ * @param margin the left margin
+ */
+ public void setMarginLeft(double margin){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(margin == -1) bodyPr.unsetLIns();
+ else bodyPr.setLIns(Units.toEMU(margin));
+ }
+ }
+
+ /**
+ * Sets the right margin.
+ * @see #getMarginRight()
+ *
+ * @param margin the right margin
+ */
+ public void setMarginRight(double margin){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(margin == -1) bodyPr.unsetRIns();
+ else bodyPr.setRIns(Units.toEMU(margin));
+ }
+ }
+
+ /**
+ * Sets the top margin.
+ * @see #getMarginTop()
+ *
+ * @param margin the top margin
+ */
+ public void setMarginTop(double margin){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(margin == -1) bodyPr.unsetTIns();
+ else bodyPr.setTIns(Units.toEMU(margin));
+ }
+ }
+
+
+ /**
+ * Returns the value indicating word wrap.
+ * One of the <code>Wrap*</code> constants defined in this class.
+ *
+ * @return the value indicating word wrap
+ */
+ public boolean getWordWrap(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ return shape.getTxBody().getBodyPr().getWrap() == STTextWrappingType.SQUARE;
+ }
+ return false;
+ }
+
+ /**
+ * Specifies how the text should be wrapped
+ *
+ * @param wrap the value indicating how the text should be wrapped
+ */
+ public void setWordWrap(boolean wrap){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ shape.getTxBody().getBodyPr().setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE);
+ }
+ }
+
+ /**
+ *
+ * Specifies that a shape should be auto-fit to fully contain the text described within it.
+ * Auto-fitting is when text within a shape is scaled in order to contain all the text inside
+ *
+ * @param value type of autofit
+ */
+ public void setTextAutofit(TextAutofit value){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit();
+ if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit();
+ if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit();
+
+ switch(value){
+ case NONE: bodyPr.addNewNoAutofit(); break;
+ case NORMAL: bodyPr.addNewNormAutofit(); break;
+ case SHAPE: bodyPr.addNewSpAutoFit(); break;
+ }
+ }
+ }
+
+ /**
+ *
+ * @return type of autofit
+ */
+ public TextAutofit getTextAutofit(){
+ CTShape shape = (CTShape) getXmlObject();
+ if (shape.isSetTxBody()) {
+ CTTextBodyProperties bodyPr = shape.getTxBody().getBodyPr();
+ if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE;
+ else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL;
+ else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE;
+ }
+ return TextAutofit.NORMAL;
+ }
+
+
+ @Override
+ void onCopy(XSLFSheet srcSheet){
+ CTShape shape = (CTShape) getXmlObject();
+ if (!shape.isSetTxBody()) return;
+
+ CTPlaceholder ph = shape.getNvSpPr().getNvPr().getPh();
+ if(ph == null || !ph.isSetType()) return;
+
+ if(ph.getType() == STPlaceholderType.TITLE){
+
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java
index 22cde4f9b0..a561281552 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommonSlideData.java
@@ -18,6 +18,7 @@
package org.apache.poi.xslf.usermodel;
import org.apache.poi.POIXMLException;
+import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
@@ -34,6 +35,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+@Beta
public class XSLFCommonSlideData {
private final CTCommonSlideData data;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
new file mode 100755
index 0000000000..d93c1351f6
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
@@ -0,0 +1,195 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.util.Beta;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual;
+
+/**
+ *
+ * Specifies a connection shape.
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFConnectorShape extends XSLFSimpleShape {
+
+ /*package*/ XSLFConnectorShape(CTConnector shape, XSLFSheet sheet){
+ super(shape, sheet);
+ }
+
+ /**
+ * @param shapeId 1-based shapeId
+ */
+ static CTConnector prototype(int shapeId) {
+ CTConnector ct = CTConnector.Factory.newInstance();
+ CTConnectorNonVisual nvSpPr = ct.addNewNvCxnSpPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("Connector " + shapeId);
+ cnv.setId(shapeId + 1);
+ nvSpPr.addNewCNvCxnSpPr();
+ nvSpPr.addNewNvPr();
+ CTShapeProperties spPr = ct.addNewSpPr();
+ CTPresetGeometry2D prst = spPr.addNewPrstGeom();
+ prst.setPrst(STShapeType.LINE);
+ prst.addNewAvLst();
+ CTLineProperties ln = spPr.addNewLn();
+ return ct;
+ }
+
+ /**
+ * Specifies the line end decoration, such as a triangle or arrowhead.
+ */
+ public void setLineHeadDecoration(LineDecoration style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+ if(style == null){
+ if(lnEnd.isSetType()) lnEnd.unsetType();
+ } else {
+ lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineDecoration getLineHeadDecoration(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetHeadEnd()) return LineDecoration.NONE;
+
+ STLineEndType.Enum end = ln.getHeadEnd().getType();
+ return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+ }
+
+ /**
+ * specifies decorations which can be added to the head of a line.
+ */
+ public void setLineHeadWidth(LineEndWidth style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+ if(style == null){
+ if(lnEnd.isSetW()) lnEnd.unsetW();
+ } else {
+ lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndWidth getLineHeadWidth(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetHeadEnd()) return null;
+
+ STLineEndWidth.Enum w = ln.getHeadEnd().getW();
+ return w == null ? null : LineEndWidth.values()[w.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end width in relation to the line width.
+ */
+ public void setLineHeadLength(LineEndLength style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
+
+ if(style == null){
+ if(lnEnd.isSetLen()) lnEnd.unsetLen();
+ } else {
+ lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndLength getLineHeadLength(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetHeadEnd()) return null;
+
+ STLineEndLength.Enum len = ln.getHeadEnd().getLen();
+ return len == null ? null : LineEndLength.values()[len.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end decoration, such as a triangle or arrowhead.
+ */
+ public void setLineTailDecoration(LineDecoration style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+ if(style == null){
+ if(lnEnd.isSetType()) lnEnd.unsetType();
+ } else {
+ lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineDecoration getLineTailDecoration(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetTailEnd()) return LineDecoration.NONE;
+
+ STLineEndType.Enum end = ln.getTailEnd().getType();
+ return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
+ }
+
+ /**
+ * specifies decorations which can be added to the tail of a line.
+ */
+ public void setLineTailWidth(LineEndWidth style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+ if(style == null){
+ if(lnEnd.isSetW()) lnEnd.unsetW();
+ } else {
+ lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndWidth getLineTailWidth(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetTailEnd()) return null;
+
+ STLineEndWidth.Enum w = ln.getTailEnd().getW();
+ return w == null ? null : LineEndWidth.values()[w.intValue() - 1];
+ }
+
+ /**
+ * Specifies the line end width in relation to the line width.
+ */
+ public void setLineTailLength(LineEndLength style){
+ CTLineProperties ln = getSpPr().getLn();
+ CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
+
+ if(style == null){
+ if(lnEnd.isSetLen()) lnEnd.unsetLen();
+ } else {
+ lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
+ }
+ }
+
+ public LineEndLength getLineTailLength(){
+ CTLineProperties ln = getSpPr().getLn();
+ if(!ln.isSetTailEnd()) return null;
+
+ STLineEndLength.Enum len = ln.getTailEnd().getLen();
+ return len == null ? null : LineEndLength.values()[len.intValue() - 1];
+ }
+
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
new file mode 100755
index 0000000000..2f72bfc96a
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
@@ -0,0 +1,84 @@
+package org.apache.poi.xslf.usermodel;
+
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.util.Beta;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+
+import java.awt.*;
+
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFDrawing {
+ private XSLFSheet _sheet;
+ private int _shapeId = 1;
+ private CTGroupShape _spTree;
+
+ /*package*/ XSLFDrawing(XSLFSheet sheet, CTGroupShape spTree){
+ _sheet = sheet;
+ _spTree = spTree;
+ XmlObject[] cNvPr = sheet.getSpTree().selectPath(
+ "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
+ for(XmlObject o : cNvPr) {
+ CTNonVisualDrawingProps p = (CTNonVisualDrawingProps)o;
+ _shapeId = (int)Math.max(_shapeId, p.getId());
+ }
+ }
+
+ public XSLFAutoShape createAutoShape(){
+ CTShape sp = _spTree.addNewSp();
+ sp.set(XSLFAutoShape.prototype(_shapeId++));
+ XSLFAutoShape shape = new XSLFAutoShape(sp, _sheet);
+ shape.setAnchor(new Rectangle());
+ return shape;
+ }
+
+ public XSLFFreeformShape createFreeform(){
+ CTShape sp = _spTree.addNewSp();
+ sp.set(XSLFFreeformShape.prototype(_shapeId++));
+ XSLFFreeformShape shape = new XSLFFreeformShape(sp, _sheet);
+ shape.setAnchor(new Rectangle());
+ return shape;
+ }
+
+ public XSLFTextBox createTextBox(){
+ CTShape sp = _spTree.addNewSp();
+ sp.set(XSLFTextBox.prototype(_shapeId++));
+ XSLFTextBox shape = new XSLFTextBox(sp, _sheet);
+ shape.setAnchor(new Rectangle());
+ return shape;
+ }
+
+ public XSLFConnectorShape createConnector(){
+ CTConnector sp = _spTree.addNewCxnSp();
+ sp.set(XSLFConnectorShape.prototype(_shapeId++));
+ XSLFConnectorShape shape = new XSLFConnectorShape(sp, _sheet);
+ shape.setAnchor(new Rectangle());
+ shape.setLineColor(Color.black);
+ shape.setLineWidth(0.75);
+ return shape;
+ }
+
+ public XSLFGroupShape createGroup(){
+ CTGroupShape obj = _spTree.addNewGrpSp();
+ obj.set(XSLFGroupShape.prototype(_shapeId++));
+ XSLFGroupShape shape = new XSLFGroupShape(obj, _sheet);
+ shape.setAnchor(new Rectangle());
+ return shape;
+ }
+
+ public XSLFPictureShape createPicture(String rel){
+ CTPicture obj = _spTree.addNewPic();
+ obj.set(XSLFPictureShape.prototype(_shapeId++, rel));
+ XSLFPictureShape shape = new XSLFPictureShape(obj, _sheet);
+ shape.setAnchor(new Rectangle());
+ return shape;
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java
new file mode 100755
index 0000000000..cb7f329181
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java
@@ -0,0 +1,81 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.POIXMLFactory;
+import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public final class XSLFFactory extends POIXMLFactory {
+ private static final POILogger logger = POILogFactory.getLogger(XSLFFactory.class);
+
+ private XSLFFactory(){
+
+ }
+
+ private static final XSLFFactory inst = new XSLFFactory();
+
+ public static XSLFFactory getInstance(){
+ return inst;
+ }
+
+ @Override
+ public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){
+ POIXMLRelation descriptor = XSLFRelation.getInstance(rel.getRelationshipType());
+ if(descriptor == null || descriptor.getRelationClass() == null){
+ logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
+ return new POIXMLDocumentPart(part, rel);
+ }
+
+ try {
+ Class<? extends POIXMLDocumentPart> cls = descriptor.getRelationClass();
+ Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
+ return constructor.newInstance(part, rel);
+ } catch (Exception e){
+ throw new POIXMLException(e);
+ }
+ }
+
+ @Override
+ public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
+ try {
+ Class<? extends POIXMLDocumentPart> cls = descriptor.getRelationClass();
+ Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
+ return constructor.newInstance();
+ } catch (Exception e){
+ throw new POIXMLException(e);
+ }
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
new file mode 100755
index 0000000000..a494a3cab9
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
@@ -0,0 +1,178 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Units;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomRect;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DClose;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DCubicBezierTo;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DLineTo;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPath2DMoveTo;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Represents a custom geometric shape.
+ * This shape will consist of a series of lines and curves described within a creation path.
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFFreeformShape extends XSLFAutoShape {
+
+ /*package*/ XSLFFreeformShape(CTShape shape, XSLFSheet sheet) {
+ super(shape, sheet);
+ }
+
+ /**
+ * Set the shape path
+ *
+ * @param path shape outline
+ * @return the number of points written
+ */
+ public int setPath(GeneralPath path) {
+ CTPath2D ctPath = CTPath2D.Factory.newInstance();
+
+ Rectangle2D bounds = path.getBounds2D();
+ int x0 = Units.toEMU(bounds.getX());
+ int y0 = Units.toEMU(bounds.getY());
+ PathIterator it = path.getPathIterator(new AffineTransform());
+ int numPoints = 0;
+ ctPath.setH(Units.toEMU(bounds.getHeight()));
+ ctPath.setW(Units.toEMU(bounds.getWidth()));
+ while (!it.isDone()) {
+ double[] vals = new double[6];
+ int type = it.currentSegment(vals);
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ CTAdjPoint2D mv = ctPath.addNewMoveTo().addNewPt();
+ mv.setX(Units.toEMU(vals[0]) - x0);
+ mv.setY(Units.toEMU(vals[1]) - y0);
+ numPoints++;
+ break;
+ case PathIterator.SEG_LINETO:
+ CTAdjPoint2D ln = ctPath.addNewLnTo().addNewPt();
+ ln.setX(Units.toEMU(vals[0]) - x0);
+ ln.setY(Units.toEMU(vals[1]) - y0);
+ numPoints++;
+ break;
+ case PathIterator.SEG_CUBICTO:
+ CTPath2DCubicBezierTo bez = ctPath.addNewCubicBezTo();
+ CTAdjPoint2D p1 = bez.addNewPt();
+ p1.setX(Units.toEMU(vals[0]) - x0);
+ p1.setY(Units.toEMU(vals[1]) - y0);
+ CTAdjPoint2D p2 = bez.addNewPt();
+ p2.setX(Units.toEMU(vals[2]) - x0);
+ p2.setY(Units.toEMU(vals[3]) - y0);
+ CTAdjPoint2D p3 = bez.addNewPt();
+ p3.setX(Units.toEMU(vals[4]) - x0);
+ p3.setY(Units.toEMU(vals[5]) - y0);
+ numPoints += 3;
+ break;
+ case PathIterator.SEG_CLOSE:
+ numPoints++;
+ ctPath.addNewClose();
+ break;
+ }
+ it.next();
+ }
+ getSpPr().getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath});
+ setAnchor(bounds);
+ return numPoints;
+ }
+
+ public GeneralPath getPath() {
+ GeneralPath path = new GeneralPath();
+ Rectangle2D bounds = getAnchor();
+ int x0 = Units.toEMU(bounds.getX());
+ int y0 = Units.toEMU(bounds.getY());
+ CTCustomGeometry2D geom = getSpPr().getCustGeom();
+ for(CTPath2D spPath : geom.getPathLst().getPathList()){
+ for(XmlObject ch : spPath.selectPath("*")){
+ if(ch instanceof CTPath2DMoveTo){
+ CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt();
+ path.moveTo(Units.toPoints((Long)pt.getX() + x0),
+ Units.toPoints((Long)pt.getY() + y0));
+ } else if (ch instanceof CTPath2DLineTo){
+ CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt();
+ path.lineTo(Units.toPoints((Long)pt.getX() + x0),
+ Units.toPoints((Long)pt.getY() + y0));
+ } else if (ch instanceof CTPath2DCubicBezierTo){
+ CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch);
+ CTAdjPoint2D pt1 = bez.getPtArray(0);
+ CTAdjPoint2D pt2 = bez.getPtArray(1);
+ CTAdjPoint2D pt3 = bez.getPtArray(2);
+ path.curveTo(
+ Units.toPoints((Long) pt1.getX() + x0),
+ Units.toPoints((Long) pt1.getY() + y0),
+ Units.toPoints((Long) pt2.getX() + x0),
+ Units.toPoints((Long) pt2.getY() + y0),
+ Units.toPoints((Long) pt3.getX() + x0),
+ Units.toPoints((Long) pt3.getY() + y0)
+ );
+
+ } else if (ch instanceof CTPath2DClose){
+ path.closePath();
+ }
+ }
+ }
+
+ return path;
+ }
+ /**
+ * @param shapeId 1-based shapeId
+ */
+ static CTShape prototype(int shapeId) {
+ CTShape ct = CTShape.Factory.newInstance();
+ CTShapeNonVisual nvSpPr = ct.addNewNvSpPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("Freeform " + shapeId);
+ cnv.setId(shapeId + 1);
+ nvSpPr.addNewCNvSpPr();
+ nvSpPr.addNewNvPr();
+ CTShapeProperties spPr = ct.addNewSpPr();
+ CTCustomGeometry2D geom = spPr.addNewCustGeom();
+ geom.addNewAvLst();
+ geom.addNewGdLst();
+ geom.addNewAhLst();
+ geom.addNewCxnLst();
+ CTGeomRect rect = geom.addNewRect();
+ rect.setR("r");
+ rect.setB("b");
+ rect.setT("t");
+ rect.setL("l");
+ geom.addNewPathLst();
+ return ct;
+ }
+
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java
new file mode 100755
index 0000000000..0abad44f30
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeGroup;
+import org.apache.poi.util.Beta;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFGraphicFrame extends XSLFShape {
+ private final CTGraphicalObjectFrame _shape;
+ private final XSLFSheet _sheet;
+
+ /*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){
+ _shape = shape;
+ _sheet = sheet;
+ }
+
+ public CTGraphicalObjectFrame getXmlObject(){
+ return _shape;
+ }
+
+ public int getShapeType(){
+ throw new RuntimeException("NotImplemented");
+ }
+
+ public int getShapeId(){
+ return (int)_shape.getNvGraphicFramePr().getCNvPr().getId();
+ }
+
+ public String getShapeName(){
+ return _shape.getNvGraphicFramePr().getCNvPr().getName();
+ }
+
+ public Rectangle2D getAnchor(){
+ throw new RuntimeException("NotImplemented");
+ }
+
+ public void setAnchor(Rectangle2D anchor){
+ throw new RuntimeException("NotImplemented");
+ }
+
+ public ShapeGroup getParent(){
+ throw new RuntimeException("NotImplemented");
+ }
+
+ public Shape[] getShapes(){
+ throw new RuntimeException("NotImplemented");
+ }
+
+
+ public boolean removeShape(Shape shape){
+ throw new RuntimeException("NotImplemented");
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
new file mode 100755
index 0000000000..804420854d
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
@@ -0,0 +1,220 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeGroup;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Units;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a group shape that consists of many shapes grouped together.
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFGroupShape extends XSLFShape {
+ private final CTGroupShape _shape;
+ private final XSLFSheet _sheet;
+ private final List<XSLFShape> _shapes;
+ private final CTGroupShapeProperties _spPr;
+ private XSLFDrawing _drawing;
+
+ /*package*/ XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){
+ _shape = shape;
+ _sheet = sheet;
+
+ _shapes = _sheet.buildShapes(_shape);
+ _spPr = shape.getGrpSpPr();
+ }
+
+ public CTGroupShape getXmlObject(){
+ return _shape;
+ }
+
+ public Rectangle2D getAnchor(){
+ CTGroupTransform2D xfrm = _spPr.getXfrm();
+ CTPoint2D off = xfrm.getOff();
+ long x = off.getX();
+ long y = off.getY();
+ CTPositiveSize2D ext = xfrm.getExt();
+ long cx = ext.getCx();
+ long cy = ext.getCy();
+ return new Rectangle2D.Double(
+ Units.toPoints(x), Units.toPoints(y),
+ Units.toPoints(cx), Units.toPoints(cy));
+ }
+
+ public void setAnchor(Rectangle2D anchor){
+ CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm();
+ CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
+ long x = Units.toEMU(anchor.getX());
+ long y = Units.toEMU(anchor.getY());
+ off.setX(x);
+ off.setY(y);
+ CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt();
+ long cx = Units.toEMU(anchor.getWidth());
+ long cy = Units.toEMU(anchor.getHeight());
+ ext.setCx(cx);
+ ext.setCy(cy);
+ }
+
+ public Rectangle2D getInteriorAnchor(){
+ CTGroupTransform2D xfrm = _spPr.getXfrm();
+ CTPoint2D off = xfrm.getChOff();
+ long x = off.getX();
+ long y = off.getY();
+ CTPositiveSize2D ext = xfrm.getChExt();
+ long cx = ext.getCx();
+ long cy = ext.getCy();
+ return new Rectangle2D.Double(
+ Units.toPoints(x), Units.toPoints(y),
+ Units.toPoints(cx), Units.toPoints(cy));
+ }
+
+ public void setInteriorAnchor(Rectangle2D anchor){
+ CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm();
+ CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff();
+ long x = Units.toEMU(anchor.getX());
+ long y = Units.toEMU(anchor.getY());
+ off.setX(x);
+ off.setY(y);
+ CTPositiveSize2D ext = xfrm.isSetChExt() ? xfrm.getChExt() : xfrm.addNewChExt();
+ long cx = Units.toEMU(anchor.getWidth());
+ long cy = Units.toEMU(anchor.getHeight());
+ ext.setCx(cx);
+ ext.setCy(cy);
+ }
+
+ public XSLFShape[] getShapes(){
+ return _shapes.toArray(new XSLFShape[_shapes.size()]);
+ }
+
+ public boolean removeShape(XSLFShape xShape) {
+ XmlObject obj = xShape.getXmlObject();
+ if(obj instanceof CTShape){
+ _shape.getSpList().remove(obj);
+ } else if (obj instanceof CTGroupShape){
+ _shape.getGrpSpList().remove(obj);
+ } else if (obj instanceof CTConnector){
+ _shape.getCxnSpList().remove(obj);
+ } else {
+ throw new IllegalArgumentException("Unsupported shape: " + xShape);
+ }
+ return _shapes.remove(xShape);
+ }
+
+ public String getShapeName(){
+ return _shape.getNvGrpSpPr().getCNvPr().getName();
+ }
+
+ public int getShapeId(){
+ return (int)_shape.getNvGrpSpPr().getCNvPr().getId();
+ }
+
+ /**
+ * @param shapeId 1-based shapeId
+ */
+ static CTGroupShape prototype(int shapeId) {
+ CTGroupShape ct = CTGroupShape.Factory.newInstance();
+ CTGroupShapeNonVisual nvSpPr = ct.addNewNvGrpSpPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("Group " + shapeId);
+ cnv.setId(shapeId + 1);
+
+ nvSpPr.addNewCNvGrpSpPr();
+ nvSpPr.addNewNvPr();
+ ct.addNewGrpSpPr();
+ return ct;
+ }
+
+ // shape factory methods
+ private XSLFDrawing getDrawing(){
+ if(_drawing == null) {
+ _drawing = new XSLFDrawing(_sheet, _shape);
+ }
+ return _drawing;
+ }
+
+ public XSLFAutoShape createAutoShape(){
+ XSLFAutoShape sh = getDrawing().createAutoShape();
+ _shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFFreeformShape createFreeform(){
+ XSLFFreeformShape sh = getDrawing().createFreeform();
+ _shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFTextBox createTextBox(){
+ XSLFTextBox sh = getDrawing().createTextBox();
+ _shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFConnectorShape createConnector(){
+ XSLFConnectorShape sh = getDrawing().createConnector();
+ _shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFGroupShape createGroup(){
+ XSLFGroupShape sh = getDrawing().createGroup();
+ _shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFPictureShape createPicture(int pictureIndex){
+
+ List<PackagePart> pics = _sheet.getPackagePart().getPackage()
+ .getPartsByName(Pattern.compile("/ppt/media/.*?"));
+
+ PackagePart pic = pics.get(pictureIndex);
+
+ PackageRelationship rel = _sheet.getPackagePart().addRelationship(
+ pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation());
+
+ XSLFPictureShape sh = getDrawing().createPicture(rel.getId());
+ sh.resize();
+ _shapes.add(sh);
+ return sh;
+ }
+
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
new file mode 100644
index 0000000000..6fd151ff17
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
@@ -0,0 +1,171 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.IOUtils;
+
+import java.io.IOException;
+
+/**
+ * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public final class XSLFPictureData extends POIXMLDocumentPart {
+ /**
+ * Extended windows meta file
+ */
+ public static final int PICTURE_TYPE_EMF = 2;
+
+ /**
+ * Windows Meta File
+ */
+ public static final int PICTURE_TYPE_WMF = 3;
+
+ /**
+ * Mac PICT format
+ */
+ public static final int PICTURE_TYPE_PICT = 4;
+
+ /**
+ * JPEG format
+ */
+ public static final int PICTURE_TYPE_JPEG = 5;
+
+ /**
+ * PNG format
+ */
+ public static final int PICTURE_TYPE_PNG = 6;
+
+ /**
+ * Device independent bitmap
+ */
+ public static final int PICTURE_TYPE_DIB = 7;
+
+ /**
+ * GIF image format
+ */
+ public static final int PICTURE_TYPE_GIF = 8;
+
+ /**
+ * Relationships for each known picture type
+ */
+ protected static final POIXMLRelation[] RELATIONS;
+
+ static {
+ RELATIONS = new POIXMLRelation[9];
+ RELATIONS[PICTURE_TYPE_EMF] = XSLFRelation.IMAGE_EMF;
+ RELATIONS[PICTURE_TYPE_WMF] = XSLFRelation.IMAGE_WMF;
+ RELATIONS[PICTURE_TYPE_PICT] = XSLFRelation.IMAGE_PICT;
+ RELATIONS[PICTURE_TYPE_JPEG] = XSLFRelation.IMAGE_JPEG;
+ RELATIONS[PICTURE_TYPE_PNG] = XSLFRelation.IMAGE_PNG;
+ RELATIONS[PICTURE_TYPE_DIB] = XSLFRelation.IMAGE_DIB;
+ RELATIONS[PICTURE_TYPE_GIF] = XSLFRelation.IMAGE_GIF;
+ }
+
+ private Long checksum = null;
+
+ /**
+ * Create a new XSLFGraphicData node
+ */
+ protected XSLFPictureData() {
+ super();
+ }
+
+ /**
+ * Construct XSLFPictureData from a package part
+ *
+ * @param part the package part holding the drawing data,
+ * @param rel the package relationship holding this drawing,
+ * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
+ */
+ public XSLFPictureData(PackagePart part, PackageRelationship rel) {
+ super(part, rel);
+ }
+
+ /**
+ * Gets the picture data as a byte array.
+ * <p>
+ * Note, that this call might be expensive since all the picture data is copied into a temporary byte array.
+ * You can grab the picture data directly from the underlying package part as follows:
+ * <br/>
+ * <code>
+ * InputStream is = getPackagePart().getInputStream();
+ * </code>
+ * </p>
+ *
+ * @return the Picture data.
+ */
+ public byte[] getData() {
+ try {
+ return IOUtils.toByteArray(getPackagePart().getInputStream());
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ }
+ }
+
+ /**
+ * Returns the file name of the image, eg image7.jpg . The original filename
+ * isn't always available, but if it can be found it's likely to be in the
+ * CTDrawing
+ */
+ public String getFileName() {
+ String name = getPackagePart().getPartName().getName();
+ if (name == null)
+ return null;
+ return name.substring(name.lastIndexOf('/') + 1);
+ }
+
+ /**
+ * Suggests a file extension for this image.
+ *
+ * @return the file extension.
+ */
+ public String suggestFileExtension() {
+ return getPackagePart().getPartName().getExtension();
+ }
+
+ /**
+ * Return an integer constant that specifies type of this picture
+ *
+ * @return an integer constant that specifies type of this picture
+ */
+ public int getPictureType() {
+ String contentType = getPackagePart().getContentType();
+ for (int i = 0; i < RELATIONS.length; i++) {
+ if (RELATIONS[i] == null) {
+ continue;
+ }
+
+ if (RELATIONS[i].getContentType().equals(contentType)) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
new file mode 100755
index 0000000000..c2ce2bd969
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
@@ -0,0 +1,107 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.util.Beta;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual;
+
+import javax.imageio.ImageIO;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFPictureShape extends XSLFSimpleShape {
+ private XSLFPictureData _data;
+
+ /*package*/ XSLFPictureShape(CTPicture shape, XSLFSheet sheet) {
+ super(shape, sheet);
+ }
+
+
+ /**
+ * @param shapeId 1-based shapeId
+ * @param rel relationship to the picture data in the ooxml package
+ */
+ static CTPicture prototype(int shapeId, String rel) {
+ CTPicture ct = CTPicture.Factory.newInstance();
+ CTPictureNonVisual nvSpPr = ct.addNewNvPicPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("Picture " + shapeId);
+ cnv.setId(shapeId + 1);
+ nvSpPr.addNewCNvPicPr().addNewPicLocks().setNoChangeAspect(true);
+ nvSpPr.addNewNvPr();
+
+ CTBlipFillProperties blipFill = ct.addNewBlipFill();
+ CTBlip blip = blipFill.addNewBlip();
+ blip.setEmbed(rel);
+ blipFill.addNewStretch().addNewFillRect();
+
+ CTShapeProperties spPr = ct.addNewSpPr();
+ CTPresetGeometry2D prst = spPr.addNewPrstGeom();
+ prst.setPrst(STShapeType.RECT);
+ prst.addNewAvLst();
+ return ct;
+ }
+
+ /**
+ * Resize this picture to the default size.
+ * For PNG and JPEG resizes the image to 100%,
+ * for other types sets the default size of 200x200 pixels.
+ */
+ public void resize() {
+ XSLFPictureData pict = getPictureData();
+
+ try {
+ BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
+ setAnchor(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
+ }
+ catch (Exception e) {
+ //default size is 200x200
+ setAnchor(new java.awt.Rectangle(50, 50, 200, 200));
+ }
+ }
+
+ public XSLFPictureData getPictureData() {
+ if(_data == null){
+ CTPicture ct = (CTPicture)getXmlObject();
+ String blipId = ct.getBlipFill().getBlip().getEmbed();
+
+ for (POIXMLDocumentPart part : getSheet().getRelations()) {
+ if(part.getPackageRelationship().getId().equals(blipId)){
+ _data = (XSLFPictureData)part;
+ }
+ }
+ }
+ return _data;
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
index 29cf65809e..c546d93dfc 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
@@ -16,14 +16,16 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLRelation;
+import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import java.util.HashMap;
+import java.util.Map;
+
+@Beta
public class XSLFRelation extends POIXMLRelation {
private static POILogger log = POILogFactory.getLogger(XSLFRelation.class);
@@ -78,16 +80,23 @@ public class XSLFRelation extends POIXMLRelation {
"application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide",
"/ppt/slides/slide#.xml",
- null
+ XSLFSlide.class
);
public static final XSLFRelation SLIDE_LAYOUT = new XSLFRelation(
"application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
"/ppt/slideLayouts/slideLayout#.xml",
- null
+ XSLFSlideLayout.class
);
+ public static final XSLFRelation SLIDE_MASTER = new XSLFRelation(
+ "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster",
+ "/ppt/slideMasters/slideMaster#.xml",
+ XSLFSlideMaster.class
+ );
+
public static final XSLFRelation COMMENTS = new XSLFRelation(
"application/vnd.openxmlformats-officedocument.presentationml.comments+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
@@ -108,6 +117,55 @@ public class XSLFRelation extends POIXMLRelation {
null
);
+ public static final XSLFRelation IMAGE_EMF = new XSLFRelation(
+ "image/x-emf",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.emf",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_WMF = new XSLFRelation(
+ "image/x-wmf",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.wmf",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_PICT = new XSLFRelation(
+ "image/pict",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.pict",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_JPEG = new XSLFRelation(
+ "image/jpeg",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.jpeg",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_PNG = new XSLFRelation(
+ "image/png",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.png",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_DIB = new XSLFRelation(
+ "image/dib",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.dib",
+ XSLFPictureData.class
+ );
+ public static final XSLFRelation IMAGE_GIF = new XSLFRelation(
+ "image/gif",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/ppt/media/image#.gif",
+ XSLFPictureData.class
+ );
+
+ public static final XSLFRelation IMAGES = new XSLFRelation(
+ null,
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ null,
+ null
+ );
private XSLFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
super(type, rel, defaultName, cls);
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
new file mode 100755
index 0000000000..b1b65eac40
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java
@@ -0,0 +1,48 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.sl.usermodel.Shape;
+import org.apache.poi.util.Beta;
+import org.apache.xmlbeans.XmlObject;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public abstract class XSLFShape {
+
+
+ public abstract Rectangle2D getAnchor();
+
+ public abstract void setAnchor(Rectangle2D anchor);
+
+ public abstract XmlObject getXmlObject();
+
+ public abstract String getShapeName();
+
+ public abstract int getShapeId();
+
+ void onCopy(XSLFSheet srcSheet){
+
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
index 3bbd099c0e..02ce9fdb7d 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
@@ -16,44 +16,199 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import org.apache.poi.sl.usermodel.Background;
-import org.apache.poi.sl.usermodel.MasterSheet;
-import org.apache.poi.sl.usermodel.Shape;
-import org.apache.poi.sl.usermodel.Sheet;
-import org.apache.poi.sl.usermodel.SlideShow;
-
-public abstract class XSLFSheet implements Sheet {
- private SlideShow slideShow;
- protected XSLFSheet(SlideShow parent) {
- this.slideShow = parent;
- }
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.util.Beta;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
- public Background getBackground() {
- // TODO Auto-generated method stub
- return null;
- }
+import javax.xml.namespace.QName;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
- public MasterSheet getMasterSheet() {
- // TODO Auto-generated method stub
- return null;
- }
+@Beta
+public abstract class XSLFSheet extends POIXMLDocumentPart {
+ private XSLFDrawing _drawing;
+ private List<XSLFShape> _shapes;
+ private CTGroupShape _spTree;
- public SlideShow getSlideShow() {
- return slideShow;
- }
+ public XSLFSheet(){
+ super();
+ }
- public void addShape(Shape shape) {
- // TODO Auto-generated method stub
+ public XSLFSheet(PackagePart part, PackageRelationship rel){
+ super(part, rel);
+ }
+ public XMLSlideShow getSlideShow() {
+ return (XMLSlideShow)getParent();
}
- public Shape[] getShapes() {
- // TODO Auto-generated method stub
- return null;
- }
+ protected List<XSLFShape> buildShapes(CTGroupShape spTree){
+ List<XSLFShape> shapes = new ArrayList<XSLFShape>();
+ for(XmlObject ch : spTree.selectPath("*")){
+ if(ch instanceof CTShape){ // simple shape
+ XSLFAutoShape shape = XSLFAutoShape.create((CTShape)ch, this);
+ shapes.add(shape);
+ } else if (ch instanceof CTGroupShape){
+ shapes.add(new XSLFGroupShape((CTGroupShape)ch, this));
+ } else if (ch instanceof CTConnector){
+ shapes.add(new XSLFConnectorShape((CTConnector)ch, this));
+ } else if (ch instanceof CTPicture){
+ shapes.add(new XSLFPictureShape((CTPicture)ch, this));
+ } else if (ch instanceof CTGraphicalObjectFrame){
+ shapes.add(new XSLFGraphicFrame((CTGraphicalObjectFrame)ch, this));
+ }
+ }
+ return shapes;
+ }
+
+ public abstract XmlObject getXmlObject();
+
+
+ private XSLFDrawing getDrawing(){
+ if(_drawing == null) {
+ _drawing = new XSLFDrawing(this, getSpTree());
+ }
+ return _drawing;
+ }
+
+ private List<XSLFShape> getShapeList(){
+ if(_shapes == null){
+ _shapes = buildShapes(getSpTree());
+ }
+ return _shapes;
+ }
+
+ // shape factory methods
+
+ public XSLFAutoShape createAutoShape(){
+ List<XSLFShape> shapes = getShapeList();
+ XSLFAutoShape sh = getDrawing().createAutoShape();
+ shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFFreeformShape createFreeform(){
+ List<XSLFShape> shapes = getShapeList();
+ XSLFFreeformShape sh = getDrawing().createFreeform();
+ shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFTextBox createTextBox(){
+ List<XSLFShape> shapes = getShapeList();
+ XSLFTextBox sh = getDrawing().createTextBox();
+ shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFConnectorShape createConnector(){
+ List<XSLFShape> shapes = getShapeList();
+ XSLFConnectorShape sh = getDrawing().createConnector();
+ shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFGroupShape createGroup(){
+ List<XSLFShape> shapes = getShapeList();
+ XSLFGroupShape sh = getDrawing().createGroup();
+ shapes.add(sh);
+ return sh;
+ }
+
+ public XSLFPictureShape createPicture(int pictureIndex){
+ List<PackagePart> pics = getPackagePart().getPackage()
+ .getPartsByName(Pattern.compile("/ppt/media/.*?"));
+
+ PackagePart pic = pics.get(pictureIndex);
+
+ PackageRelationship rel = getPackagePart().addRelationship(
+ pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation());
+ addRelation(rel.getId(), new XSLFPictureData(pic, rel));
+
+ XSLFPictureShape sh = getDrawing().createPicture(rel.getId());
+ sh.resize();
+
+ getShapeList().add(sh);
+ return sh;
+ }
+
+ public XSLFShape[] getShapes(){
+ return getShapeList().toArray(new XSLFShape[_shapes.size()]);
+ }
+
+ public boolean removeShape(XSLFShape xShape) {
+ XmlObject obj = xShape.getXmlObject();
+ CTGroupShape spTree = getSpTree();
+ if(obj instanceof CTShape){
+ spTree.getSpList().remove(obj);
+ } else if (obj instanceof CTGroupShape){
+ spTree.getGrpSpList().remove(obj);
+ } else if (obj instanceof CTConnector){
+ spTree.getCxnSpList().remove(obj);
+ } else {
+ throw new IllegalArgumentException("Unsupported shape: " + xShape);
+ }
+ return getShapeList().remove(xShape);
+ }
+
+ protected abstract String getRootElementName();
+
+ protected CTGroupShape getSpTree(){
+ if(_spTree == null) {
+ XmlObject root = getXmlObject();
+ XmlObject[] sp = root.selectPath(
+ "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:spTree");
+ if(sp.length == 0) throw new IllegalStateException("CTGroupShape was not found");
+ _spTree = (CTGroupShape)sp[0];
+ }
+ return _spTree;
+ }
+
+ protected final void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
+ map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
+ map.put("http://schemas.openxmlformats.org/presentationml/2006/main", "p");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+ String docName = getRootElementName();
+ if(docName != null) {
+ xmlOptions.setSaveSyntheticDocumentElement(
+ new QName("http://schemas.openxmlformats.org/presentationml/2006/main", docName));
+ }
+
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ getXmlObject().save(out, xmlOptions);
+ out.close();
+ }
+
+ /**
+ * Set the contents of this sheet to be a copy of the source sheet.
+ *
+ * @param src the source sheet to copy data from
+ */
+ public void copy(XSLFSheet src){
+ _shapes = null;
+ _spTree = null;
+ _drawing = null;
+ getXmlObject().set(src.getXmlObject());
+ }
- public boolean removeShape(Shape shape) {
- // TODO Auto-generated method stub
- return false;
- }
} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
new file mode 100755
index 0000000000..3b624dc0ab
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
@@ -0,0 +1,268 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.xslf.usermodel.LineCap;
+import org.apache.poi.xslf.usermodel.LineDash;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Units;
+import org.apache.xmlbeans.XmlObject;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
+import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public abstract class XSLFSimpleShape extends XSLFShape {
+ private final XmlObject _shape;
+ private final XSLFSheet _sheet;
+ private CTShapeProperties _spPr;
+ private CTNonVisualDrawingProps _nvPr;
+
+ /*package*/ XSLFSimpleShape(XmlObject shape, XSLFSheet sheet){
+ _shape = shape;
+ _sheet = sheet;
+ }
+
+ public XmlObject getXmlObject(){
+ return _shape;
+ }
+
+ public XSLFSheet getSheet(){
+ return _sheet;
+ }
+ /**
+ * TODO match STShapeType with {@link org.apache.poi.sl.usermodel.ShapeTypes}
+ */
+ public int getShapeType() {
+ STShapeType.Enum stEnum = getSpPr().getPrstGeom().getPrst();
+ return stEnum.intValue();
+ }
+
+ public String getShapeName() {
+ return getNvPr().getName();
+ }
+
+ public int getShapeId() {
+ return (int)getNvPr().getId();
+ }
+
+ protected CTNonVisualDrawingProps getNvPr(){
+ if(_nvPr == null){
+ XmlObject[] rs = _shape.selectPath(
+ "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
+ if(rs.length != 0) {
+ _nvPr = (CTNonVisualDrawingProps)rs[0];
+ }
+ }
+ return _nvPr;
+ }
+
+ protected CTShapeProperties getSpPr(){
+ if(_spPr == null) {
+ for(XmlObject obj : _shape.selectPath("*")){
+ if(obj instanceof CTShapeProperties){
+ _spPr = (CTShapeProperties)obj;
+ }
+ }
+ }
+ if(_spPr == null) {
+ throw new IllegalStateException("CTShapeProperties was not found.");
+ }
+ return _spPr;
+ }
+
+ public Rectangle2D getAnchor(){
+ CTTransform2D xfrm = getSpPr().getXfrm();
+ CTPoint2D off = xfrm.getOff();
+ long x = off.getX();
+ long y = off.getY();
+ CTPositiveSize2D ext = xfrm.getExt();
+ long cx = ext.getCx();
+ long cy = ext.getCy();
+ return new Rectangle2D.Double(
+ Units.toPoints(x), Units.toPoints(y),
+ Units.toPoints(cx), Units.toPoints(cy));
+ }
+
+ public void setAnchor(Rectangle2D anchor){
+ CTTransform2D xfrm = getSpPr().isSetXfrm() ? getSpPr().getXfrm() : getSpPr().addNewXfrm();
+ CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
+ long x = Units.toEMU(anchor.getX());
+ long y = Units.toEMU(anchor.getY());
+ off.setX(x);
+ off.setY(y);
+ CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt();
+ long cx = Units.toEMU(anchor.getWidth());
+ long cy = Units.toEMU(anchor.getHeight());
+ ext.setCx(cx);
+ ext.setCy(cy);
+ }
+
+ /**
+ * Rotate this shape.
+ * <p>
+ * Positive angles are clockwise (i.e., towards the positive y axis);
+ * negative angles are counter-clockwise (i.e., towards the negative y axis).
+ * </p>
+ *
+ * @param theta the rotation angle in degrees.
+ */
+ public void setRotation(double theta){
+ CTTransform2D xfrm = getSpPr().getXfrm();
+ xfrm.setRot((int)(theta*60000));
+ }
+
+ /**
+ * Rotation angle in degrees
+ * <p>
+ * Positive angles are clockwise (i.e., towards the positive y axis);
+ * negative angles are counter-clockwise (i.e., towards the negative y axis).
+ * </p>
+ *
+ * @return rotation angle in degrees
+ */
+ public double getRotation(){
+ CTTransform2D xfrm = getSpPr().getXfrm();
+ return (double)xfrm.getRot()/60000;
+ }
+
+ public void setFlipHorizontal(boolean flip){
+ CTTransform2D xfrm = getSpPr().getXfrm();
+ xfrm.setFlipH(flip);
+ }
+
+ public void setFlipVertical(boolean flip){
+ CTTransform2D xfrm = getSpPr().getXfrm();
+ xfrm.setFlipV(flip);
+ }
+ /**
+ * Whether the shape is horizontally flipped
+ *
+ * @return whether the shape is horizontally flipped
+ */
+ public boolean getFlipHorizontal(){
+ return getSpPr().getXfrm().getFlipH();
+ }
+
+ public boolean getFlipVertical(){
+ return getSpPr().getXfrm().getFlipV();
+ }
+
+ public void setLineColor(Color color){
+ CTShapeProperties spPr = getSpPr();
+ if(color == null) {
+ if(spPr.isSetLn() && spPr.getLn().isSetSolidFill()) spPr.getLn().unsetSolidFill();
+ }
+ else {
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+
+ CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
+ rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
+
+ CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();
+ fill.setSrgbClr(rgb);
+ }
+ }
+
+ public Color getLineColor(){
+ CTShapeProperties spPr = getSpPr();
+ if(!spPr.isSetLn() || !spPr.getLn().isSetSolidFill()) return null;
+
+ CTSRgbColor rgb = spPr.getLn().getSolidFill().getSrgbClr();
+ byte[] val = rgb.getVal();
+ return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+ }
+
+ public void setLineWidth(double width){
+ CTShapeProperties spPr = getSpPr();
+ if(width == 0.) {
+ if(spPr.isSetLn()) spPr.getLn().unsetW();
+ }
+ else {
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+ ln.setW(Units.toEMU(width));
+ }
+ }
+
+ public double getLineWidth(){
+ CTShapeProperties spPr = getSpPr();
+ CTLineProperties ln = spPr.getLn();
+ if(ln == null || !ln.isSetW()) return 0;
+
+ return Units.toPoints(ln.getW());
+ }
+
+ public void setLineDash(LineDash dash){
+ CTShapeProperties spPr = getSpPr();
+ if(dash == null) {
+ if(spPr.isSetLn()) spPr.getLn().unsetPrstDash();
+ }
+ else {
+ CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory.newInstance();
+ val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1));
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+ ln.setPrstDash(val);
+ }
+ }
+
+ public LineDash getLineDash(){
+ CTShapeProperties spPr = getSpPr();
+ CTLineProperties ln = spPr.getLn();
+ if(ln == null || !ln.isSetPrstDash()) return null;
+
+ CTPresetLineDashProperties dash = ln.getPrstDash();
+ return LineDash.values()[dash.getVal().intValue() - 1];
+ }
+
+ public void setLineCap(LineCap cap){
+ CTShapeProperties spPr = getSpPr();
+ if(cap == null) {
+ if(spPr.isSetLn()) spPr.getLn().unsetCap();
+ }
+ else {
+ CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
+ ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
+ }
+ }
+
+ public LineCap getLineCap(){
+ CTShapeProperties spPr = getSpPr();
+ CTLineProperties ln = spPr.getLn();
+ if(ln == null || !ln.isSetCap()) return null;
+
+ return LineCap.values()[ln.getCap().intValue() - 1];
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
index 29af4941ec..f864344d71 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java
@@ -16,82 +16,124 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import org.apache.poi.sl.usermodel.Notes;
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.sl.usermodel.Slide;
-import org.apache.poi.sl.usermodel.SlideShow;
-import org.apache.poi.util.Internal;
+import org.apache.poi.util.Beta;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
-
-public class XSLFSlide extends XSLFSheet implements Slide {
- private CTSlide slide;
- private CTSlideIdListEntry slideId;
- private XSLFCommonSlideData data;
-
- public XSLFSlide(CTSlide slide, CTSlideIdListEntry slideId, SlideShow parent) {
- super(parent);
- this.slide = slide;
- this.slideId = slideId;
- this.data = new XSLFCommonSlideData(slide.getCSld());
- }
-
- /**
- * While developing only!
- */
- @Internal
- public CTSlide _getCTSlide() {
- return slide;
- }
- /**
- * While developing only!
- */
- @Internal
- public CTSlideIdListEntry _getCTSlideId() {
- return slideId;
- }
-
-
- public boolean getFollowMasterBackground() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean getFollowMasterColourScheme() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean getFollowMasterObjects() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public Notes getNotes() {
- // TODO Auto-generated method stub
- return null;
- }
+import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@Beta
+public final class XSLFSlide extends XSLFSheet {
+ private final CTSlide _slide;
+ private XSLFSlideLayout _layout;
+
+ /**
+ * Create a new slide
+ */
+ XSLFSlide() {
+ super();
+ _slide = prototype();
+ }
- public void setFollowMasterBackground(boolean follow) {
- // TODO Auto-generated method stub
+ /**
+ * Construct a SpreadsheetML drawing from a package part
+ *
+ * @param part the package part holding the drawing data,
+ * the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
+ * @param rel the package relationship holding this drawing,
+ * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing
+ */
+ XSLFSlide(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
+ super(part, rel);
+
+ SldDocument doc =
+ SldDocument.Factory.parse(getPackagePart().getInputStream());
+ _slide = doc.getSld();
+ }
- }
- public void setFollowMasterColourScheme(boolean follow) {
- // TODO Auto-generated method stub
+ private static CTSlide prototype(){
+ CTSlide ctSlide = CTSlide.Factory.newInstance();
+ CTCommonSlideData cSld = ctSlide.addNewCSld();
+ CTGroupShape spTree = cSld.addNewSpTree();
+
+ CTGroupShapeNonVisual nvGrpSpPr = spTree.addNewNvGrpSpPr();
+ CTNonVisualDrawingProps cnvPr = nvGrpSpPr.addNewCNvPr();
+ cnvPr.setId(1);
+ cnvPr.setName("");
+ nvGrpSpPr.addNewCNvGrpSpPr();
+ nvGrpSpPr.addNewNvPr();
+
+ CTGroupShapeProperties grpSpr = spTree.addNewGrpSpPr();
+ CTGroupTransform2D xfrm = grpSpr.addNewXfrm();
+ CTPoint2D off = xfrm.addNewOff();
+ off.setX(0);
+ off.setY(0);
+ CTPositiveSize2D ext = xfrm.addNewExt();
+ ext.setCx(0);
+ ext.setCy(0);
+ CTPoint2D choff = xfrm.addNewChOff();
+ choff.setX(0);
+ choff.setY(0);
+ CTPositiveSize2D chExt = xfrm.addNewChExt();
+ chExt.setCx(0);
+ chExt.setCy(0);
+ ctSlide.addNewClrMapOvr().addNewMasterClrMapping();
+ return ctSlide;
+ }
+ @Override
+ public CTSlide getXmlObject() {
+ return _slide;
}
- public void setFollowMasterObjects(boolean follow) {
- // TODO Auto-generated method stub
+ @Override
+ protected String getRootElementName(){
+ return "sld";
+ }
- }
+ public XSLFSlideMaster getMasterSheet(){
+ return getSlideLayout().getSlideMaster();
+ }
- public void setNotes(Notes notes) {
- // TODO Auto-generated method stub
+ public XSLFSlideLayout getSlideLayout(){
+ if(_layout == null){
+ for (POIXMLDocumentPart p : getRelations()) {
+ if (p instanceof XSLFSlideLayout){
+ _layout = (XSLFSlideLayout)p;
+ }
+ }
+ }
+ if(_layout == null) {
+ throw new IllegalArgumentException("SlideLayout was not found for " + this.toString());
+ }
+ return _layout;
+ }
- }
+ public void setFollowMasterBackground(boolean value){
+ _slide.setShowMasterSp(value);
+ }
- public XSLFCommonSlideData getCommonSlideData() {
- return data;
+ public boolean getFollowMasterBackground(){
+ return !_slide.isSetShowMasterSp() || _slide.getShowMasterSp();
}
+
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
new file mode 100755
index 0000000000..871ece50dd
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java
@@ -0,0 +1,103 @@
+/* ====================================================================
+ 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.xslf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout;
+import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
+
+import java.io.IOException;
+
+@Beta
+public class XSLFSlideLayout extends XSLFSheet {
+ private CTSlideLayout _layout;
+ private XSLFSlideMaster _master;
+
+ XSLFSlideLayout() {
+ super();
+ _layout = CTSlideLayout.Factory.newInstance();
+ }
+
+ public XSLFSlideLayout(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
+ super(part, rel);
+ SldLayoutDocument doc =
+ SldLayoutDocument.Factory.parse(getPackagePart().getInputStream());
+ _layout = doc.getSldLayout();
+ }
+
+
+ public String getName(){
+ return _layout.getCSld().getName();
+ }
+
+ /**
+ * While developing only!
+ */
+ @Internal
+ public CTSlideLayout getXmlObject() {
+ return _layout;
+ }
+
+ @Override
+ protected String getRootElementName(){
+ return "sldLayout";
+ }
+
+ /**
+ * Slide master object associated with this layout.
+ * <p>
+ * Within a slide master slide are contained all elements
+ * that describe the objects and their corresponding formatting
+ * for within a presentation slide.
+ * </p>
+ * <p>
+ * Within a slide master slide are two main elements.
+ * The cSld element specifies the common slide elements such as shapes and
+ * their attached text bodies. Then the txStyles element specifies the
+ * formatting for the text within each of these shapes. The other properties
+ * within a slide master slide specify other properties for within a presentation slide
+ * such as color information, headers and footers, as well as timing and
+ * transition information for all corresponding presentation slides.
+ * </p>
+ *
+ * @return slide master. Never null.
+ * @throws IllegalStateException if slide master was not found
+ */
+ public XSLFSlideMaster getSlideMaster(){
+ if(_master == null){
+ for (POIXMLDocumentPart p : getRelations()) {
+ if (p instanceof XSLFSlideMaster){
+ _master = (XSLFSlideMaster)p;
+ }
+ }
+ }
+ if(_master == null) {
+ throw new IllegalStateException("SlideMaster was not found for " + this.toString());
+ }
+ return _master;
+ }
+
+ public XMLSlideShow getSlideShow() {
+ return (XMLSlideShow)getParent().getParent();
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
new file mode 100755
index 0000000000..d7c86407a2
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java
@@ -0,0 +1,90 @@
+/* ====================================================================
+ 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.xslf.usermodel;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.util.Beta;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
+import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* Slide master object associated with this layout.
+* <p>
+* Within a slide master slide are contained all elements
+* that describe the objects and their corresponding formatting
+* for within a presentation slide.
+* </p>
+* <p>
+* Within a slide master slide are two main elements.
+* The cSld element specifies the common slide elements such as shapes and
+* their attached text bodies. Then the txStyles element specifies the
+* formatting for the text within each of these shapes. The other properties
+* within a slide master slide specify other properties for within a presentation slide
+* such as color information, headers and footers, as well as timing and
+* transition information for all corresponding presentation slides.
+* </p>
+ *
+ * @author Yegor Kozlov
+*/
+@Beta
+ public class XSLFSlideMaster extends XSLFSheet {
+ private CTSlideMaster _slide;
+ private Map<String, XSLFSlideLayout> _layouts;
+
+ XSLFSlideMaster() {
+ super();
+ _slide = CTSlideMaster.Factory.newInstance();
+ }
+
+ protected XSLFSlideMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
+ super(part, rel);
+ SldMasterDocument doc =
+ SldMasterDocument.Factory.parse(getPackagePart().getInputStream());
+ _slide = doc.getSldMaster();
+ }
+
+ @Override
+ public CTSlideMaster getXmlObject() {
+ return _slide;
+ }
+
+ @Override
+ protected String getRootElementName(){
+ return "sldMaster";
+ }
+
+ public XSLFSlideLayout getLayout(String name){
+ if(_layouts == null){
+ _layouts = new HashMap<String, XSLFSlideLayout>();
+ for (POIXMLDocumentPart p : getRelations()) {
+ if (p instanceof XSLFSlideLayout){
+ XSLFSlideLayout layout = (XSLFSlideLayout)p;
+ _layouts.put(layout.getName().toLowerCase(), layout);
+ }
+ }
+ }
+ return _layouts.get(name);
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
new file mode 100755
index 0000000000..c009f5492d
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextBox.java
@@ -0,0 +1,97 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.util.Beta;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
+import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
+
+
+/**
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFTextBox extends XSLFAutoShape {
+
+ /*package*/ XSLFTextBox(CTShape shape, XSLFSheet sheet){
+ super(shape, sheet);
+ }
+
+ /**
+ *
+ * @param shapeId 1-based shapeId
+ */
+ static CTShape prototype(int shapeId){
+ CTShape ct = CTShape.Factory.newInstance();
+ CTShapeNonVisual nvSpPr = ct.addNewNvSpPr();
+ CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
+ cnv.setName("TextBox " + shapeId);
+ cnv.setId(shapeId + 1);
+ nvSpPr.addNewCNvSpPr().setTxBox(true);
+ nvSpPr.addNewNvPr();
+ CTShapeProperties spPr = ct.addNewSpPr();
+ CTPresetGeometry2D prst = spPr.addNewPrstGeom();
+ prst.setPrst(STShapeType.RECT);
+ prst.addNewAvLst();
+ CTTextBody txBody = ct.addNewTxBody();
+ txBody.addNewBodyPr();
+ txBody.addNewLstStyle();
+
+ return ct;
+ }
+
+ /**
+ * Specifies that the corresponding shape should be represented by the generating application
+ * as a placeholder. When a shape is considered a placeholder by the generating application
+ * it can have special properties to alert the user that they may enter content into the shape.
+ * Different types of placeholders are allowed and can be specified by using the placeholder
+ * type attribute for this element
+ *
+ * @param placeholder
+ */
+ public void setPlaceholder(Placeholder placeholder){
+ CTShape sh = (CTShape)getXmlObject();
+ CTApplicationNonVisualDrawingProps nv = sh.getNvSpPr().getNvPr();
+ if(placeholder == null) {
+ if(nv.isSetPh()) nv.unsetPh();
+ } else {
+ nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1));
+ }
+ }
+
+ public Placeholder getPlaceholder(){
+ CTShape sh = (CTShape)getXmlObject();
+ CTPlaceholder ph = sh.getNvSpPr().getNvPr().getPh();
+ if(ph == null) return null;
+ else {
+ int val = ph.getType().intValue();
+ return Placeholder.values()[val - 1];
+ }
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
new file mode 100755
index 0000000000..9317298ee3
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
@@ -0,0 +1,334 @@
+/* ====================================================================
+ 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.xslf.usermodel;
+
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.Units;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Represents a paragraph of text within the containing text body.
+ * The paragraph is the highest level text separation mechanism.
+ *
+ * @author Yegor Kozlov
+ * @since POI-3.8
+ */
+@Beta
+public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
+ private final CTTextParagraph _p;
+ private final List<XSLFTextRun> _runs;
+
+ XSLFTextParagraph(CTTextParagraph p){
+ _p = p;
+ _runs = new ArrayList<XSLFTextRun>();
+ for (CTRegularTextRun r : _p.getRList()) {
+ _runs.add(new XSLFTextRun(r));
+ }
+ }
+
+ public String getText(){
+ StringBuilder out = new StringBuilder();
+ for (CTRegularTextRun r : _p.getRList()) {
+ out.append(r.getT());
+ }
+ return out.toString();
+ }
+
+ @Internal
+ public CTTextParagraph getXmlObject(){
+ return _p;
+ }
+
+ public List<XSLFTextRun> getTextRuns(){
+ return _runs;
+ }
+
+ public Iterator<XSLFTextRun> iterator(){
+ return _runs.iterator();
+ }
+
+ public XSLFTextRun addNewTextRun(){
+ CTRegularTextRun r = _p.addNewR();
+ XSLFTextRun run = new XSLFTextRun(r);
+ _runs.add(run);
+ return run;
+ }
+
+ public void addLineBreak(){
+ _p.addNewBr();
+ }
+
+ /**
+ * Returns the alignment that is applied to the paragraph.
+ *
+ * If this attribute is omitted, then a value of left is implied.
+ * @return ??? alignment that is applied to the paragraph
+ */
+ public TextAlign getTextAlign(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetAlgn()) return TextAlign.LEFT;
+
+ return TextAlign.values()[pr.getAlgn().intValue() - 1];
+ }
+
+ /**
+ * Specifies the alignment that is to be applied to the paragraph.
+ * Possible values for this include left, right, centered, justified and distributed,
+ * see {@link org.apache.poi.xslf.usermodel.TextAlign}.
+ *
+ * @param align text align
+ */
+ public void setTextAlign(TextAlign align){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ if(align == null) {
+ if(pr.isSetAlgn()) pr.unsetAlgn();
+ } else {
+ pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1));
+ }
+ }
+
+ /**
+ * Specifies the indent size that will be applied to the first line of text in the paragraph.
+ *
+ * @param value the indent in points. The value of -1 unsets the indent attribute
+ * from the underlying xml bean.
+ */
+ public void setIndent(double value){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ if(value == -1) {
+ if(pr.isSetIndent()) pr.unsetIndent();
+ } else {
+ pr.setIndent(Units.toEMU(value));
+ }
+ }
+
+ /**
+ *
+ * @return the indent applied to the first line of text in the paragraph.
+ */
+ public double getIndent(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetIndent()) return 0;
+
+ return Units.toPoints(pr.getIndent());
+ }
+
+ /**
+ * Specifies the left margin of the paragraph. This is specified in addition to the text body
+ * inset and applies only to this text paragraph. That is the text body Inset and the LeftMargin
+ * attributes are additive with respect to the text position.
+ *
+ * @param value the left margin of the paragraph
+ */
+ public void setLeftMargin(double value){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ pr.setMarL(Units.toEMU(value));
+ }
+
+ /**
+ *
+ * @return the left margin of the paragraph
+ */
+ public double getLeftMargin(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetMarL()) return 0;
+
+ return Units.toPoints(pr.getMarL());
+ }
+
+ /**
+ * This element specifies the vertical line spacing that is to be used within a paragraph.
+ * This may be specified in two different ways, percentage spacing and font point spacing:
+ * <p>
+ * If linespacing >= 0, then linespacing is a percentage of normal line height
+ * If linespacing < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ * Examples:
+ * <pre><code>
+ * // spacing will be 120% of the size of the largest text on each line
+ * paragraph.setLineSpacing(120);
+ *
+ * // spacing will be 200% of the size of the largest text on each line
+ * paragraph.setLineSpacing(200);
+ *
+ * // spacing will be 48 points
+ * paragraph.setLineSpacing(-48.0);
+ * </code></pre>
+ *
+ * @param linespacing the vertical line spacing
+ */
+ public void setLineSpacing(double linespacing){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
+ if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000));
+ else spc.addNewSpcPts().setVal((int)(-linespacing*100));
+ pr.setLnSpc(spc);
+ }
+
+ /**
+ * Returns the vertical line spacing that is to be used within a paragraph.
+ * This may be specified in two different ways, percentage spacing and font point spacing:
+ * <p>
+ * If linespacing >= 0, then linespacing is a percentage of normal line height.
+ * If linespacing < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ *
+ * @return the vertical line spacing.
+ */
+ public double getLineSpacing(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetLnSpc()) return 100; // TODO fetch from master
+
+ CTTextSpacing spc = pr.getLnSpc();
+ if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
+ else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
+ else return 100;
+ }
+
+ /**
+ * Set the amount of vertical white space that will be present before the paragraph.
+ * This space is specified in either percentage or points:
+ * <p>
+ * If spaceBefore >= 0, then space is a percentage of normal line height.
+ * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ * Examples:
+ * <pre><code>
+ * // The paragraph will be formatted to have a spacing before the paragraph text.
+ * // The spacing will be 200% of the size of the largest text on each line
+ * paragraph.setSpaceBefore(200);
+ *
+ * // The spacing will be a size of 48 points
+ * paragraph.setSpaceBefore(-48.0);
+ * </code></pre>
+ *
+ * @param spaceBefore the vertical white space before the paragraph.
+ */
+ public void setSpaceBefore(double spaceBefore){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
+ if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000));
+ else spc.addNewSpcPts().setVal((int)(-spaceBefore*100));
+ pr.setSpcBef(spc);
+ }
+
+ /**
+ * The amount of vertical white space before the paragraph
+ * This may be specified in two different ways, percentage spacing and font point spacing:
+ * <p>
+ * If spaceBefore >= 0, then space is a percentage of normal line height.
+ * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ *
+ * @return the vertical white space before the paragraph
+ */
+ public double getSpaceBefore(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetSpcBef()) return 0; // TODO fetch from master
+
+ CTTextSpacing spc = pr.getSpcBef();
+ if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
+ else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
+ else return 0;
+ }
+
+ /**
+ * Set the amount of vertical white space that will be present after the paragraph.
+ * This space is specified in either percentage or points:
+ * <p>
+ * If spaceAfter >= 0, then space is a percentage of normal line height.
+ * If spaceAfter < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ * Examples:
+ * <pre><code>
+ * // The paragraph will be formatted to have a spacing after the paragraph text.
+ * // The spacing will be 200% of the size of the largest text on each line
+ * paragraph.setSpaceAfter(200);
+ *
+ * // The spacing will be a size of 48 points
+ * paragraph.setSpaceAfter(-48.0);
+ * </code></pre>
+ *
+ * @param spaceAfter the vertical white space after the paragraph.
+ */
+ public void setSpaceAfter(double spaceAfter){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+ CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
+ if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000));
+ else spc.addNewSpcPts().setVal((int)(-spaceAfter*100));
+ pr.setSpcAft(spc);
+ }
+
+ /**
+ * The amount of vertical white space after the paragraph
+ * This may be specified in two different ways, percentage spacing and font point spacing:
+ * <p>
+ * If spaceBefore >= 0, then space is a percentage of normal line height.
+ * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
+ * </p>
+ *
+ * @return the vertical white space after the paragraph
+ */
+ public double getSpaceAfter(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null || !pr.isSetSpcAft()) return 0; // TODO fetch from master
+
+ CTTextSpacing spc = pr.getSpcAft();
+ if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
+ else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
+ else return 0;
+ }
+
+ /**
+ * Specifies the particular level text properties that this paragraph will follow.
+ * The value for this attribute formats the text according to the corresponding level
+ * paragraph properties defined in the SlideMaster.
+ *
+ * @param level the level (0 ... 4)
+ */
+ public void setLevel(int level){
+ CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+
+ pr.setLvl(level);
+ }
+
+ /**
+ *
+ * @return the text level of this paragraph. Default is 0.
+ */
+ public int getLevel(){
+ CTTextParagraphProperties pr = _p.getPPr();
+ if(pr == null) return 0;
+
+ return pr.getLvl();
+
+ }
+
+ @Override
+ public String toString(){
+ return "[" + getClass() + "]" + getText();
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
new file mode 100755
index 0000000000..859649197b
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
@@ -0,0 +1,202 @@
+/* ====================================================================
+ 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.xslf.usermodel;
+
+import org.apache.poi.util.Beta;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
+
+import java.awt.*;
+
+/**
+ * Represents a run of text within the containing text body. The run element is the
+ * lowest level text separation mechanism within a text body.
+ *
+ * @author Yegor Kozlov
+ */
+@Beta
+public class XSLFTextRun {
+ private final CTRegularTextRun _r;
+
+ XSLFTextRun(CTRegularTextRun r){
+ _r = r;
+ }
+
+ public String getText(){
+ return _r.getT();
+ }
+
+ public void setText(String text){
+ _r.setT(text);
+ }
+
+ public CTRegularTextRun getXmlObject(){
+ return _r;
+ }
+
+ public void setFontColor(Color color){
+ CTTextCharacterProperties rPr = getRpR();
+ CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
+ CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
+ clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
+ }
+
+ /**
+ *
+ * @param fontSize font size in points.
+ * The value of <code>-1</code> unsets the Sz attribyte from the underlying xml bean
+ */
+ public void setFontSize(double fontSize){
+ CTTextCharacterProperties rPr = getRpR();
+ if(fontSize == -1.0) {
+ if(rPr.isSetSz()) rPr.unsetSz();
+ } else {
+ rPr.setSz((int)(100*fontSize));
+ }
+ }
+
+ /**
+ * @return font size in points or -1 if font size is not set.
+ */
+ public double getFontSize(){
+ if(!_r.isSetRPr()) return -1;
+
+ return _r.getRPr().getSz()*0.01;
+ }
+
+ /**
+ * Specifies the typeface, or name of the font that is to be used for this text run.
+ *
+ * @param typeface the font to apply to this text run.
+ * The value of <code>null</code> unsets the Typeface attrubute from the underlying xml.
+ */
+ public void setFontFamily(String typeface){
+ setFontFamily(typeface, (byte)-1, (byte)-1, false);
+ }
+
+ public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){
+ CTTextCharacterProperties rPr = getRpR();
+
+ if(typeface == null){
+ if(rPr.isSetLatin()) rPr.unsetLatin();
+ if(rPr.isSetCs()) rPr.unsetCs();
+ if(rPr.isSetSym()) rPr.unsetSym();
+ } else {
+ if(isSymbol){
+ CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym();
+ font.setTypeface(typeface);
+ } else {
+ CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin();
+ latin.setTypeface(typeface);
+ if(charset != -1) latin.setCharset(charset);
+ if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily);
+ }
+ }
+ }
+
+ /**
+ * @return font family or null if niot set
+ */
+ public String getFontFamily(){
+ if(!_r.isSetRPr() || !_r.getRPr().isSetLatin()) return null;
+
+ return _r.getRPr().getLatin().getTypeface();
+ }
+
+ /**
+ * Specifies whether a run of text will be formatted as strikethrough text.
+ *
+ * @param strike whether a run of text will be formatted as strikethrough text.
+ */
+ public void setStrikethrough(boolean strike){
+ getRpR().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
+ }
+
+ /**
+ * @return whether a run of text will be formatted as strikethrough text. Default is false.
+ */
+ public boolean isStrikethrough(){
+ if(!_r.isSetRPr()) return false;
+
+ return _r.getRPr().getStrike() == STTextStrikeType.SNG_STRIKE;
+ }
+
+ /**
+ * Specifies whether this run of text will be formatted as bold text
+ *
+ * @param bold whether this run of text will be formatted as bold text
+ */
+ public void setBold(boolean bold){
+ getRpR().setB(bold);
+ }
+
+ /**
+ * @return whether this run of text is formatted as bold text
+ */
+ public boolean isBold(){
+ if(!_r.isSetRPr()) return false;
+
+ return _r.getRPr().getB();
+ }
+
+ /**
+ * @param italic whether this run of text is formatted as italic text
+ */
+ public void setItalic(boolean italic){
+ getRpR().setI(italic);
+ }
+
+ /**
+ * @return whether this run of text is formatted as italic text
+ */
+ public boolean isItalic(){
+ if(!_r.isSetRPr()) return false;
+
+ return _r.getRPr().getI();
+ }
+
+ /**
+ * @param underline whether this run of text is formatted as underlined text
+ */
+ public void setUnderline(boolean underline){
+ getRpR().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
+ }
+
+ /**
+ * @return whether this run of text is formatted as underlined text
+ */
+ public boolean isUnderline(){
+ if(!_r.isSetRPr() || !_r.getRPr().isSetU()) return false;
+
+ return _r.getRPr().getU() != STTextUnderlineType.NONE;
+ }
+
+ protected CTTextCharacterProperties getRpR(){
+ return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr();
+ }
+
+ @Override
+ public String toString(){
+ return "[" + getClass() + "]" + getText();
+ }
+
+} \ No newline at end of file