Common sl unification - copy first paragraph / textrun properties on XSLFTextShape.setText()

Common sl unification - converted ApacheconEU08 example to common sl - added missing functionality
Common sl unification - return null instead of default values for missing borders X/HSLFTable
Common sl unification - use points in HSLFTable.setColumnWidth()
Fix appending text to empty HSLFTextParagraph


git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1711171 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2015-10-29 01:05:27 +00:00
parent 632228a34e
commit 1d1bdc1521
57 changed files with 4058 additions and 1159 deletions

View File

@ -26,19 +26,20 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.poi.hslf.model.PPGraphics2D;
import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.hslf.usermodel.HSLFAutoShape;
import org.apache.poi.hslf.usermodel.HSLFGroupShape;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTable; import org.apache.poi.sl.draw.DrawTableShape;
import org.apache.poi.hslf.usermodel.HSLFTableCell; import org.apache.poi.sl.draw.SLGraphics;
import org.apache.poi.hslf.usermodel.HSLFTextBox; import org.apache.poi.sl.usermodel.AutoShape;
import org.apache.poi.hslf.usermodel.HSLFTextParagraph; import org.apache.poi.sl.usermodel.GroupShape;
import org.apache.poi.hslf.usermodel.HSLFTextRun;
import org.apache.poi.hslf.usermodel.HSLFLine;
import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.TableShape;
import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape.TextPlaceholder;
import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.sl.usermodel.VerticalAlignment;
/** /**
@ -49,7 +50,8 @@ import org.apache.poi.sl.usermodel.VerticalAlignment;
public final class ApacheconEU08 { public final class ApacheconEU08 {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow(); SlideShow<?,?> ppt = new HSLFSlideShow();
// SlideShow<?,?> ppt = new XMLSlideShow();
ppt.setPageSize(new Dimension(720, 540)); ppt.setPageSize(new Dimension(720, 540));
slide1(ppt); slide1(ppt);
@ -65,69 +67,62 @@ public final class ApacheconEU08 {
slide11(ppt); slide11(ppt);
slide12(ppt); slide12(ppt);
FileOutputStream out = new FileOutputStream("apachecon_eu_08.ppt"); String ext = ppt.getClass().getName().contains("HSLF") ? "ppt" : "pptx";
FileOutputStream out = new FileOutputStream("apachecon_eu_08."+ext);
ppt.write(out); ppt.write(out);
out.close(); out.close();
} }
public static void slide1(HSLFSlideShow ppt) throws IOException { public static void slide1(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE);
box1.setText("POI-HSLF"); box1.setText("POI-HSLF");
box1.setAnchor(new Rectangle(54, 78, 612, 115)); box1.setAnchor(new Rectangle(54, 78, 612, 115));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY);
box2.setText("Java API To Access Microsoft PowerPoint Format Files"); box2.setText("Java API To Access Microsoft PowerPoint Format Files");
box2.setAnchor(new Rectangle(108, 204, 504, 138)); box2.setAnchor(new Rectangle(108, 204, 504, 138));
slide.addShape(box2);
HSLFTextBox box3 = new HSLFTextBox(); TextBox<?,?> box3 = slide.createTextBox();
box3.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32d); box3.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(32d);
box3.setText( box3.setText(
"Yegor Kozlov\r" + "Yegor Kozlov\r" +
"yegor - apache - org"); "yegor - apache - org");
box3.setHorizontalCentered(true); box3.setHorizontalCentered(true);
box3.setAnchor(new Rectangle(206, 348, 310, 84)); box3.setAnchor(new Rectangle(206, 348, 310, 84));
slide.addShape(box3);
} }
public static void slide2(HSLFSlideShow ppt) throws IOException { public static void slide2(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("What is HSLF?"); box1.setText("What is HSLF?");
box1.setAnchor(new Rectangle(36, 21, 648, 90)); box1.setAnchor(new Rectangle(36, 21, 648, 90));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " + box2.setText("HorribleSLideshowFormat is the POI Project's pure Java implementation " +
"of the Powerpoint binary file format. \r" + "of the Powerpoint binary file format. \r" +
"POI sub-project since 2005\r" + "POI sub-project since 2005\r" +
"Started by Nick Birch, Yegor Kozlov joined soon after"); "Started by Nick Burch, Yegor Kozlov joined soon after");
box2.setAnchor(new Rectangle(36, 126, 648, 356)); box2.setAnchor(new Rectangle(36, 126, 648, 356));
slide.addShape(box2);
} }
public static void slide3(HSLFSlideShow ppt) throws IOException { public static void slide3(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in a Nutshell"); box1.setText("HSLF in a Nutshell");
box1.setAnchor(new Rectangle(36, 15, 648, 65)); box1.setAnchor(new Rectangle(36, 15, 648, 65));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText( box2.setText(
"HSLF provides a way to read, create and modify MS PowerPoint presentations\r" + "HSLF provides a way to read, create and modify MS PowerPoint presentations\r" +
"Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" + "Pure Java API - you don't need PowerPoint to read and write *.ppt files\r" +
@ -140,7 +135,7 @@ public final class ApacheconEU08 {
"Access to low level data structures" "Access to low level data structures"
); );
List<HSLFTextParagraph> tp = box2.getTextParagraphs(); List<? extends TextParagraph<?,?,?>> tp = box2.getTextParagraphs();
for (int i : new byte[]{0,1,2,8}) { for (int i : new byte[]{0,1,2,8}) {
tp.get(i).getTextRuns().get(0).setFontSize(28d); tp.get(i).getTextRuns().get(0).setFontSize(28d);
} }
@ -149,102 +144,88 @@ public final class ApacheconEU08 {
tp.get(i).setIndentLevel(1); tp.get(i).setIndentLevel(1);
} }
box2.setAnchor(new Rectangle(36, 80, 648, 400)); box2.setAnchor(new Rectangle(36, 80, 648, 400));
slide.addShape(box2);
} }
public static void slide4(HSLFSlideShow ppt) throws IOException { public static void slide4(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
String[][] txt1 = { String[][] txt1 = {
{"Note"}, {"Note"},
{"This presentation was created programmatically using POI HSLF"} {"This presentation was created programmatically using POI HSLF"}
}; };
HSLFTable table1 = new HSLFTable(2, 1); TableShape<?,?> table1 = slide.createTable(2, 1);
for (int i = 0; i < txt1.length; i++) { for (int i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) { for (int j = 0; j < txt1[i].length; j++) {
HSLFTableCell cell = table1.getCell(i, j); TableCell<?,?> cell = table1.getCell(i, j);
cell.setText(txt1[i][j]); cell.setText(txt1[i][j]);
HSLFTextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0); TextRun rt = cell.getTextParagraphs().get(0).getTextRuns().get(0);
rt.setFontSize(10d); rt.setFontSize(10d);
rt.setFontFamily("Arial"); rt.setFontFamily("Arial");
rt.setBold(true); rt.setBold(true);
if(i == 0){ if(i == 0){
rt.setFontSize(32d); rt.setFontSize(32d);
rt.setFontColor(Color.white); rt.setFontColor(Color.white);
cell.getFill().setForegroundColor(new Color(0, 153, 204)); cell.setFillColor(new Color(0, 153, 204));
} else { } else {
rt.setFontSize(28d); rt.setFontSize(28d);
cell.getFill().setForegroundColor(new Color(235, 239, 241)); cell.setFillColor(new Color(235, 239, 241));
} }
cell.setVerticalAlignment(VerticalAlignment.MIDDLE); cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
} }
} }
HSLFLine border1 = table1.createBorder(); DrawTableShape dts = new DrawTableShape(table1);
border1.setLineColor(Color.black); dts.setAllBorders(1.0, Color.black);
border1.setLineWidth(1.0); dts.setOutsideBorders(4.0);
table1.setAllBorders(border1);
HSLFLine border2 = table1.createBorder(); table1.setColumnWidth(0, 450);
border2.setLineColor(Color.black); table1.setRowHeight(0, 50);
border2.setLineWidth(2.0); table1.setRowHeight(1, 80);
table1.setOutsideBorders(border2);
table1.setColumnWidth(0, 510); Dimension dim = ppt.getPageSize();
table1.setRowHeight(0, 60); Rectangle oldAnchor = table1.getAnchor();
table1.setRowHeight(1, 100); table1.setAnchor(new Rectangle((dim.width-450)/2, 100, oldAnchor.width, oldAnchor.height));
slide.addShape(table1);
table1.moveTo(100, 100); TextBox<?,?> box1 = slide.createTextBox();
HSLFTextBox box1 = new HSLFTextBox();
box1.setHorizontalCentered(true); box1.setHorizontalCentered(true);
box1.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(24d); box1.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(24d);
box1.setText("The source code is available at\r" + box1.setText("The source code is available at\r" +
"http://people.apache.org/~yegor/apachecon_eu08/"); "http://people.apache.org/~yegor/apachecon_eu08/");
box1.setAnchor(new Rectangle(80, 356, 553, 65)); box1.setAnchor(new Rectangle(80, 356, 553, 65));
slide.addShape(box1);
} }
public static void slide5(HSLFSlideShow ppt) throws IOException { public static void slide5(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 1\rData Extraction"); box1.setText("HSLF in Action - 1\rData Extraction");
box1.setAnchor(new Rectangle(36, 21, 648, 100)); box1.setAnchor(new Rectangle(36, 21, 648, 100));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText( box2.setText(
"Text from slides and notes\r" + "Text from slides and notes\r" +
"Images\r" + "Images\r" +
"Shapes and their properties (type, position in the slide, color, font, etc.)"); "Shapes and their properties (type, position in the slide, color, font, etc.)");
box2.setAnchor(new Rectangle(36, 150, 648, 300)); box2.setAnchor(new Rectangle(36, 150, 648, 300));
slide.addShape(box2);
} }
public static void slide6(HSLFSlideShow ppt) throws IOException { public static void slide6(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 2"); box1.setText("HSLF in Action - 2");
box1.setAnchor(new Rectangle(36, 20, 648, 90)); box1.setAnchor(new Rectangle(36, 20, 648, 90));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d); box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d);
box2.setText("Creating a simple presentation from scratch"); box2.setText("Creating a simple presentation from scratch");
box2.setAnchor(new Rectangle(170, 100, 364, 30)); box2.setAnchor(new Rectangle(170, 100, 364, 30));
slide.addShape(box2);
HSLFTextBox box3 = new HSLFTextBox(); TextBox<?,?> box3 = slide.createTextBox();
HSLFTextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0); TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
rt3.setFontFamily("Courier New"); rt3.setFontFamily("Courier New");
rt3.setFontSize(8d); rt3.setFontSize(8d);
box3.setText( box3.setText(
@ -283,77 +264,67 @@ public final class ApacheconEU08 {
"out.close();"); "out.close();");
box3.setAnchor(new Rectangle(30, 150, 618, 411)); box3.setAnchor(new Rectangle(30, 150, 618, 411));
box3.setHorizontalCentered(true); box3.setHorizontalCentered(true);
slide.addShape(box3);
} }
public static void slide7(HSLFSlideShow ppt) throws IOException { public static void slide7(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setHorizontalCentered(true); box2.setHorizontalCentered(true);
box2.setVerticalAlignment(VerticalAlignment.MIDDLE); box2.setVerticalAlignment(VerticalAlignment.MIDDLE);
box2.setText("Java Code"); box2.setText("Java Code");
box2.getFill().setForegroundColor(new Color(187, 224, 227)); box2.setFillColor(new Color(187, 224, 227));
box2.setLineColor(Color.black); box2.setStrokeStyle(0.75, Color.black);
box2.setLineWidth(0.75);
box2.setAnchor(new Rectangle(66, 243, 170, 170)); box2.setAnchor(new Rectangle(66, 243, 170, 170));
slide.addShape(box2);
HSLFTextBox box3 = new HSLFTextBox(); TextBox<?,?> box3 = slide.createTextBox();
box3.setHorizontalCentered(true); box3.setHorizontalCentered(true);
box3.setVerticalAlignment(VerticalAlignment.MIDDLE); box3.setVerticalAlignment(VerticalAlignment.MIDDLE);
box3.setText("*.ppt file"); box3.setText("*.ppt file");
box3.setLineWidth(0.75); box3.setFillColor(new Color(187, 224, 227));
box3.setLineColor(Color.black); box3.setStrokeStyle(0.75, Color.black);
box3.getFill().setForegroundColor(new Color(187, 224, 227));
box3.setAnchor(new Rectangle(473, 243, 170, 170)); box3.setAnchor(new Rectangle(473, 243, 170, 170));
slide.addShape(box3);
HSLFAutoShape box4 = new HSLFAutoShape(ShapeType.RIGHT_ARROW); AutoShape<?,?> box4 = slide.createAutoShape();
box4.getFill().setForegroundColor(new Color(187, 224, 227)); box4.setShapeType(ShapeType.RIGHT_ARROW);
box4.setLineWidth(0.75); box4.setFillColor(new Color(187, 224, 227));
box4.setLineColor(Color.black); box4.setStrokeStyle(0.75, Color.black);
box4.setAnchor(new Rectangle(253, 288, 198, 85)); box4.setAnchor(new Rectangle(253, 288, 198, 85));
slide.addShape(box4);
} }
public static void slide8(HSLFSlideShow ppt) throws IOException { public static void slide8(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("Wait, there is more!"); box1.setText("Wait, there is more!");
box1.setAnchor(new Rectangle(36, 21, 648, 90)); box1.setAnchor(new Rectangle(36, 21, 648, 90));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText( box2.setText(
"Rich text\r" + "Rich text\r" +
"Tables\r" + "Tables\r" +
"Pictures (JPEG, PNG, BMP, WMF, PICT)\r" + "Pictures (JPEG, PNG, BMP, WMF, PICT)\r" +
"Comprehensive formatting features"); "Comprehensive formatting features");
box2.setAnchor(new Rectangle(36, 126, 648, 356)); box2.setAnchor(new Rectangle(36, 126, 648, 356));
slide.addShape(box2);
} }
public static void slide9(HSLFSlideShow ppt) throws IOException { public static void slide9(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF in Action - 3"); box1.setText("HSLF in Action - 3");
box1.setAnchor(new Rectangle(36, 20, 648, 50)); box1.setAnchor(new Rectangle(36, 20, 648, 50));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d); box2.getTextParagraphs().get(0).getTextRuns().get(0).setFontSize(18d);
box2.setText("PPGraphics2D: PowerPoint Graphics2D driver"); box2.setText("PPGraphics2D: PowerPoint Graphics2D driver");
box2.setAnchor(new Rectangle(178, 70, 387, 30)); box2.setAnchor(new Rectangle(178, 70, 387, 30));
slide.addShape(box2);
HSLFTextBox box3 = new HSLFTextBox(); TextBox<?,?> box3 = slide.createTextBox();
HSLFTextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0); TextRun rt3 = box3.getTextParagraphs().get(0).getTextRuns().get(0);
rt3.setFontFamily("Courier New"); rt3.setFontFamily("Courier New");
rt3.setFontSize(8d); rt3.setFontSize(8d);
box3.setText( box3.setText(
@ -397,10 +368,9 @@ public final class ApacheconEU08 {
"out.close();"); "out.close();");
box3.setAnchor(new Rectangle(96, 110, 499, 378)); box3.setAnchor(new Rectangle(96, 110, 499, 378));
box3.setHorizontalCentered(true); box3.setHorizontalCentered(true);
slide.addShape(box3);
} }
public static void slide10(HSLFSlideShow ppt) throws IOException { public static void slide10(SlideShow<?,?> ppt) throws IOException {
//bar chart data. The first value is the bar color, the second is the width //bar chart data. The first value is the bar color, the second is the width
Object[] def = new Object[]{ Object[] def = new Object[]{
Color.yellow, new Integer(100), Color.yellow, new Integer(100),
@ -409,14 +379,13 @@ public final class ApacheconEU08 {
Color.red, new Integer(200), Color.red, new Integer(200),
}; };
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFGroupShape group = new HSLFGroupShape(); GroupShape<?,?> group = slide.createGroup();
//define position of the drawing in the slide //define position of the drawing in the slide
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300); Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
group.setAnchor(bounds); group.setAnchor(bounds);
slide.addShape(group); Graphics2D graphics = new SLGraphics(group);
Graphics2D graphics = new PPGraphics2D(group);
//draw a simple bar graph //draw a simple bar graph
int x = bounds.x + 50, y = bounds.y + 50; int x = bounds.x + 50, y = bounds.y + 50;
@ -437,17 +406,16 @@ public final class ApacheconEU08 {
} }
public static void slide11(HSLFSlideShow ppt) throws IOException { public static void slide11(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.TITLE);
box1.setText("HSLF Development Plans"); box1.setText("HSLF Development Plans");
box1.setAnchor(new Rectangle(36, 21, 648, 90)); box1.setAnchor(new Rectangle(36, 21, 648, 90));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.BODY);
box2.setText( box2.setText(
"Support for more PowerPoint functionality\r" + "Support for more PowerPoint functionality\r" +
"Rendering slides into java.awt.Graphics2D\r" + "Rendering slides into java.awt.Graphics2D\r" +
@ -457,7 +425,7 @@ public final class ApacheconEU08 {
"PPT2PDF transcoder" "PPT2PDF transcoder"
); );
List<HSLFTextParagraph> tp = box2.getTextParagraphs(); List<? extends TextParagraph<?,?,?>> tp = box2.getTextParagraphs();
for (int i : new byte[]{0,1,3}) { for (int i : new byte[]{0,1,3}) {
tp.get(i).getTextRuns().get(0).setFontSize(28d); tp.get(i).getTextRuns().get(0).setFontSize(28d);
} }
@ -467,24 +435,21 @@ public final class ApacheconEU08 {
} }
box2.setAnchor(new Rectangle(36, 126, 648, 400)); box2.setAnchor(new Rectangle(36, 126, 648, 400));
slide.addShape(box2);
} }
public static void slide12(HSLFSlideShow ppt) throws IOException { public static void slide12(SlideShow<?,?> ppt) throws IOException {
HSLFSlide slide = ppt.createSlide(); Slide<?,?> slide = ppt.createSlide();
HSLFTextBox box1 = new HSLFTextBox(); TextBox<?,?> box1 = slide.createTextBox();
box1.setRunType(TextHeaderAtom.CENTER_TITLE_TYPE); box1.setTextPlaceholder(TextPlaceholder.CENTER_TITLE);
box1.setText("Questions?"); box1.setText("Questions?");
box1.setAnchor(new Rectangle(54, 167, 612, 115)); box1.setAnchor(new Rectangle(54, 167, 612, 115));
slide.addShape(box1);
HSLFTextBox box2 = new HSLFTextBox(); TextBox<?,?> box2 = slide.createTextBox();
box2.setRunType(TextHeaderAtom.CENTRE_BODY_TYPE); box2.setTextPlaceholder(TextPlaceholder.CENTER_BODY);
box2.setText( box2.setText(
"http://poi.apache.org/hslf/\r" + "http://poi.apache.org/hslf/\r" +
"http://people.apache.org/~yegor"); "http://people.apache.org/~yegor");
box2.setAnchor(new Rectangle(108, 306, 504, 138)); box2.setAnchor(new Rectangle(108, 306, 504, 138));
slide.addShape(box2);
} }
} }

View File

@ -25,7 +25,7 @@ import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTable; import org.apache.poi.hslf.usermodel.HSLFTable;
import org.apache.poi.hslf.usermodel.HSLFTableCell; import org.apache.poi.hslf.usermodel.HSLFTableCell;
import org.apache.poi.hslf.usermodel.HSLFTextRun; import org.apache.poi.hslf.usermodel.HSLFTextRun;
import org.apache.poi.hslf.usermodel.HSLFLine; import org.apache.poi.sl.draw.DrawTableShape;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.sl.usermodel.VerticalAlignment;
@ -53,7 +53,7 @@ public final class TableDemo {
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
//six rows, two columns //six rows, two columns
HSLFTable table1 = new HSLFTable(6, 2); HSLFTable table1 = slide.createTable(6, 2);
for (int i = 0; i < txt1.length; i++) { for (int i = 0; i < txt1.length; i++) {
for (int j = 0; j < txt1[i].length; j++) { for (int j = 0; j < txt1[i].length; j++) {
HSLFTableCell cell = table1.getCell(i, j); HSLFTableCell cell = table1.getCell(i, j);
@ -71,15 +71,12 @@ public final class TableDemo {
} }
} }
HSLFLine border1 = table1.createBorder(); DrawTableShape dts1 = new DrawTableShape(table1);
border1.setLineColor(Color.black); dts1.setAllBorders(1.0, Color.black);
border1.setLineWidth(1.0);
table1.setAllBorders(border1);
table1.setColumnWidth(0, 300); table1.setColumnWidth(0, 300);
table1.setColumnWidth(1, 150); table1.setColumnWidth(1, 150);
slide.addShape(table1);
int pgWidth = ppt.getPageSize().width; int pgWidth = ppt.getPageSize().width;
table1.moveTo((pgWidth - table1.getAnchor().width)/2, 100); table1.moveTo((pgWidth - table1.getAnchor().width)/2, 100);
@ -92,7 +89,7 @@ public final class TableDemo {
}; };
//two rows, one column //two rows, one column
HSLFTable table2 = new HSLFTable(2, 1); HSLFTable table2 = slide.createTable(2, 1);
for (int i = 0; i < txt2.length; i++) { for (int i = 0; i < txt2.length; i++) {
for (int j = 0; j < txt2[i].length; j++) { for (int j = 0; j < txt2[i].length; j++) {
HSLFTableCell cell = table2.getCell(i, j); HSLFTableCell cell = table2.getCell(i, j);
@ -119,10 +116,9 @@ public final class TableDemo {
table2.setRowHeight(0, 30); table2.setRowHeight(0, 30);
table2.setRowHeight(1, 70); table2.setRowHeight(1, 70);
HSLFLine border2 = table2.createBorder(); DrawTableShape dts2 = new DrawTableShape(table2);
table2.setOutsideBorders(border2); dts2.setOutsideBorders(Color.black, 1.0);
slide.addShape(table2);
table2.moveTo(200, 400); table2.moveTo(200, 400);
FileOutputStream out = new FileOutputStream("hslf-table.ppt"); FileOutputStream out = new FileOutputStream("hslf-table.ppt");

View File

@ -23,6 +23,8 @@ import java.awt.Rectangle;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
/** /**
* How to set slide title * How to set slide title
* *

View File

@ -24,6 +24,7 @@ import java.awt.Rectangle;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
/** /**
@ -56,8 +57,8 @@ public class Tutorial4 {
r.setBold(true); r.setBold(true);
r.setFontColor(Color.white); r.setFontColor(Color.white);
th.setFillColor(new Color(79, 129, 189)); th.setFillColor(new Color(79, 129, 189));
th.setBorderBottom(2); th.setBorderWidth(BorderEdge.bottom, 2.0);
th.setBorderBottomColor(Color.white); th.setBorderColor(BorderEdge.bottom, Color.white);
tbl.setColumnWidth(i, 150); // all columns are equally sized tbl.setColumnWidth(i, 150); // all columns are equally sized
} }

View File

@ -17,9 +17,15 @@
package org.apache.poi.sl.draw; package org.apache.poi.sl.draw;
import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import org.apache.poi.sl.usermodel.GroupShape; import org.apache.poi.sl.usermodel.GroupShape;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.TableShape; import org.apache.poi.sl.usermodel.TableShape;
public class DrawTableShape extends DrawShape { public class DrawTableShape extends DrawShape {
@ -57,5 +63,111 @@ public class DrawTableShape extends DrawShape {
} }
} }
@Override
protected TableShape<?,?> getShape() {
return (TableShape<?,?>)shape;
}
/**
* Format the table and apply the specified Line to all cell boundaries,
* both outside and inside.
* An empty args parameter removes the affected border.
*
* @param args a varargs array possible containing {@link Double} (width),
* {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
*/
public void setAllBorders(Object... args) {
TableShape<?,?> table = getShape();
final int rows = table.getNumberOfRows();
final int cols = table.getNumberOfColumns();
BorderEdge edges[] = { BorderEdge.top, BorderEdge.left, null, null };
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
edges[2] = (col == cols - 1) ? BorderEdge.right : null;
edges[3] = (row == rows - 1) ? BorderEdge.bottom : null;
setEdges(table.getCell(row, col), edges, args);
}
}
}
/**
* Format the outside border using the specified Line object
* An empty args parameter removes the affected border.
*
* @param args a varargs array possible containing {@link Double} (width),
* {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
*/
public void setOutsideBorders(Object... args){
if (args.length == 0) return;
TableShape<?,?> table = getShape();
final int rows = table.getNumberOfRows();
final int cols = table.getNumberOfColumns();
BorderEdge edges[] = new BorderEdge[4];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
edges[0] = (col == 0) ? BorderEdge.left : null;
edges[1] = (col == cols - 1) ? BorderEdge.right : null;
edges[2] = (row == 0) ? BorderEdge.top : null;
edges[3] = (row == rows - 1) ? BorderEdge.bottom : null;
setEdges(table.getCell(row, col), edges, args);
}
}
}
/**
* Format the inside border using the specified Line object
* An empty args parameter removes the affected border.
*
* @param args a varargs array possible containing {@link Double} (width),
* {@link StrokeStyle.LineCompound}, {@link Color}, {@link StrokeStyle.LineDash}
*/
public void setInsideBorders(Object... args) {
if (args.length == 0) return;
TableShape<?,?> table = getShape();
final int rows = table.getNumberOfRows();
final int cols = table.getNumberOfColumns();
BorderEdge edges[] = new BorderEdge[2];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
edges[0] = (col > 0 && col < cols - 1) ? BorderEdge.right : null;
edges[1] = (row > 0 && row < rows - 1) ? BorderEdge.bottom : null;
setEdges(table.getCell(row, col), edges, args);
}
}
}
/**
* Apply the border attributes (args) to the given cell and edges
*
* @param cell the cell
* @param edges the border edges
* @param args the border attributes
*/
private static void setEdges(TableCell<?,?> cell, BorderEdge edges[], Object... args) {
for (BorderEdge be : edges) {
if (be != null) {
if (args.length == 0) {
cell.removeBorder(be);
} else {
for (Object o : args) {
if (o instanceof Double) {
cell.setBorderWidth(be, (Double)o);
} else if (o instanceof Color) {
cell.setBorderColor(be, (Color)o);
} else if (o instanceof LineDash) {
cell.setBorderDash(be, (LineDash)o);
} else if (o instanceof LineCompound) {
cell.setBorderCompound(be, (LineCompound)o);
}
}
}
}
}
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
import java.awt.Color;
import org.apache.poi.sl.draw.geom.CustomGeometry; import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.IAdjustableShape; import org.apache.poi.sl.draw.geom.IAdjustableShape;
@ -25,15 +27,66 @@ public interface SimpleShape<
S extends Shape<S,P>, S extends Shape<S,P>,
P extends TextParagraph<S,P,?> P extends TextParagraph<S,P,?>
> extends Shape<S,P>, IAdjustableShape, PlaceableShape<S,P> { > extends Shape<S,P>, IAdjustableShape, PlaceableShape<S,P> {
enum Placeholder {
TITLE,
BODY,
CENTERED_TITLE,
SUBTITLE,
DATETIME,
SLIDE_NUMBER,
FOOTER,
HEADER,
CONTENT,
CHART,
TABLE,
CLIP_ART,
DGM,
MEDIA,
SLIDE_IMAGE,
PICTURE
}
FillStyle getFillStyle(); FillStyle getFillStyle();
LineDecoration getLineDecoration(); LineDecoration getLineDecoration();
StrokeStyle getStrokeStyle(); StrokeStyle getStrokeStyle();
/**
* Sets the line attributes.
* Possible attributes are Double (width), LineCap, LineDash, LineCompound, Color
* (implementations of PaintStyle aren't yet supported ...)
*
* If no styles are given, the line will be hidden
*
* @param styles the line attributes
*/
void setStrokeStyle(Object... styles);
CustomGeometry getGeometry(); CustomGeometry getGeometry();
ShapeType getShapeType(); ShapeType getShapeType();
void setShapeType(ShapeType type);
boolean isPlaceholder(); boolean isPlaceholder();
Shadow<S,P> getShadow(); Shadow<S,P> getShadow();
/**
* Returns the solid color fill.
*
* @return solid fill color of null if not set or fill color
* is not solid (pattern or gradient)
*/
Color getFillColor();
/**
* 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 solid fill attribute from the underlying implementation
*/
void setFillColor(Color color);
} }

View File

@ -49,6 +49,13 @@ public interface SlideShow<
*/ */
Dimension getPageSize(); Dimension getPageSize();
/**
* Change the current page size
*
* @param pgsize page size (in points)
*/
void setPageSize(Dimension pgsize);
/** /**
* Returns all Pictures of this slideshow. * Returns all Pictures of this slideshow.
* The returned {@link List} is unmodifiable. * The returned {@link List} is unmodifiable.

View File

@ -20,18 +20,27 @@ package org.apache.poi.sl.usermodel;
public interface StrokeStyle { public interface StrokeStyle {
enum LineCap { enum LineCap {
/** Rounded ends */ /** Rounded ends */
ROUND(1), ROUND(0,1),
/** Square protrudes by half line width */ /** Square protrudes by half line width */
SQUARE(2), SQUARE(1,2),
/** Line ends at end point*/ /** Line ends at end point*/
FLAT(3); FLAT(2,3);
public final int nativeId;
public final int ooxmlId; public final int ooxmlId;
LineCap(int ooxmlId) { LineCap(int nativeId, int ooxmlId) {
this.nativeId = nativeId;
this.ooxmlId = ooxmlId; this.ooxmlId = ooxmlId;
} }
public static LineCap fromNativeId(int nativeId) {
for (LineCap ld : values()) {
if (ld.nativeId == nativeId) return ld;
}
return null;
}
public static LineCap fromOoxmlId(int ooxmlId) { public static LineCap fromOoxmlId(int ooxmlId) {
for (LineCap lc : values()) { for (LineCap lc : values()) {
if (lc.ooxmlId == ooxmlId) return lc; if (lc.ooxmlId == ooxmlId) return lc;
@ -96,20 +105,22 @@ public interface StrokeStyle {
enum LineCompound { enum LineCompound {
/** Single line (of width lineWidth) - native 0 / ooxml default */ /** Single line (of width lineWidth) - native 0 / ooxml default */
SINGLE(0), SINGLE(0, 1),
/** Double lines of equal width - native 1 / ooxml "dbl" */ /** Double lines of equal width - native 1 / ooxml "dbl" */
DOUBLE(1), DOUBLE(1, 2),
/** Double lines, one thick, one thin - native 2 / ooxml "thickThin" */ /** Double lines, one thick, one thin - native 2 / ooxml "thickThin" */
THICK_THIN(2), THICK_THIN(2, 3),
/** Double lines, reverse order - native 3 / ooxml "thinThick" */ /** Double lines, reverse order - native 3 / ooxml "thinThick" */
THIN_THICK(3), THIN_THICK(3, 4),
/** Three lines, thin, thick, thin - native 4 / ooxml "tri" */ /** Three lines, thin, thick, thin - native 4 / ooxml "tri" */
TRIPLE(4); TRIPLE(4, 5);
public final int nativeId; public final int nativeId;
public final int ooxmlId;
LineCompound(int nativeId) { LineCompound(int nativeId, int ooxmlId) {
this.nativeId = nativeId; this.nativeId = nativeId;
this.ooxmlId = ooxmlId;
} }
public static LineCompound fromNativeId(int nativeId) { public static LineCompound fromNativeId(int nativeId) {
@ -118,6 +129,13 @@ public interface StrokeStyle {
} }
return null; return null;
} }
public static LineCompound fromOoxmlId(int ooxmlId) {
for (LineCompound lc : values()) {
if (lc.ooxmlId == ooxmlId) return lc;
}
return null;
}
} }

View File

@ -17,9 +17,70 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
import java.awt.Color;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
public interface TableCell< public interface TableCell<
S extends Shape<S,P>, S extends Shape<S,P>,
P extends TextParagraph<S,P,?> P extends TextParagraph<S,P,?>
> extends TextShape<S,P> { > extends TextShape<S,P> {
enum BorderEdge { bottom, left, top, right };
/**
* Return line style of given edge or {@code null} if border is not defined
*
* @param edge the border edge
* @return line style of given edge or {@code null} if border is not defined
*/
StrokeStyle getBorderStyle(BorderEdge edge);
/**
* Sets the {@link StrokeStyle} of the given border edge.
* A {@code null} property of the style is ignored.
*
* @param edge border edge
* @param style the new stroke style
*/
void setBorderStyle(BorderEdge edge, StrokeStyle style);
/**
* Convenience method for setting the border width.
*
* @param edge border edge
* @param width the new border width
*/
void setBorderWidth(BorderEdge edge, double width);
/**
* Convenience method for setting the border color.
*
* @param edge border edge
* @param color the new border color
*/
void setBorderColor(BorderEdge edge, Color color);
/**
* Convenience method for setting the border line compound.
*
* @param edge border edge
* @param compound the new border line compound
*/
void setBorderCompound(BorderEdge edge, LineCompound compound);
/**
* Convenience method for setting the border line dash.
*
* @param edge border edge
* @param dash the new border line dash
*/
void setBorderDash(BorderEdge edge, LineDash dash);
/**
* Remove all line attributes of the given border edge
*
* @param edge the border edge to be cleared
*/
void removeBorder(BorderEdge edge);
} }

View File

@ -21,5 +21,25 @@ public interface TableShape<
S extends Shape<S,P>, S extends Shape<S,P>,
P extends TextParagraph<S,P,?> P extends TextParagraph<S,P,?>
> extends Shape<S,P>, PlaceableShape<S,P> { > extends Shape<S,P>, PlaceableShape<S,P> {
// to be defined ... int getNumberOfColumns();
int getNumberOfRows();
TableCell<S,P> getCell(int row, int col);
/**
* Sets the width (in points) of the n-th column
*
* @param idx the column index (0-based)
* @param width the width (in points)
*/
void setColumnWidth(int idx, double width);
/**
* Sets the row height.
*
* @param row the row index (0-based)
* @param height the height to set (in points)
*/
void setRowHeight(int row, double height);
} }

View File

@ -17,6 +17,13 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
/**
* Represents a TextFrame shape in PowerPoint.
* <p>
* Contains the text in a text frame as well as the properties and methods
* that control alignment and anchoring of the text.
* </p>
*/
public interface TextBox< public interface TextBox<
S extends Shape<S,P>, S extends Shape<S,P>,
P extends TextParagraph<S,P,?> P extends TextParagraph<S,P,?>

View File

@ -18,6 +18,7 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
import java.awt.Color; import java.awt.Color;
import java.util.List;
@ -339,4 +340,9 @@ public interface TextParagraph<
TextShape<S,P> getParentShape(); TextShape<S,P> getParentShape();
/**
* Fetch the text runs that are contained within this block of text
*/
List<T> getTextRuns();
} }

View File

@ -80,13 +80,76 @@ public interface TextRun {
* @param fontSize font size in points, if null the underlying fontsize will be unset * @param fontSize font size in points, if null the underlying fontsize will be unset
*/ */
void setFontSize(Double fontSize); void setFontSize(Double fontSize);
/**
* @return font family or null if not set
*/
String getFontFamily(); String getFontFamily();
/**
* 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.
*/
void setFontFamily(String typeface);
/**
* @return true, if text is bold
*/
boolean isBold(); boolean isBold();
/**
* Sets the bold state
*
* @param bold set to true for bold text, false for normal weight
*/
void setBold(boolean bold);
/**
* @return true, if text is italic
*/
boolean isItalic(); boolean isItalic();
/**
* Sets the italic state
*
* @param italic set to true for italic text, false for non-italics
*/
void setItalic(boolean italic);
/**
* @return true, if text is underlined
*/
boolean isUnderlined(); boolean isUnderlined();
/**
* Sets the underlined state
*
* @param underlined set to true for underlined text, false for no underlining
*/
void setUnderlined(boolean underlined);
/**
* @return true, if text is stroked
*/
boolean isStrikethrough(); boolean isStrikethrough();
/**
* Sets the strikethrough state
*
* @param stroked set to true for stroked text, false for no stroking
*/
void setStrikethrough(boolean stroked);
/**
* @return true, if text is sub scripted
*/
boolean isSubscript(); boolean isSubscript();
/**
* @return true, if text is super scripted
*/
boolean isSuperscript(); boolean isSuperscript();
/** /**

View File

@ -26,7 +26,7 @@ public interface TextShape<
/** /**
* Vertical Text Types * Vertical Text Types
*/ */
public enum TextDirection { enum TextDirection {
/** /**
* Horizontal text. This should be default. * Horizontal text. This should be default.
*/ */
@ -59,7 +59,7 @@ public interface TextShape<
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside * Auto-fitting is when text within a shape is scaled in order to contain all the text inside
* </p> * </p>
*/ */
public enum TextAutofit { enum TextAutofit {
/** /**
* Specifies that text within the text body should not be auto-fit to the bounding box. * 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 * Auto-fitting is when text within a text box is scaled in order to remain inside
@ -90,6 +90,46 @@ public interface TextShape<
SHAPE SHAPE
} }
/**
* This enum represents a compromise for the handling of
* HSLF run types (see org.apache.poi.hslf.record.TextHeaderAtom) and
* XSLF placeholders (see org.apache.poi.xslf.usermodel.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.
*
* This enum and the handling around it may change significantly in future releases
*/
enum TextPlaceholder {
/** Title placeholder shape text */
TITLE,
/** Body placeholder shape text */
BODY,
/** Center title placeholder shape text */
CENTER_TITLE,
/** Center body placeholder shape text */
CENTER_BODY,
/** Half-sized body placeholder shape text */
HALF_BODY,
/** Quarter-sized body placeholder shape text */
QUARTER_BODY,
/** Notes placeholder shape text */
NOTES,
/** Any other text */
OTHER
}
/**
* Sets (overwrites) the current text.
* Uses the properties of the first paragraph / textrun.
* Text paragraphs are split by \\r or \\n.
* New lines within text run are split by \\u000b
*
* @param text the text string used by this object.
*
* @return the last text run of the - potential split - text
*/
TextRun setText(String text);
/** /**
* @return the TextParagraphs for this text box * @return the TextParagraphs for this text box
*/ */
@ -100,6 +140,13 @@ public interface TextShape<
*/ */
Insets2D getInsets(); Insets2D getInsets();
/**
* Sets the shape margins
*
* @param insets the new shape margins
*/
void setInsets(Insets2D insets);
/** /**
* Compute the cumulative height occupied by the text * Compute the cumulative height occupied by the text
*/ */
@ -112,6 +159,14 @@ public interface TextShape<
*/ */
VerticalAlignment getVerticalAlignment(); VerticalAlignment getVerticalAlignment();
/**
* Sets the type of vertical alignment for the text.
*
* @param vAlign - the type of alignment.
* A {@code null} values unsets this property.
*/
void setVerticalAlignment(VerticalAlignment vAlign);
/** /**
* Returns if the text is centered. * Returns if the text is centered.
* If true and if the individual paragraph settings allow it, * If true and if the individual paragraph settings allow it,
@ -122,13 +177,36 @@ public interface TextShape<
*/ */
boolean isHorizontalCentered(); boolean isHorizontalCentered();
/**
* Sets if the paragraphs are horizontal centered
*
* @param isCentered true, if the paragraphs are horizontal centered
* A {@code null} values unsets this property.
*/
void setHorizontalCentered(Boolean isCentered);
/** /**
* @return whether to wrap words within the bounding rectangle * @return whether to wrap words within the bounding rectangle
*/ */
boolean getWordWrap(); boolean getWordWrap();
/**
* @param wrap whether to wrap words within the bounding rectangle
*/
void setWordWrap(boolean wrap);
/** /**
* @return vertical orientation of the text * @return vertical orientation of the text
*/ */
TextDirection getTextDirection(); TextDirection getTextDirection();
/**
* Sets the text placeholder
*/
void setTextPlaceholder(TextPlaceholder placeholder);
/**
* @return the text placeholder
*/
TextPlaceholder getTextPlaceholder();
} }

View File

@ -1,41 +0,0 @@
/*
* ====================================================================
* 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,
CONTENT,
CHART,
TABLE,
CLIP_ART,
DGM,
MEDIA,
SLIDE_IMAGE,
PICTURE
}

View File

@ -41,7 +41,6 @@ import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.Resources; import org.apache.poi.sl.usermodel.Resources;
import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.DocumentHelper;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -404,11 +403,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
return slide; return slide;
} }
/** @Override
* Returns the current page size
*
* @return the page size
*/
public Dimension getPageSize(){ public Dimension getPageSize(){
CTSlideSize sz = _presentation.getSldSz(); CTSlideSize sz = _presentation.getSldSz();
int cx = sz.getCx(); int cx = sz.getCx();
@ -416,11 +411,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy)); return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy));
} }
/** @Override
* Sets the page size to the given <code>Dimension</code> object.
*
* @param pgSize page size
*/
public void setPageSize(Dimension pgSize){ public void setPageSize(Dimension pgSize){
CTSlideSize sz = CTSlideSize.Factory.newInstance(); CTSlideSize sz = CTSlideSize.Factory.newInstance();
sz.setCx(Units.toEMU(pgSize.getWidth())); sz.setCx(Units.toEMU(pgSize.getWidth()));

View File

@ -25,7 +25,12 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
@ -72,13 +77,25 @@ public class XSLFAutoShape extends XSLFTextShape
return ct; return ct;
} }
protected static void initTextBody(CTTextBody txBody) {
CTTextBodyProperties bodypr = txBody.addNewBodyPr();
bodypr.setAnchor(STTextAnchoringType.T);
bodypr.setRtlCol(false);
CTTextParagraph p = txBody.addNewP();
p.addNewPPr().setAlgn(STTextAlignType.L);
CTTextCharacterProperties endPr = p.addNewEndParaRPr();
endPr.setLang("en-US");
endPr.setSz(1100);
p.addNewR().setT("");
txBody.addNewLstStyle();
}
protected CTTextBody getTextBody(boolean create){ protected CTTextBody getTextBody(boolean create){
CTShape shape = (CTShape)getXmlObject(); CTShape shape = (CTShape)getXmlObject();
CTTextBody txBody = shape.getTxBody(); CTTextBody txBody = shape.getTxBody();
if (txBody == null && create) { if (txBody == null && create) {
txBody = shape.addNewTxBody(); txBody = shape.addNewTxBody();
txBody.addNewBodyPr(); initTextBody(txBody);
txBody.addNewLstStyle();
} }
return txBody; return txBody;
} }

View File

@ -33,6 +33,7 @@ import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
import org.apache.poi.sl.usermodel.PlaceableShape; import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;

View File

@ -39,6 +39,7 @@ import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawPictureShape; import org.apache.poi.sl.draw.DrawPictureShape;
import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Sheet; import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;

View File

@ -88,15 +88,13 @@ public abstract class XSLFSimpleShape extends XSLFShape
super(shape,sheet); super(shape,sheet);
} }
/** @Override
*
* @param type
*/
public void setShapeType(ShapeType type) { public void setShapeType(ShapeType type) {
STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId); STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId);
getSpPr().getPrstGeom().setPrst(geom); getSpPr().getPrstGeom().setPrst(geom);
} }
@Override
public ShapeType getShapeType(){ public ShapeType getShapeType(){
STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst(); STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst();
return ShapeType.forId(geom.intValue(), true); return ShapeType.forId(geom.intValue(), true);
@ -362,6 +360,40 @@ public abstract class XSLFSimpleShape extends XSLFShape
return lineWidth; return lineWidth;
} }
/**
* @param compound set the line compound style
*/
public void setLineCompound(LineCompound compound) {
CTShapeProperties spPr = getSpPr();
if (compound == null) {
if (spPr.isSetLn() && spPr.getLn().isSetCmpd())
spPr.getLn().unsetCmpd();
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
STCompoundLine.Enum xCmpd;
switch (compound) {
default:
case SINGLE:
xCmpd = STCompoundLine.SNG;
break;
case DOUBLE:
xCmpd = STCompoundLine.DBL;
break;
case THICK_THIN:
xCmpd = STCompoundLine.THICK_THIN;
break;
case THIN_THICK:
xCmpd = STCompoundLine.THIN_THICK;
break;
case TRIPLE:
xCmpd = STCompoundLine.TRI;
break;
}
ln.setCmpd(xCmpd);
}
}
/** /**
* @return the line compound * @return the line compound
*/ */
@ -420,12 +452,9 @@ public abstract class XSLFSimpleShape extends XSLFShape
if (spPr.isSetLn() && spPr.getLn().isSetPrstDash()) if (spPr.isSetLn() && spPr.getLn().isSetPrstDash())
spPr.getLn().unsetPrstDash(); spPr.getLn().unsetPrstDash();
} else { } else {
CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
.newInstance(); CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash();
val.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId)); ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
.addNewLn();
ln.setPrstDash(val);
} }
} }
@ -513,13 +542,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
return cap; return cap;
} }
/** @Override
* 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) { public void setFillColor(Color color) {
CTShapeProperties spPr = getSpPr(); CTShapeProperties spPr = getSpPr();
if (color == null) { if (color == null) {
@ -545,10 +568,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
} }
} }
/** @Override
* @return solid fill color of null if not set or fill color
* is not solid (pattern or gradient)
*/
public Color getFillColor() { public Color getFillColor() {
PaintStyle ps = getFillPaint(); PaintStyle ps = getFillPaint();
if (ps instanceof SolidPaint) { if (ps instanceof SolidPaint) {
@ -874,4 +894,28 @@ public abstract class XSLFSimpleShape extends XSLFShape
}; };
} }
@Override
public void setStrokeStyle(Object... styles) {
if (styles.length == 0) {
// remove stroke
setLineColor(null);
return;
}
// TODO: handle PaintStyle
for (Object st : styles) {
if (st instanceof Number) {
setLineWidth(((Number)st).doubleValue());
} else if (st instanceof LineCap) {
setLineCap((LineCap)st);
} else if (st instanceof LineDash) {
setLineDash((LineDash)st);
} else if (st instanceof LineCompound) {
setLineCompound((LineCompound)st);
} else if (st instanceof Color) {
setLineColor((Color)st);
}
}
}
} }

View File

@ -25,9 +25,9 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Notes; import org.apache.poi.sl.usermodel.Notes;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.DocumentHelper;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;

View File

@ -22,8 +22,8 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.DocumentHelper;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;

View File

@ -25,8 +25,8 @@ import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.DocumentHelper;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;

View File

@ -80,15 +80,22 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this)); for(CTTableRow row : trArray) _rows.add(new XSLFTableRow(row, this));
} }
@Override
public XSLFTableCell getCell(int row, int col) {
return getRows().get(row).getCells().get(col);
}
@Internal @Internal
public CTTable getCTTable(){ public CTTable getCTTable(){
return _table; return _table;
} }
@Override
public int getNumberOfColumns() { public int getNumberOfColumns() {
return _table.getTblGrid().sizeOfGridColArray(); return _table.getTblGrid().sizeOfGridColArray();
} }
@Override
public int getNumberOfRows() { public int getNumberOfRows() {
return _table.sizeOfTrArray(); return _table.sizeOfTrArray();
} }
@ -98,10 +105,16 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
_table.getTblGrid().getGridColArray(idx).getW()); _table.getTblGrid().getGridColArray(idx).getW());
} }
@Override
public void setColumnWidth(int idx, double width) { public void setColumnWidth(int idx, double width) {
_table.getTblGrid().getGridColArray(idx).setW(Units.toEMU(width)); _table.getTblGrid().getGridColArray(idx).setW(Units.toEMU(width));
} }
@Override
public void setRowHeight(int row, double height) {
_table.getTrArray(row).setH(Units.toEMU(height));
}
public Iterator<XSLFTableRow> iterator(){ public Iterator<XSLFTableRow> iterator(){
return _rows.iterator(); return _rows.iterator();
} }

View File

@ -21,6 +21,12 @@ package org.apache.poi.xslf.usermodel;
import java.awt.Color; import java.awt.Color;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell; import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
@ -44,7 +50,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
* Represents a cell of a table in a .pptx presentation * Represents a cell of a table in a .pptx presentation
*/ */
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> { public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> {
static double defaultBorderWidth = 1.0;
private CTTableCellProperties _tcPr = null; private CTTableCellProperties _tcPr = null;
/*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){ /*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){
@ -57,8 +62,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
CTTextBody txBody = cell.getTxBody(); CTTextBody txBody = cell.getTxBody();
if (txBody == null && create) { if (txBody == null && create) {
txBody = cell.addNewTxBody(); txBody = cell.addNewTxBody();
txBody.addNewBodyPr(); XSLFAutoShape.initTextBody(txBody);
txBody.addNewLstStyle();
} }
return txBody; return txBody;
} }
@ -108,67 +112,174 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
pr.setMarB(Units.toEMU(margin)); pr.setMarB(Units.toEMU(margin));
} }
private CTLineProperties getCTLine(char bltr, boolean create) { private CTLineProperties getCTLine(BorderEdge edge, boolean create) {
if (edge == null) {
throw new IllegalArgumentException("BorderEdge needs to be specified.");
}
CTTableCellProperties pr = getCellProperties(create); CTTableCellProperties pr = getCellProperties(create);
if (pr == null) return null; if (pr == null) return null;
switch (bltr) { switch (edge) {
case 'b': case bottom:
return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null); return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null);
case 'l': case left:
return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null); return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null);
case 't': case top:
return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null); return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null);
case 'r': case right:
return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null); return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null);
default: default:
return null; return null;
} }
} }
private void setBorderWidth(char bltr, double width) { @Override
CTLineProperties ln = getCTLine(bltr, true); public void removeBorder(BorderEdge edge) {
CTTableCellProperties pr = getCellProperties(false);
if (pr == null) return;
switch (edge) {
case bottom:
if (pr.isSetLnB()) {
pr.unsetLnB();
}
break;
case left:
if (pr.isSetLnL()) {
pr.unsetLnL();
}
break;
case top:
if (pr.isSetLnT()) {
pr.unsetLnT();
}
break;
case right:
if (pr.isSetLnR()) {
pr.unsetLnB();
}
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public StrokeStyle getBorderStyle(final BorderEdge edge) {
final Double width = getBorderWidth(edge);
return (width == null) ? null : new StrokeStyle() {
public PaintStyle getPaint() {
return DrawPaint.createSolidPaint(getBorderColor(edge));
}
public LineCap getLineCap() {
return getBorderCap(edge);
}
public LineDash getLineDash() {
return getBorderDash(edge);
}
public LineCompound getLineCompound() {
return getBorderCompound(edge);
}
public double getLineWidth() {
return width;
}
};
}
@Override
public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
if (style == null) {
throw new IllegalArgumentException("StrokeStyle needs to be specified.");
}
LineCap cap = style.getLineCap();
if (cap != null) {
setBorderCap(edge, cap);
}
LineCompound compound = style.getLineCompound();
if (compound != null) {
setBorderCompound(edge, compound);
}
LineDash dash = style.getLineDash();
if (dash != null) {
setBorderDash(edge, dash);
}
double width = style.getLineWidth();
setBorderWidth(edge, width);
}
public Double getBorderWidth(BorderEdge edge) {
CTLineProperties ln = getCTLine(edge, false);
return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW());
}
@Override
public void setBorderWidth(BorderEdge edge, double width) {
CTLineProperties ln = getCTLine(edge, true);
ln.setW(Units.toEMU(width)); ln.setW(Units.toEMU(width));
} }
private double getBorderWidth(char bltr) { private CTLineProperties setBorderDefaults(BorderEdge edge) {
CTLineProperties ln = getCTLine(bltr, false); CTLineProperties ln = getCTLine(edge, true);
return (ln == null || !ln.isSetW()) ? defaultBorderWidth : Units.toPoints(ln.getW()); if (ln.isSetNoFill()) {
ln.unsetNoFill();
} }
private void setBorderColor(char bltr, Color color) { if(!ln.isSetPrstDash()) {
CTLineProperties ln = getCTLine(bltr, true); ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
}
if(color == null){ if (!ln.isSetCmpd()) {
ln.addNewNoFill();
if(ln.isSetSolidFill()) ln.unsetSolidFill();
} else {
if(ln.isSetNoFill()) ln.unsetNoFill();
if(!ln.isSetPrstDash()) ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
ln.setCmpd(STCompoundLine.SNG); ln.setCmpd(STCompoundLine.SNG);
}
if (!ln.isSetAlgn()) {
ln.setAlgn(STPenAlignment.CTR); ln.setAlgn(STPenAlignment.CTR);
}
if (!ln.isSetCap()) {
ln.setCap(STLineCap.FLAT); ln.setCap(STLineCap.FLAT);
}
if (!ln.isSetRound()) {
ln.addNewRound(); ln.addNewRound();
}
if (!ln.isSetHeadEnd()) {
CTLineEndProperties hd = ln.addNewHeadEnd(); CTLineEndProperties hd = ln.addNewHeadEnd();
hd.setType(STLineEndType.NONE); hd.setType(STLineEndType.NONE);
hd.setW(STLineEndWidth.MED); hd.setW(STLineEndWidth.MED);
hd.setLen(STLineEndLength.MED); hd.setLen(STLineEndLength.MED);
}
if (!ln.isSetTailEnd()) {
CTLineEndProperties tl = ln.addNewTailEnd(); CTLineEndProperties tl = ln.addNewTailEnd();
tl.setType(STLineEndType.NONE); tl.setType(STLineEndType.NONE);
tl.setW(STLineEndWidth.MED); tl.setW(STLineEndWidth.MED);
tl.setLen(STLineEndLength.MED); tl.setLen(STLineEndLength.MED);
}
return ln;
}
@Override
public void setBorderColor(BorderEdge edge, Color color) {
if (color == null) {
throw new IllegalArgumentException("Colors need to be specified.");
}
CTLineProperties ln = setBorderDefaults(edge);
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
ln.addNewSolidFill().setSrgbClr(rgb); ln.addNewSolidFill().setSrgbClr(rgb);
} }
}
private Color getBorderColor(char bltr) { public Color getBorderColor(BorderEdge edge) {
CTLineProperties ln = getCTLine(bltr,false); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null; if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
CTSolidColorFillProperties fill = ln.getSolidFill(); CTSolidColorFillProperties fill = ln.getSolidFill();
@ -180,69 +291,63 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
} }
public void setBorderLeft(double width) { public LineCompound getBorderCompound(BorderEdge edge) {
setBorderWidth('l', width); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) {
return null;
} }
public double getBorderLeft() { return LineCompound.fromOoxmlId(ln.getCmpd().intValue());
return getBorderWidth('l');
} }
public void setBorderLeftColor(Color color) { @Override
setBorderColor('l', color); public void setBorderCompound(BorderEdge edge, LineCompound compound) {
if (compound == null) {
throw new IllegalArgumentException("LineCompound need to be specified.");
} }
public Color getBorderLeftColor() { CTLineProperties ln = setBorderDefaults(edge);
return getBorderColor('l'); ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId));
} }
public void setBorderRight(double width) { public LineDash getBorderDash(BorderEdge edge) {
setBorderWidth('r', width); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) {
return null;
} }
public double getBorderRight() { return LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue());
return getBorderWidth('r');
} }
public void setBorderRightColor(Color color) { @Override
setBorderColor('r', color); public void setBorderDash(BorderEdge edge, LineDash dash) {
if (dash == null) {
throw new IllegalArgumentException("LineDash need to be specified.");
} }
public Color getBorderRightColor() { CTLineProperties ln = setBorderDefaults(edge);
return getBorderColor('r'); ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
} }
public void setBorderTop(double width) { public LineCap getBorderCap(BorderEdge edge) {
setBorderWidth('t', width); CTLineProperties ln = getCTLine(edge, false);
if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) {
return null;
} }
public double getBorderTop() { return LineCap.fromOoxmlId(ln.getCap().intValue());
return getBorderWidth('t');
} }
public void setBorderTopColor(Color color) { public void setBorderCap(BorderEdge edge, LineCap cap) {
setBorderColor('t', color); if (cap == null) {
throw new IllegalArgumentException("LineCap need to be specified.");
} }
public Color getBorderTopColor() { CTLineProperties ln = setBorderDefaults(edge);
return getBorderColor('t'); ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
} }
public void setBorderBottom(double width) {
setBorderWidth('b', width);
}
public double getBorderBottom() {
return getBorderWidth('b');
}
public void setBorderBottomColor(Color color) {
setBorderColor('b', color);
}
public Color getBorderBottomColor(){
return getBorderColor('b');
}
/** /**
* Specifies a solid color fill. The shape is filled entirely with the specified color. * Specifies a solid color fill. The shape is filled entirely with the specified color.

View File

@ -54,8 +54,7 @@ public class XSLFTextBox extends XSLFAutoShape
prst.setPrst(STShapeType.RECT); prst.setPrst(STShapeType.RECT);
prst.addNewAvLst(); prst.addNewAvLst();
CTTextBody txBody = ct.addNewTxBody(); CTTextBody txBody = ct.addNewTxBody();
txBody.addNewBodyPr(); XSLFAutoShape.initTextBody(txBody);
txBody.addNewLstStyle();
return ct; return ct;
} }

View File

@ -32,7 +32,26 @@ import org.apache.poi.util.Units;
import org.apache.poi.xslf.model.ParagraphPropertyFetcher; import org.apache.poi.xslf.model.ParagraphPropertyFetcher;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.*; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
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.CTTextTabStop;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextFontAlignType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
@ -100,6 +119,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
} }
@Override
public List<XSLFTextRun> getTextRuns(){ public List<XSLFTextRun> getTextRuns(){
return _runs; return _runs;
} }

View File

@ -206,12 +206,7 @@ public class XSLFTextRun implements TextRun {
} }
} }
/** @Override
* 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){ public void setFontFamily(String typeface){
setFontFamily(typeface, (byte)-1, (byte)-1, false); setFontFamily(typeface, (byte)-1, (byte)-1, false);
} }
@ -236,9 +231,7 @@ public class XSLFTextRun implements TextRun {
} }
} }
/** @Override
* @return font family or null if not set
*/
public String getFontFamily(){ public String getFontFamily(){
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
@ -281,18 +274,12 @@ public class XSLFTextRun implements TextRun {
return visitor.getValue() == null ? 0 : visitor.getValue(); return visitor.getValue() == null ? 0 : visitor.getValue();
} }
/** @Override
* 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) { public void setStrikethrough(boolean strike) {
getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE); getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
} }
/** @Override
* @return whether a run of text will be formatted as strikethrough text. Default is false.
*/
public boolean isStrikethrough() { public boolean isStrikethrough() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -307,9 +294,7 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue(); return fetcher.getValue() == null ? false : fetcher.getValue();
} }
/** @Override
* @return whether a run of text will be formatted as a superscript text. Default is false.
*/
public boolean isSuperscript() { public boolean isSuperscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -357,9 +342,7 @@ public class XSLFTextRun implements TextRun {
setBaselineOffset(flag ? -25.0 : 0.); setBaselineOffset(flag ? -25.0 : 0.);
} }
/** @Override
* @return whether a run of text will be formatted as a superscript text. Default is false.
*/
public boolean isSubscript() { public boolean isSubscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -392,18 +375,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? TextCap.NONE : fetcher.getValue(); return fetcher.getValue() == null ? TextCap.NONE : fetcher.getValue();
} }
/** @Override
* 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){ public void setBold(boolean bold){
getRPr().setB(bold); getRPr().setB(bold);
} }
/** @Override
* @return whether this run of text is formatted as bold text
*/
public boolean isBold(){ public boolean isBold(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -418,16 +395,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue(); return fetcher.getValue() == null ? false : fetcher.getValue();
} }
/** @Override
* @param italic whether this run of text is formatted as italic text
*/
public void setItalic(boolean italic){ public void setItalic(boolean italic){
getRPr().setI(italic); getRPr().setI(italic);
} }
/** @Override
* @return whether this run of text is formatted as italic text
*/
public boolean isItalic(){ public boolean isItalic(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -442,16 +415,12 @@ public class XSLFTextRun implements TextRun {
return fetcher.getValue() == null ? false : fetcher.getValue(); return fetcher.getValue() == null ? false : fetcher.getValue();
} }
/** @Override
* @param underline whether this run of text is formatted as underlined text public void setUnderlined(boolean underline) {
*/
public void setUnderline(boolean underline) {
getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE); getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
} }
/** @Override
* @return whether this run of text is formatted as underlined text
*/
public boolean isUnderlined(){ public boolean isUnderlined(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
@ -501,6 +470,7 @@ public class XSLFTextRun implements TextRun {
CTPlaceholder ph = shape.getCTPlaceholder(); CTPlaceholder ph = shape.getCTPlaceholder();
if (ph == null){ if (ph == null){
// if it is a plain text box then take defaults from presentation.xml // if it is a plain text box then take defaults from presentation.xml
@SuppressWarnings("resource")
XMLSlideShow ppt = sheet.getSlideShow(); XMLSlideShow ppt = sheet.getSlideShow();
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel()); CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
if (themeProps != null) { if (themeProps != null) {
@ -543,7 +513,7 @@ public class XSLFTextRun implements TextRun {
if(italic != isItalic()) setItalic(italic); if(italic != isItalic()) setItalic(italic);
boolean underline = r.isUnderlined(); boolean underline = r.isUnderlined();
if(underline != isUnderlined()) setUnderline(underline); if(underline != isUnderlined()) setUnderlined(underline);
boolean strike = r.isStrikethrough(); boolean strike = r.isStrikethrough();
if(strike != isStrikethrough()) setStrikethrough(strike); if(strike != isStrikethrough()) setStrikethrough(strike);

View File

@ -37,8 +37,10 @@ import org.apache.poi.xslf.model.TextBodyPropertyFetcher;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
@ -91,10 +93,52 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
txBody.setPArray(null); // remove any existing paragraphs txBody.setPArray(null); // remove any existing paragraphs
} }
public void setText(String text){ @Override
clearText(); public XSLFTextRun setText(String text) {
// copy properties from first paragraph / textrun
CTTextParagraphProperties pPr = null;
CTTextCharacterProperties rPr = null;
if (!_paragraphs.isEmpty()) {
XSLFTextParagraph p0 = _paragraphs.get(0);
pPr = p0.getXmlObject().getPPr();
if (!p0.getTextRuns().isEmpty()) {
XSLFTextRun r0 = p0.getTextRuns().get(0);
rPr = r0.getXmlObject().getRPr();
}
}
addNewTextParagraph().addNewTextRun().setText(text); // can't call clearText otherwise we receive a XmlValueDisconnectedException
_paragraphs.clear();
CTTextBody txBody = getTextBody(true);
int cntPs = txBody.sizeOfPArray();
// split text by paragraph and new line char
XSLFTextRun r = null;
for (String paraText : text.split("\\r\\n?|\\n")) {
XSLFTextParagraph para = addNewTextParagraph();
if (pPr != null) {
para.getXmlObject().setPPr(pPr);
}
boolean first = true;
for (String runText : paraText.split("[\u000b]")) {
if (!first) {
para.addLineBreak();
}
r = para.addNewTextRun();
r.setText(runText);
if (rPr != null) {
r.getXmlObject().setRPr(rPr);
}
first = false;
}
}
// simply setting a new pArray leads to XmlValueDisconnectedException
for (int i = cntPs-1; i >= 0; i--) {
txBody.removeP(i);
}
return r;
} }
@Override @Override
@ -115,13 +159,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return paragraph; return paragraph;
} }
@Override
/**
* Sets the type of vertical alignment for the text.
*
* @param anchor - the type of alignment.
* A {@code null} values unsets this property.
*/
public void setVerticalAlignment(VerticalAlignment anchor){ public void setVerticalAlignment(VerticalAlignment anchor){
CTTextBodyProperties bodyPr = getTextBodyPr(); CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) { if (bodyPr != null) {
@ -133,11 +171,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
} }
} }
/** @Override
* Returns the type of vertical alignment for the text.
*
* @return the type of vertical alignment
*/
public VerticalAlignment getVerticalAlignment(){ public VerticalAlignment getVerticalAlignment(){
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){ PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
public boolean fetch(CTTextBodyProperties props){ public boolean fetch(CTTextBodyProperties props){
@ -153,14 +187,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue(); return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue();
} }
/** @Override
* Sets if the paragraphs are horizontal centered
*
* @param isCentered true, if the paragraphs are horizontal centered
* A {@code null} values unsets this property.
*
* @see TextShape#isHorizontalCentered()
*/
public void setHorizontalCentered(Boolean isCentered){ public void setHorizontalCentered(Boolean isCentered){
CTTextBodyProperties bodyPr = getTextBodyPr(); CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) { if (bodyPr != null) {
@ -369,10 +396,15 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return insets; return insets;
} }
@Override
public void setInsets(Insets2D insets) {
setTopInset(insets.top);
setLeftInset(insets.left);
setBottomInset(insets.bottom);
setRightInset(insets.right);
}
/** @Override
* @return whether to wrap words within the bounding rectangle
*/
public boolean getWordWrap(){ public boolean getWordWrap(){
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){ PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
public boolean fetch(CTTextBodyProperties props){ public boolean fetch(CTTextBodyProperties props){
@ -387,10 +419,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return fetcher.getValue() == null ? true : fetcher.getValue(); return fetcher.getValue() == null ? true : fetcher.getValue();
} }
/** @Override
*
* @param wrap whether to wrap words within the bounding rectangle
*/
public void setWordWrap(boolean wrap){ public void setWordWrap(boolean wrap){
CTTextBodyProperties bodyPr = getTextBodyPr(); CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) { if (bodyPr != null) {
@ -532,4 +561,45 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
tgtP.copy(srcP); tgtP.copy(srcP);
} }
} }
@Override
public void setTextPlaceholder(TextPlaceholder placeholder) {
switch (placeholder) {
default:
case NOTES:
case HALF_BODY:
case QUARTER_BODY:
case BODY:
setPlaceholder(Placeholder.BODY);
break;
case TITLE:
setPlaceholder(Placeholder.TITLE);
break;
case CENTER_BODY:
setPlaceholder(Placeholder.BODY);
setHorizontalCentered(true);
break;
case CENTER_TITLE:
setPlaceholder(Placeholder.CENTERED_TITLE);
break;
case OTHER:
setPlaceholder(Placeholder.CONTENT);
break;
}
}
@Override
public TextPlaceholder getTextPlaceholder() {
Placeholder ph = getTextType();
if (ph == null) return TextPlaceholder.BODY;
switch (ph) {
case BODY: return TextPlaceholder.BODY;
case TITLE: return TextPlaceholder.TITLE;
case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE;
default:
case CONTENT: return TextPlaceholder.OTHER;
}
}
} }

View File

@ -268,7 +268,7 @@ public class TestXSLFAutoShape {
assertFalse(r.isUnderlined()); assertFalse(r.isUnderlined());
assertFalse(r.getXmlObject().getRPr().isSetU()); assertFalse(r.getXmlObject().getRPr().isSetU());
r.setUnderline(true); r.setUnderlined(true);
assertTrue(r.isUnderlined()); assertTrue(r.isUnderlined());
assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU()); assertEquals(STTextUnderlineType.SNG, r.getXmlObject().getRPr().getU());

View File

@ -20,13 +20,16 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import java.io.IOException;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test; import org.junit.Test;
public class TestXSLFNotes { public class TestXSLFNotes {
@Test @Test
public void createNewNote() { public void createNewNote() throws IOException {
XMLSlideShow ppt = new XMLSlideShow(); XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide1 = ppt.createSlide(); XSLFSlide slide1 = ppt.createSlide();
@ -48,10 +51,12 @@ public class TestXSLFNotes {
} }
assertNotNull(note); assertNotNull(note);
assertEquals("New Note", note); assertEquals("New Note", note);
ppt.close();
} }
@Test @Test
public void addNote() { public void addNote() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx");
@ -69,10 +74,12 @@ public class TestXSLFNotes {
} }
assertNotNull(note); assertNotNull(note);
assertEquals("New Note", note); assertEquals("New Note", note);
ppt.close();
} }
@Test @Test
public void replaceNotes() { public void replaceNotes() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("sample.pptx");
@ -93,5 +100,7 @@ public class TestXSLFNotes {
assertNotNull(note); assertNotNull(note);
assertEquals("New Note", note); assertEquals("New Note", note);
} }
ppt.close();
} }
} }

View File

@ -28,6 +28,7 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.poi.sl.draw.geom.TestPresetGeometries; import org.apache.poi.sl.draw.geom.TestPresetGeometries;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
@ -168,7 +169,7 @@ public class TestXSLFSimpleShape {
} }
@Test @Test
public void testDefaultProperties() { public void testDefaultProperties() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
XSLFSlide slide6 = ppt.getSlides().get(5); XSLFSlide slide6 = ppt.getSlides().get(5);
@ -234,10 +235,12 @@ public class TestXSLFSimpleShape {
assertEquals(50000, ref5.getLumModArray(0).getVal()); assertEquals(50000, ref5.getLumModArray(0).getVal());
assertEquals("accent1", ref5.getVal().toString()); assertEquals("accent1", ref5.getVal().toString());
assertEquals(new Color(79, 129, 189), s5.getFillColor()); assertEquals(new Color(79, 129, 189), s5.getFillColor());
ppt.close();
} }
@Test @Test
public void testAnchor(){ public void testAnchor() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
List<XSLFSlide> slide = ppt.getSlides(); List<XSLFSlide> slide = ppt.getSlides();
@ -267,6 +270,7 @@ public class TestXSLFSimpleShape {
assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm()); assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm());
assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor()); assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor());
ppt.close();
} }
@SuppressWarnings({ "deprecation", "unused" }) @SuppressWarnings({ "deprecation", "unused" })

View File

@ -16,23 +16,29 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.Test; import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
import java.awt.Color;
import java.util.List;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class TestXSLFTable { public class TestXSLFTable {
@Test @Test
public void testRead(){ public void testRead() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
XSLFSlide slide = ppt.getSlides().get(3); XSLFSlide slide = ppt.getSlides().get(3);
@ -69,10 +75,12 @@ public class TestXSLFTable {
assertEquals("A1", cells1.get(0).getText()); assertEquals("A1", cells1.get(0).getText());
assertEquals("B1", cells1.get(1).getText()); assertEquals("B1", cells1.get(1).getText());
assertEquals("C1", cells1.get(2).getText()); assertEquals("C1", cells1.get(2).getText());
ppt.close();
} }
@Test @Test
public void testCreate() { public void testCreate() throws IOException {
XMLSlideShow ppt = new XMLSlideShow(); XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide(); XSLFSlide slide = ppt.createSlide();
@ -121,38 +129,21 @@ public class TestXSLFTable {
cell1.addNewTextParagraph().addNewTextRun().setText("Apache"); cell1.addNewTextParagraph().addNewTextRun().setText("Apache");
assertEquals("Apache", cell1.getText()); assertEquals("Apache", cell1.getText());
assertEquals(1.0, cell1.getBorderBottom(), 0); for (BorderEdge edge : BorderEdge.values()) {
cell1.setBorderBottom(2.0); assertNull(cell1.getBorderWidth(edge));
assertEquals(2.0, cell1.getBorderBottom(), 0); cell1.setBorderWidth(edge, 2.0);
assertNull(cell1.getBorderBottomColor()); assertEquals(2.0, cell1.getBorderWidth(edge), 0);
cell1.setBorderBottomColor(Color.yellow); assertNull(cell1.getBorderColor(edge));
assertEquals(Color.yellow, cell1.getBorderBottomColor()); cell1.setBorderColor(edge, Color.yellow);
assertEquals(Color.yellow, cell1.getBorderColor(edge));
assertEquals(1.0, cell1.getBorderTop(), 0); }
cell1.setBorderTop(2.0);
assertEquals(2.0, cell1.getBorderTop(), 0);
assertNull(cell1.getBorderTopColor());
cell1.setBorderTopColor(Color.yellow);
assertEquals(Color.yellow, cell1.getBorderTopColor());
assertEquals(1.0, cell1.getBorderLeft(), 0);
cell1.setBorderLeft(2.0);
assertEquals(2.0, cell1.getBorderLeft(), 0);
assertNull(cell1.getBorderLeftColor());
cell1.setBorderLeftColor(Color.yellow);
assertEquals(Color.yellow, cell1.getBorderLeftColor());
assertEquals(1.0, cell1.getBorderRight(), 0);
cell1.setBorderRight(2.0);
assertEquals(2.0, cell1.getBorderRight(), 0);
assertNull(cell1.getBorderRightColor());
cell1.setBorderRightColor(Color.yellow);
assertEquals(Color.yellow, cell1.getBorderRightColor());
assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment()); assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment());
cell1.setVerticalAlignment(VerticalAlignment.MIDDLE); cell1.setVerticalAlignment(VerticalAlignment.MIDDLE);
assertEquals(VerticalAlignment.MIDDLE, cell1.getVerticalAlignment()); assertEquals(VerticalAlignment.MIDDLE, cell1.getVerticalAlignment());
cell1.setVerticalAlignment(null); cell1.setVerticalAlignment(null);
assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment()); assertEquals(VerticalAlignment.TOP, cell1.getVerticalAlignment());
ppt.close();
} }
} }

View File

@ -19,6 +19,9 @@ package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import java.io.IOException;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.junit.Test; import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
@ -28,7 +31,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties
public class TestXSLFTextBox { public class TestXSLFTextBox {
@Test @Test
public void testPlaceholder() { public void testPlaceholder() throws IOException {
XMLSlideShow ppt = new XMLSlideShow(); XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide(); XSLFSlide slide = ppt.createSlide();
@ -39,13 +42,15 @@ public class TestXSLFTextBox {
shape.setPlaceholder(null); shape.setPlaceholder(null);
assertNull(shape.getTextType()); assertNull(shape.getTextType());
shape.setText("Apache POI"); shape.setText("Apache POI");
ppt.close();
} }
/** /**
* text box inherits default text proeprties from presentation.xml * text box inherits default text proeprties from presentation.xml
*/ */
@Test @Test
public void testDefaultTextStyle() { public void testDefaultTextStyle() throws IOException {
XMLSlideShow ppt = new XMLSlideShow(); XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide(); XSLFSlide slide = ppt.createSlide();
@ -79,5 +84,7 @@ public class TestXSLFTextBox {
pPr.unsetSz(); // Should never be pPr.unsetSz(); // Should never be
assertNull(r.getFontSize()); assertNull(r.getFontSize());
ppt.close();
} }
} }

View File

@ -28,6 +28,7 @@ import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.XSLFTestDataSamples; import org.apache.poi.xslf.XSLFTestDataSamples;
@ -45,7 +46,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
public class TestXSLFTextShape { public class TestXSLFTextShape {
@Test @Test
public void testLayouts(){ public void testLayouts() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx"); XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx");
List<XSLFSlide> slide = ppt.getSlides(); List<XSLFSlide> slide = ppt.getSlides();
@ -57,6 +58,8 @@ public class TestXSLFTextShape {
verifySlide7(slide.get(6)); verifySlide7(slide.get(6));
verifySlide8(slide.get(7)); verifySlide8(slide.get(7));
verifySlide10(slide.get(9)); verifySlide10(slide.get(9));
ppt.close();
} }
void verifySlide1(XSLFSlide slide){ void verifySlide1(XSLFSlide slide){

View File

@ -297,7 +297,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
txt.setTopInset(0); txt.setTopInset(0);
txt.setLeftInset(0); txt.setLeftInset(0);
txt.setRightInset(0); txt.setRightInset(0);
txt.setWordWrap(HSLFTextBox.WrapNone); txt.setWordWrap(false);
txt.setHorizontalCentered(false); txt.setHorizontalCentered(false);
txt.setVerticalAlignment(VerticalAlignment.MIDDLE); txt.setVerticalAlignment(VerticalAlignment.MIDDLE);
@ -1826,7 +1826,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable {
float[] dash = bs.getDashArray(); float[] dash = bs.getDashArray();
if (dash != null) { if (dash != null) {
//TODO: implement more dashing styles //TODO: implement more dashing styles
shape.setLineDashing(StrokeStyle.LineDash.DASH); shape.setLineDash(StrokeStyle.LineDash.DASH);
} }
} }
} }

View File

@ -1,96 +0,0 @@
/* ====================================================================
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.hslf.model;
import org.apache.poi.ddf.*;
import org.apache.poi.hslf.record.OEPlaceholderAtom;
import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.hslf.usermodel.HSLFTextBox;
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.sl.usermodel.ShapeContainer;
import java.io.ByteArrayOutputStream;
/**
* Represents a Placeholder in PowerPoint.
*
* @author Yegor Kozlov
*/
public final class Placeholder extends HSLFTextBox {
protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
super(escherRecord, parent);
}
public Placeholder(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
super(parent);
}
public Placeholder(){
super();
}
/**
* Create a new Placeholder and initialize internal structures
*
* @return the created <code>EscherContainerRecord</code> which holds shape data
*/
protected EscherContainerRecord createSpContainer(boolean isChild){
_escherContainer = super.createSpContainer(isChild);
EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER);
EscherClientDataRecord cldata = new EscherClientDataRecord();
cldata.setOptions((short)15);
AbstractEscherOptRecord opt = getEscherOptRecord();
//Placeholders can't be grouped
setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
//OEPlaceholderAtom tells powerpoint that this shape is a placeholder
//
OEPlaceholderAtom oep = new OEPlaceholderAtom();
/**
* Extarct from MSDN:
*
* There is a special case when the placeholder does not have a position in the layout.
* This occurs when the user has moved the placeholder from its original position.
* In this case the placeholder ID is -1.
*/
oep.setPlacementId(-1);
oep.setPlaceholderId(OEPlaceholderAtom.Body);
//convert hslf into ddf record
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
oep.writeOut(out);
} catch(Exception e){
throw new HSLFException(e);
}
cldata.setRemainingData(out.toByteArray());
//append placeholder container before EscherTextboxRecord
_escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
return _escherContainer;
}
}

View File

@ -67,7 +67,7 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape<HSLFShape,
protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){ protected void setDefaultTextProperties(HSLFTextParagraph _txtrun){
setVerticalAlignment(VerticalAlignment.MIDDLE); setVerticalAlignment(VerticalAlignment.MIDDLE);
setHorizontalCentered(true); setHorizontalCentered(true);
setWordWrap(HSLFTextBox.WrapNone); setWordWrap(false);
} }
/** /**

View File

@ -43,7 +43,6 @@ import org.apache.poi.util.Units;
*/ */
public class HSLFGroupShape extends HSLFShape public class HSLFGroupShape extends HSLFShape
implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
/** /**
* Create a new ShapeGroup. This constructor is used when a new shape is created. * Create a new ShapeGroup. This constructor is used when a new shape is created.
* *
@ -73,34 +72,16 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
super(escherRecord, parent); super(escherRecord, parent);
} }
/** @Override
* Sets the anchor (the bounding box rectangle) of this shape. public void setAnchor(Rectangle anchor) {
* All coordinates should be expressed in Master units (576 dpi).
*
* @param anchor new anchor
*/
public void setAnchor(java.awt.Rectangle anchor){
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
//hack. internal variable EscherClientAnchorRecord.shortRecord can be boolean isInitialized = !(clientAnchor.getDx1() == 0 && clientAnchor.getRow1() == 0);
//initialized only in fillFields(). We need to set shortRecord=false;
byte[] header = new byte[16];
LittleEndian.putUShort(header, 0, 0);
LittleEndian.putUShort(header, 2, 0);
LittleEndian.putInt(header, 4, 8);
clientAnchor.fillFields(header, 0, null);
clientAnchor.setFlag((short)Units.pointsToMaster(anchor.y)); if (isInitialized) {
clientAnchor.setCol1((short)Units.pointsToMaster(anchor.x)); moveAndScale(anchor);
clientAnchor.setDx1((short)Units.pointsToMaster(anchor.width + anchor.x)); } else {
clientAnchor.setRow1((short)Units.pointsToMaster(anchor.height + anchor.y)); setExteriorAnchor(anchor);
}
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
spgr.setRectX1(Units.pointsToMaster(anchor.x));
spgr.setRectY1(Units.pointsToMaster(anchor.y));
spgr.setRectX2(Units.pointsToMaster(anchor.x + anchor.width));
spgr.setRectY2(Units.pointsToMaster(anchor.y + anchor.height));
} }
@Override @Override
@ -116,7 +97,6 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
spgr.setRectY1(y1); spgr.setRectY1(y1);
spgr.setRectX2(x2); spgr.setRectX2(x2);
spgr.setRectY2(y2); spgr.setRectY2(y2);
} }
@Override @Override
@ -129,6 +109,27 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
return new Rectangle(x1,y1,x2-x1,y2-y1); return new Rectangle(x1,y1,x2-x1,y2-y1);
} }
protected void setExteriorAnchor(Rectangle anchor) {
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
//hack. internal variable EscherClientAnchorRecord.shortRecord can be
//initialized only in fillFields(). We need to set shortRecord=false;
byte[] header = new byte[16];
LittleEndian.putUShort(header, 0, 0);
LittleEndian.putUShort(header, 2, 0);
LittleEndian.putInt(header, 4, 8);
clientAnchor.fillFields(header, 0, null);
// All coordinates need to be converted to Master units (576 dpi)
clientAnchor.setFlag((short)Units.pointsToMaster(anchor.y));
clientAnchor.setCol1((short)Units.pointsToMaster(anchor.x));
clientAnchor.setDx1((short)Units.pointsToMaster(anchor.width + anchor.x));
clientAnchor.setRow1((short)Units.pointsToMaster(anchor.height + anchor.y));
// TODO: does this make sense?
setInteriorAnchor(anchor);
}
/** /**
* Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes * Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
*/ */
@ -174,23 +175,22 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
} }
/** /**
* Moves this <code>ShapeGroup</code> to the specified location. * Moves and scales this <code>ShapeGroup</code> to the specified anchor.
* <p>
* @param x the x coordinate of the top left corner of the shape in new location
* @param y the y coordinate of the top left corner of the shape in new location
*/ */
public void moveTo(int x, int y){ protected void moveAndScale(Rectangle anchorDest){
Rectangle anchor = getAnchor(); Rectangle anchorSrc = getAnchor();
int dx = x - anchor.x; double scaleX = (anchorSrc.width == 0) ? 0 : anchorDest.width / (double)anchorSrc.width;
int dy = y - anchor.y; double scaleY = (anchorSrc.height == 0) ? 0 : anchorDest.height / (double)anchorSrc.height;
anchor.translate(dx, dy);
setAnchor(anchor);
setExteriorAnchor(anchorDest);
for (HSLFShape shape : getShapes()) { for (HSLFShape shape : getShapes()) {
Rectangle chanchor = shape.getAnchor(); Rectangle chanchor = shape.getAnchor();
chanchor.translate(dx, dy); int x = (int)Math.rint(anchorDest.x+(chanchor.x-anchorSrc.x)*scaleX);
shape.setAnchor(chanchor); int y = (int)Math.rint(anchorDest.y+(chanchor.y-anchorSrc.y)*scaleY);
int width = (int)Math.rint(chanchor.width*scaleX);
int height = (int)Math.rint(chanchor.height*scaleY);
shape.setAnchor(new Rectangle(x, y, width, height));
} }
} }
@ -262,9 +262,6 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* @return the shapes contained in this group container
*/
@Override @Override
public List<HSLFShape> getShapes() { public List<HSLFShape> getShapes() {
// Out escher container record should contain several // Out escher container record should contain several

View File

@ -0,0 +1,55 @@
/* ====================================================================
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.hslf.usermodel;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.sl.usermodel.SimpleShape.Placeholder;
import org.apache.poi.sl.usermodel.ShapeContainer;
/**
* Represents a Placeholder in PowerPoint.
*
* @author Yegor Kozlov
*/
public final class HSLFPlaceholder extends HSLFTextBox {
protected HSLFPlaceholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
super(escherRecord, parent);
}
public HSLFPlaceholder(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
super(parent);
}
public HSLFPlaceholder(){
super();
}
/**
* Create a new Placeholder and initialize internal structures
*
* @return the created <code>EscherContainerRecord</code> which holds shape data
*/
protected EscherContainerRecord createSpContainer(boolean isChild){
_escherContainer = super.createSpContainer(isChild);
setPlaceholder(Placeholder.BODY);
return _escherContainer;
}
}

View File

@ -116,19 +116,11 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
return getShapeType().nativeName; return getShapeType().nativeName;
} }
/**
* @return type of the shape.
* @see org.apache.poi.hslf.record.RecordTypes
*/
public ShapeType getShapeType(){ public ShapeType getShapeType(){
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
return ShapeType.forId(spRecord.getShapeType(), false); return ShapeType.forId(spRecord.getShapeType(), false);
} }
/**
* @param type type of the shape.
* @see org.apache.poi.hslf.record.RecordTypes
*/
public void setShapeType(ShapeType type){ public void setShapeType(ShapeType type){
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
spRecord.setShapeType( (short) type.nativeId ); spRecord.setShapeType( (short) type.nativeId );
@ -209,7 +201,9 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> {
* @param x the x coordinate of the top left corner of the shape * @param x the x coordinate of the top left corner of the shape
* @param y the y coordinate of the top left corner of the shape * @param y the y coordinate of the top left corner of the shape
*/ */
public void moveTo(float x, float y){ public final void moveTo(float x, float y) {
// This convenience method should be implemented via setAnchor in subclasses
// see HSLFGroupShape.setAnchor() for a reference
Rectangle anchor = getAnchor(); Rectangle anchor = getAnchor();
anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight()); anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
setAnchor(anchor); setAnchor(anchor);

View File

@ -56,7 +56,7 @@ public final class HSLFShapeFactory {
EscherPropertyFactory f = new EscherPropertyFactory(); EscherPropertyFactory f = new EscherPropertyFactory();
List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() ); List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
for (EscherProperty ep : props) { for (EscherProperty ep : props) {
if (ep.getPropertyNumber() == 0x39F if (ep.getPropertyNumber() == EscherProperties.GROUPSHAPE__TABLEPROPERTIES
&& ep instanceof EscherSimpleProperty && ep instanceof EscherSimpleProperty
&& ((EscherSimpleProperty)ep).getPropertyValue() == 1) { && ((EscherSimpleProperty)ep).getPropertyValue() == 1) {
isTable = true; isTable = true;
@ -65,9 +65,13 @@ public final class HSLFShapeFactory {
} }
} }
HSLFGroupShape group = (isTable) HSLFGroupShape group;
? new HSLFTable(spContainer, parent) if (isTable) {
: new HSLFGroupShape(spContainer, parent); group = new HSLFTable(spContainer, parent);
} else {
group = new HSLFGroupShape(spContainer, parent);
}
return group; return group;
} }
@ -82,65 +86,73 @@ public final class HSLFShapeFactory {
shape = new HSLFTextBox(spContainer, parent); shape = new HSLFTextBox(spContainer, parent);
break; break;
case HOST_CONTROL: case HOST_CONTROL:
case FRAME: { case FRAME:
InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID); shape = createFrame(spContainer, parent);
OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
if(info != null && info.getInteractiveInfoAtom() != null){
switch(info.getInteractiveInfoAtom().getAction()){
case InteractiveInfoAtom.ACTION_OLE:
shape = new OLEShape(spContainer, parent);
break; break;
case InteractiveInfoAtom.ACTION_MEDIA:
shape = new MovieShape(spContainer, parent);
break;
default:
break;
}
} else if (oes != null){
shape = new OLEShape(spContainer, parent);
}
if(shape == null) shape = new HSLFPictureShape(spContainer, parent);
break;
}
case LINE: case LINE:
shape = new HSLFLine(spContainer, parent); shape = new HSLFLine(spContainer, parent);
break; break;
case NOT_PRIMITIVE: { case NOT_PRIMITIVE:
AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID); shape = createNonPrimitive(spContainer, parent);
EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
if(prop != null)
shape = new HSLFFreeformShape(spContainer, parent);
else {
logger.log(POILogger.INFO, "Creating AutoShape for a NotPrimitive shape");
shape = new HSLFAutoShape(spContainer, parent);
}
break; break;
}
default: default:
EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID);
if (parent instanceof HSLFTable && etr != null) {
shape = new HSLFTableCell(spContainer, (HSLFTable)parent);
} else {
shape = new HSLFAutoShape(spContainer, parent); shape = new HSLFAutoShape(spContainer, parent);
}
break; break;
} }
return shape; return shape;
}
private static HSLFShape createFrame(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
if(info != null && info.getInteractiveInfoAtom() != null){
switch(info.getInteractiveInfoAtom().getAction()){
case InteractiveInfoAtom.ACTION_OLE:
return new OLEShape(spContainer, parent);
case InteractiveInfoAtom.ACTION_MEDIA:
return new MovieShape(spContainer, parent);
default:
break;
}
}
OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
if (oes != null){
return new OLEShape(spContainer, parent);
}
return new HSLFPictureShape(spContainer, parent);
}
private static HSLFShape createNonPrimitive(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
if(prop != null) {
return new HSLFFreeformShape(spContainer, parent);
}
logger.log(POILogger.INFO, "Creating AutoShape for a NotPrimitive shape");
return new HSLFAutoShape(spContainer, parent);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) { protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
Record oep = null;
for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) { for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
EscherRecord obj = it.next(); EscherRecord obj = it.next();
if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) { if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
byte[] data = obj.serialize(); byte[] data = obj.serialize();
Record[] records = Record.findChildRecords(data, 8, data.length - 8); for (Record r : Record.findChildRecords(data, 8, data.length - 8)) {
for (int j = 0; j < records.length; j++) { if (r.getRecordType() == recordType) {
if (records[j].getRecordType() == recordType) { return (T)r;
return (T)records[j];
} }
} }
} }
} }
return (T)oep; return null;
} }
} }

View File

@ -458,7 +458,7 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
throw new IllegalArgumentException("numRows and numCols must be greater than 0"); throw new IllegalArgumentException("numRows and numCols must be greater than 0");
} }
HSLFTable s = new HSLFTable(numRows,numCols); HSLFTable s = new HSLFTable(numRows,numCols);
s.setAnchor(new Rectangle(0, 0, 100, 100)); // anchor is set in constructor based on numRows/numCols
addShape(s); addShape(s);
return s; return s;
} }

View File

@ -27,6 +27,7 @@ import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.draw.geom.*; import org.apache.poi.sl.draw.geom.*;
import org.apache.poi.sl.usermodel.*; import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -146,12 +147,33 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
return clr == null ? Color.black : clr; return clr == null ? Color.black : clr;
} }
/**
* Gets line cap.
*
* @return cap of the line.
*/
public LineCap getLineCap(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE);
return (prop == null) ? LineCap.FLAT : LineCap.fromNativeId(prop.getPropertyValue());
}
/**
* Sets line cap.
*
* @param pen new style of the line.
*/
public void setLineCap(LineCap pen){
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId);
}
/** /**
* Gets line dashing. * Gets line dashing.
* *
* @return dashing of the line. * @return dashing of the line.
*/ */
public LineDash getLineDashing(){ public LineDash getLineDash(){
AbstractEscherOptRecord opt = getEscherOptRecord(); AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue()); return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue());
@ -162,7 +184,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
* *
* @param pen new style of the line. * @param pen new style of the line.
*/ */
public void setLineDashing(LineDash pen){ public void setLineDash(LineDash pen){
AbstractEscherOptRecord opt = getEscherOptRecord(); AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId); setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId);
} }
@ -204,7 +226,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
} }
public LineDash getLineDash() { public LineDash getLineDash() {
return HSLFSimpleShape.this.getLineDashing(); return HSLFSimpleShape.this.getLineDash();
} }
public LineCompound getLineCompound() { public LineCompound getLineCompound() {
@ -218,18 +240,12 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
}; };
} }
/** @Override
* The color used to fill this shape.
*/
public Color getFillColor() { public Color getFillColor() {
return getFill().getForegroundColor(); return getFill().getForegroundColor();
} }
/** @Override
* The color used to fill this shape.
*
* @param color the background color
*/
public void setFillColor(Color color) { public void setFillColor(Color color) {
getFill().setForegroundColor(color); getFill().setForegroundColor(color);
} }
@ -475,4 +491,123 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
} }
}; };
} }
protected void setPlaceholder(Placeholder placeholder) {
EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
spRecord.setFlags(flags);
EscherClientDataRecord cldata = _escherContainer.getChildById(EscherClientDataRecord.RECORD_ID);
if (cldata == null) {
cldata = new EscherClientDataRecord();
// append placeholder container before EscherTextboxRecord
_escherContainer.addChildBefore(cldata, EscherTextboxRecord.RECORD_ID);
}
cldata.setOptions((short)15);
AbstractEscherOptRecord opt = getEscherOptRecord();
// Placeholders can't be grouped
setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144);
// OEPlaceholderAtom tells powerpoint that this shape is a placeholder
OEPlaceholderAtom oep = new OEPlaceholderAtom();
/**
* Extarct from MSDN:
*
* There is a special case when the placeholder does not have a position in the layout.
* This occurs when the user has moved the placeholder from its original position.
* In this case the placeholder ID is -1.
*/
oep.setPlacementId(-1);
boolean isMaster = (getSheet() instanceof HSLFSlideMaster);
boolean isNotes = (getSheet() instanceof HSLFNotes);
byte phId;
switch (placeholder) {
case TITLE:
phId = (isMaster) ? OEPlaceholderAtom.MasterTitle : OEPlaceholderAtom.Title;
break;
case BODY:
phId = (isMaster) ? OEPlaceholderAtom.MasterBody :
((isNotes) ? OEPlaceholderAtom.NotesBody : OEPlaceholderAtom.Body);
break;
case CENTERED_TITLE:
phId = (isMaster) ? OEPlaceholderAtom.MasterCenteredTitle : OEPlaceholderAtom.CenteredTitle;
break;
case SUBTITLE:
phId = (isMaster) ? OEPlaceholderAtom.MasterSubTitle : OEPlaceholderAtom.Subtitle;
break;
case DATETIME:
phId = OEPlaceholderAtom.MasterDate;
break;
case SLIDE_NUMBER:
phId = OEPlaceholderAtom.MasterSlideNumber;
break;
case FOOTER:
phId = OEPlaceholderAtom.MasterFooter;
break;
case HEADER:
phId = OEPlaceholderAtom.MasterHeader;
break;
case DGM:
case CHART:
phId = OEPlaceholderAtom.Graph;
break;
case TABLE:
phId = OEPlaceholderAtom.Table;
break;
case PICTURE:
case CLIP_ART:
phId = OEPlaceholderAtom.ClipArt;
break;
case MEDIA:
phId = OEPlaceholderAtom.MediaClip;
break;
case SLIDE_IMAGE:
phId = (isMaster) ? OEPlaceholderAtom.MasterNotesSlideImage : OEPlaceholderAtom.NotesSlideImage;
break;
default:
case CONTENT:
phId = OEPlaceholderAtom.Object;
break;
}
oep.setPlaceholderId(phId);
//convert hslf into ddf record
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
oep.writeOut(out);
} catch(Exception e){
throw new HSLFException(e);
}
cldata.setRemainingData(out.toByteArray());
}
@Override
public void setStrokeStyle(Object... styles) {
if (styles.length == 0) {
// remove stroke
setLineColor(null);
return;
}
// TODO: handle PaintStyle
for (Object st : styles) {
if (st instanceof Number) {
setLineWidth(((Number)st).doubleValue());
} else if (st instanceof LineCap) {
setLineCap((LineCap)st);
} else if (st instanceof LineDash) {
setLineDash((LineDash)st);
} else if (st instanceof LineCompound) {
setLineCompound((LineCompound)st);
} else if (st instanceof Color) {
setLineColor((Color)st);
}
}
}
} }

View File

@ -27,7 +27,6 @@ import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherSpRecord; import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hslf.model.Comment; import org.apache.poi.hslf.model.Comment;
import org.apache.poi.hslf.model.HeadersFooters; import org.apache.poi.hslf.model.HeadersFooters;
import org.apache.poi.hslf.model.Placeholder;
import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.Comment2000; import org.apache.poi.hslf.record.Comment2000;
import org.apache.poi.hslf.record.EscherTextboxWrapper; import org.apache.poi.hslf.record.EscherTextboxWrapper;
@ -196,7 +195,7 @@ public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTe
* @return <code>TextBox</code> object that represents the slide's title. * @return <code>TextBox</code> object that represents the slide's title.
*/ */
public HSLFTextBox addTitle() { public HSLFTextBox addTitle() {
Placeholder pl = new Placeholder(); HSLFPlaceholder pl = new HSLFPlaceholder();
pl.setShapeType(ShapeType.RECT); pl.setShapeType(ShapeType.RECT);
pl.setRunType(TextHeaderAtom.TITLE_TYPE); pl.setRunType(TextHeaderAtom.TITLE_TYPE);
pl.setText("Click to edit title"); pl.setText("Click to edit title");

View File

@ -531,9 +531,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
return HSLFSoundData.find(_documentRecord); return HSLFSoundData.find(_documentRecord);
} }
/** @Override
* Return the current page size
*/
public Dimension getPageSize() { public Dimension getPageSize() {
DocumentAtom docatom = _documentRecord.getDocumentAtom(); DocumentAtom docatom = _documentRecord.getDocumentAtom();
int pgx = (int)Units.masterToPoints((int)docatom.getSlideSizeX()); int pgx = (int)Units.masterToPoints((int)docatom.getSlideSizeX());
@ -541,12 +539,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
return new Dimension(pgx, pgy); return new Dimension(pgx, pgy);
} }
/** @Override
* Change the current page size
*
* @param pgsize
* page size (in points)
*/
public void setPageSize(Dimension pgsize) { public void setPageSize(Dimension pgsize) {
DocumentAtom docatom = _documentRecord.getDocumentAtom(); DocumentAtom docatom = _documentRecord.getDocumentAtom();
docatom.setSlideSizeX(Units.pointsToMaster(pgsize.width)); docatom.setSlideSizeX(Units.pointsToMaster(pgsize.width));

View File

@ -21,17 +21,16 @@ import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.apache.poi.ddf.AbstractEscherOptRecord; import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherArrayProperty; import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord; import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties; import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSimpleProperty; import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.TableShape; import org.apache.poi.sl.usermodel.TableShape;
@ -46,11 +45,6 @@ import org.apache.poi.util.Units;
public final class HSLFTable extends HSLFGroupShape public final class HSLFTable extends HSLFGroupShape
implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> { implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
protected static final int BORDER_TOP = 1;
protected static final int BORDER_RIGHT = 2;
protected static final int BORDER_BOTTOM = 3;
protected static final int BORDER_LEFT = 4;
protected static final int BORDERS_ALL = 5; protected static final int BORDERS_ALL = 5;
protected static final int BORDERS_OUTSIDE = 6; protected static final int BORDERS_OUTSIDE = 6;
protected static final int BORDERS_INSIDE = 7; protected static final int BORDERS_INSIDE = 7;
@ -65,7 +59,7 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
* @param numRows the number of rows * @param numRows the number of rows
* @param numCols the number of columns * @param numCols the number of columns
*/ */
public HSLFTable(int numRows, int numCols) { protected HSLFTable(int numRows, int numCols) {
this(numRows, numCols, null); this(numRows, numCols, null);
} }
@ -76,7 +70,7 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
* @param numCols the number of columns * @param numCols the number of columns
* @param parent the parent shape, or null if table is added to sheet * @param parent the parent shape, or null if table is added to sheet
*/ */
public HSLFTable(int numRows, int numCols, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) { protected HSLFTable(int numRows, int numCols, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
super(parent); super(parent);
if(numRows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1"); if(numRows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1");
@ -96,13 +90,13 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
} }
tblWidth = x; tblWidth = x;
tblHeight = y; tblHeight = y;
setAnchor(new Rectangle(0, 0, tblWidth, tblHeight)); setExteriorAnchor(new Rectangle(0, 0, tblWidth, tblHeight));
EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0); EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0);
AbstractEscherOptRecord opt = new EscherOptRecord(); AbstractEscherOptRecord opt = new EscherOptRecord();
opt.setRecordId((short)RecordTypes.EscherUserDefined); opt.setRecordId((short)RecordTypes.EscherUserDefined);
opt.addEscherProperty(new EscherSimpleProperty((short)0x39F, 1)); opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GROUPSHAPE__TABLEPROPERTIES, 1));
EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | 0x3A0), false, null); EscherArrayProperty p = new EscherArrayProperty((short)(0x4000 | EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES), false, null);
p.setSizeOfElements(0x0004); p.setSizeOfElements(0x0004);
p.setNumberOfElementsInArray(numRows); p.setNumberOfElementsInArray(numRows);
p.setNumberOfElementsInMemory(numRows); p.setNumberOfElementsInMemory(numRows);
@ -111,12 +105,12 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
} }
/** /**
* Create a Table object and initilize it from the supplied Record container. * Create a Table object and initialize it from the supplied Record container.
* *
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape * @param parent the parent of the shape
*/ */
public HSLFTable(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) { protected HSLFTable(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
super(escherRecord, parent); super(escherRecord, parent);
} }
@ -131,9 +125,12 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
return cells[row][col]; return cells[row][col];
} }
@Override
public int getNumberOfColumns() { public int getNumberOfColumns() {
return cells[0].length; return cells[0].length;
} }
@Override
public int getNumberOfRows() { public int getNumberOfRows() {
return cells.length; return cells.length;
} }
@ -141,52 +138,26 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
protected void afterInsert(HSLFSheet sh){ protected void afterInsert(HSLFSheet sh){
super.afterInsert(sh); super.afterInsert(sh);
EscherContainerRecord spCont = (EscherContainerRecord) getSpContainer().getChild(0); Set<HSLFLine> lineSet = new HashSet<HSLFLine>();
List<EscherRecord> lst = spCont.getChildRecords(); for (HSLFTableCell row[] : cells) {
AbstractEscherOptRecord opt = (AbstractEscherOptRecord)lst.get(lst.size()-2); for (HSLFTableCell c : row) {
EscherArrayProperty p = opt.lookup(0x3A0);
for (int i = 0; i < cells.length; i++) {
HSLFTableCell cell = cells[i][0];
int rowHeight = Units.pointsToMaster(cell.getAnchor().height);
byte[] val = new byte[4];
LittleEndian.putInt(val, 0, rowHeight);
p.setElement(i, val);
for (int j = 0; j < cells[i].length; j++) {
HSLFTableCell c = cells[i][j];
addShape(c); addShape(c);
for (HSLFLine bt : new HSLFLine[]{ c.borderTop, c.borderRight, c.borderBottom, c.borderLeft }) {
HSLFLine bt = c.getBorderTop(); if (bt != null) {
if(bt != null) addShape(bt); lineSet.add(bt);
}
HSLFLine br = c.getBorderRight(); }
if(br != null) addShape(br);
HSLFLine bb = c.getBorderBottom();
if(bb != null) addShape(bb);
HSLFLine bl = c.getBorderLeft();
if(bl != null) addShape(bl);
} }
} }
for (HSLFLine l : lineSet) {
addShape(l);
} }
protected void initTable(){ updateRowHeightsProperty();
List<HSLFShape> shapeList = getShapes();
Iterator<HSLFShape> shapeIter = shapeList.iterator();
while (shapeIter.hasNext()) {
HSLFShape shape = shapeIter.next();
if (shape instanceof HSLFAutoShape) {
HSLFAutoShape autoShape = (HSLFAutoShape)shape;
EscherTextboxRecord etr = autoShape.getEscherChild(EscherTextboxRecord.RECORD_ID);
if (etr != null) continue;
}
shapeIter.remove();
} }
Collections.sort(shapeList, new Comparator<HSLFShape>(){ private static class TableCellComparator implements Comparator<HSLFShape> {
public int compare( HSLFShape o1, HSLFShape o2 ) { public int compare( HSLFShape o1, HSLFShape o2 ) {
Rectangle anchor1 = o1.getAnchor(); Rectangle anchor1 = o1.getAnchor();
Rectangle anchor2 = o2.getAnchor(); Rectangle anchor2 = o2.getAnchor();
@ -196,33 +167,140 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
if (delta == 0) delta = (anchor2.width*anchor2.height)-(anchor1.width*anchor1.height); if (delta == 0) delta = (anchor2.width*anchor2.height)-(anchor1.width*anchor1.height);
return delta; return delta;
} }
}); }
int y0 = (shapeList.isEmpty()) ? -1 : shapeList.get(0).getAnchor().y - 1; private void cellListToArray() {
int maxrowlen = 0; List<HSLFTableCell> htc = new ArrayList<HSLFTableCell>();
List<List<HSLFShape>> lst = new ArrayList<List<HSLFShape>>(); for (HSLFShape h : getShapes()) {
List<HSLFShape> row = null; if (h instanceof HSLFTableCell) {
for (HSLFShape sh : shapeList) { htc.add((HSLFTableCell)h);
if(sh instanceof HSLFTextShape){ }
}
if (htc.isEmpty()) {
throw new IllegalStateException("HSLFTable without HSLFTableCells");
}
Collections.sort(htc, new TableCellComparator());
List<HSLFTableCell[]> lst = new ArrayList<HSLFTableCell[]>();
List<HSLFTableCell> row = new ArrayList<HSLFTableCell>();
int y0 = htc.get(0).getAnchor().y;
for (HSLFTableCell sh : htc) {
Rectangle anchor = sh.getAnchor(); Rectangle anchor = sh.getAnchor();
if(anchor.y != y0){ boolean isNextRow = (anchor.y > y0);
if (isNextRow) {
y0 = anchor.y; y0 = anchor.y;
row = new ArrayList<HSLFShape>(); lst.add(row.toArray(new HSLFTableCell[row.size()]));
lst.add(row); row.clear();
} }
row.add(sh); row.add(sh);
maxrowlen = Math.max(maxrowlen, row.size()); }
lst.add(row.toArray(new HSLFTableCell[row.size()]));
cells = lst.toArray(new HSLFTableCell[lst.size()][]);
}
static class LineRect {
final HSLFLine l;
final double lx1, lx2, ly1, ly2;
LineRect(HSLFLine l) {
this.l = l;
Rectangle r = l.getAnchor();
lx1 = r.getMinX();
lx2 = r.getMaxX();
ly1 = r.getMinY();
ly2 = r.getMaxY();
}
int leftFit(double x1, double x2, double y1, double y2) {
return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x1-lx2)+Math.abs(y2-ly2));
}
int topFit(double x1, double x2, double y1, double y2) {
return (int)(Math.abs(x1-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y1-ly2));
}
int rightFit(double x1, double x2, double y1, double y2) {
return (int)(Math.abs(x2-lx1)+Math.abs(y1-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2));
}
int bottomFit(double x1, double x2, double y1, double y2) {
return (int)(Math.abs(x1-lx1)+Math.abs(y2-ly1)+Math.abs(x2-lx2)+Math.abs(y2-ly2));
} }
} }
cells = new HSLFTableCell[lst.size()][maxrowlen];
for (int i = 0; i < lst.size(); i++) { private void fitLinesToCells() {
row = lst.get(i); List<LineRect> lines = new ArrayList<LineRect>();
for (int j = 0; j < row.size(); j++) { for (HSLFShape h : getShapes()) {
HSLFTextShape tx = (HSLFTextShape)row.get(j); if (h instanceof HSLFLine) {
cells[i][j] = new HSLFTableCell(tx.getSpContainer(), getParent()); lines.add(new LineRect((HSLFLine)h));
cells[i][j].setSheet(tx.getSheet());
} }
} }
final int threshold = 5;
// TODO: this only works for non-rotated tables
for (HSLFTableCell[] tca : cells) {
for (HSLFTableCell tc : tca) {
final Rectangle cellAnchor = tc.getAnchor();
/**
* x1/y1 --------+
* | |
* +---------x2/y2
*/
final double x1 = cellAnchor.getMinX();
final double x2 = cellAnchor.getMaxX();
final double y1 = cellAnchor.getMinY();
final double y2 = cellAnchor.getMaxY();
LineRect lline = null, tline = null, rline = null, bline = null;
int lfit = Integer.MAX_VALUE, tfit = Integer.MAX_VALUE, rfit = Integer.MAX_VALUE, bfit = Integer.MAX_VALUE;
for (LineRect lr : lines) {
// calculate border fit
int lfitx = lr.leftFit(x1, x2, y1, y2);
if (lfitx < lfit) {
lfit = lfitx;
lline = lr;
}
int tfitx = lr.topFit(x1, x2, y1, y2);
if (tfitx < tfit) {
tfit = tfitx;
tline = lr;
}
int rfitx = lr.rightFit(x1, x2, y1, y2);
if (rfitx < rfit) {
rfit = rfitx;
rline = lr;
}
int bfitx = lr.bottomFit(x1, x2, y1, y2);
if (bfitx < bfit) {
bfit = bfitx;
bline = lr;
}
}
if (lfit < threshold) {
tc.borderLeft = lline.l;
}
if (tfit < threshold) {
tc.borderTop = tline.l;
}
if (rfit < threshold) {
tc.borderRight = rline.l;
}
if (bfit < threshold) {
tc.borderBottom = bline.l;
}
}
}
}
protected void initTable(){
cellListToArray();
fitLinesToCells();
} }
/** /**
@ -232,151 +310,102 @@ implements HSLFShapeContainer, TableShape<HSLFShape,HSLFTextParagraph> {
*/ */
public void setSheet(HSLFSheet sheet){ public void setSheet(HSLFSheet sheet){
super.setSheet(sheet); super.setSheet(sheet);
if(cells == null) initTable(); if (cells == null) {
initTable();
} else {
for (HSLFTableCell cols[] : cells) {
for (HSLFTableCell col : cols) {
col.setSheet(sheet);
}
}
}
} }
/** @Override
* Sets the row height. public void setRowHeight(int row, double height) {
* int pxHeight = Units.pointsToPixel(height);
* @param row the row index (0-based)
* @param height the height to set (in pixels)
*/
public void setRowHeight(int row, int height){
int currentHeight = cells[row][0].getAnchor().height; int currentHeight = cells[row][0].getAnchor().height;
int dy = height - currentHeight; int dy = pxHeight - currentHeight;
for (int i = row; i < cells.length; i++) { for (int i = row; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) { for (int j = 0; j < cells[i].length; j++) {
Rectangle anchor = cells[i][j].getAnchor(); Rectangle anchor = cells[i][j].getAnchor();
if(i == row) anchor.height = height; if(i == row) {
else anchor.y += dy; anchor.height = pxHeight;
} else {
anchor.y += dy;
}
cells[i][j].setAnchor(anchor); cells[i][j].setAnchor(anchor);
} }
} }
Rectangle tblanchor = getAnchor(); Rectangle tblanchor = getAnchor();
tblanchor.height += dy; tblanchor.height += dy;
setAnchor(tblanchor); setExteriorAnchor(tblanchor);
} }
/** @Override
* Sets the column width. public void setColumnWidth(int col, final double width){
* if (col < 0 || col >= cells[0].length) {
* @param col the column index (0-based) throw new IllegalArgumentException("Column index '"+col+"' is not within range [0-"+(cells[0].length-1)+"]");
* @param width the width to set (in pixels) }
*/ double currentWidth = cells[0][col].getAnchor().getWidth();
public void setColumnWidth(int col, int width){ double dx = width - currentWidth;
int currentWidth = cells[0][col].getAnchor().width; for (HSLFTableCell cols[] : cells) {
int dx = width - currentWidth; Rectangle anchor = cols[col].getAnchor();
for (int i = 0; i < cells.length; i++) { anchor.width = (int)Math.rint(width);
Rectangle anchor = cells[i][col].getAnchor(); cols[col].setAnchor(anchor);
anchor.width = width;
cells[i][col].setAnchor(anchor);
if(col < cells[i].length - 1) for (int j = col+1; j < cells[i].length; j++) { if (col < cols.length - 1) {
anchor = cells[i][j].getAnchor(); for (int j = col+1; j < cols.length; j++) {
anchor = cols[j].getAnchor();
anchor.x += dx; anchor.x += dx;
cells[i][j].setAnchor(anchor); cols[j].setAnchor(anchor);
}
} }
} }
Rectangle tblanchor = getAnchor(); Rectangle tblanchor = getAnchor();
tblanchor.width += dx; tblanchor.width += dx;
setAnchor(tblanchor); setExteriorAnchor(tblanchor);
} }
/** protected HSLFTableCell getRelativeCell(HSLFTableCell origin, int row, int col) {
* Format the table and apply the specified Line to all cell boundaries, int thisRow = 0, thisCol = 0;
* both outside and inside boolean found = false;
* outer: for (HSLFTableCell[] tca : cells) {
* @param line the border line thisCol = 0;
*/ for (HSLFTableCell tc : tca) {
public void setAllBorders(HSLFLine line){ if (tc == origin) {
for (int i = 0; i < cells.length; i++) { found = true;
for (int j = 0; j < cells[i].length; j++) { break outer;
HSLFTableCell cell = cells[i][j];
cell.setBorderTop(cloneBorder(line));
cell.setBorderLeft(cloneBorder(line));
if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line));
} }
thisCol++;
} }
thisRow++;
} }
/** int otherRow = thisRow + row;
* Format the outside border using the specified Line object int otherCol = thisCol + col;
* return (found
* @param line the border line && 0 <= otherRow && otherRow < cells.length
*/ && 0 <= otherCol && otherCol < cells[otherRow].length)
public void setOutsideBorders(HSLFLine line){ ? cells[otherRow][otherCol] : null;
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
HSLFTableCell cell = cells[i][j];
if(j == 0) cell.setBorderLeft(cloneBorder(line));
if(j == cells[i].length - 1) cell.setBorderRight(cloneBorder(line));
else {
cell.setBorderLeft(null);
cell.setBorderLeft(null);
} }
if(i == 0) cell.setBorderTop(cloneBorder(line)); @Override
else if(i == cells.length - 1) cell.setBorderBottom(cloneBorder(line)); protected void moveAndScale(Rectangle anchorDest){
else { super.moveAndScale(anchorDest);
cell.setBorderTop(null); updateRowHeightsProperty();
cell.setBorderBottom(null);
}
}
}
} }
/** private void updateRowHeightsProperty() {
* Format the inside border using the specified Line object
*
* @param line the border line
*/
public void setInsideBorders(HSLFLine line){
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
HSLFTableCell cell = cells[i][j];
if(j != cells[i].length - 1)
cell.setBorderRight(cloneBorder(line));
else {
cell.setBorderLeft(null);
cell.setBorderLeft(null);
}
if(i != cells.length - 1) cell.setBorderBottom(cloneBorder(line));
else {
cell.setBorderTop(null);
cell.setBorderBottom(null);
}
}
}
}
private HSLFLine cloneBorder(HSLFLine line){
HSLFLine border = createBorder();
border.setLineWidth(line.getLineWidth());
border.setLineDashing(line.getLineDashing());
border.setLineColor(line.getLineColor());
border.setLineCompound(line.getLineCompound());
return border;
}
/**
* Create a border to format this table
*
* @return the created border
*/
public HSLFLine createBorder(){
HSLFLine line = new HSLFLine(this);
AbstractEscherOptRecord opt = getEscherOptRecord(); AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1); EscherArrayProperty p = opt.lookup(EscherProperties.GROUPSHAPE__TABLEROWPROPERTIES);
setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1); byte[] val = new byte[4];
setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000); for (int rowIdx = 0; rowIdx < cells.length; rowIdx++) {
setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000); int rowHeight = Units.pointsToMaster(cells[rowIdx][0].getAnchor().height);
LittleEndian.putInt(val, 0, rowHeight);
return line; p.setElement(rowIdx, val);
}
} }
} }

View File

@ -17,13 +17,18 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import java.awt.Color;
import java.awt.Rectangle; import java.awt.Rectangle;
import org.apache.poi.ddf.AbstractEscherOptRecord; import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties; import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.sl.usermodel.ShapeContainer; import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell; import org.apache.poi.sl.usermodel.TableCell;
/** /**
@ -35,10 +40,10 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
protected static final int DEFAULT_WIDTH = 100; protected static final int DEFAULT_WIDTH = 100;
protected static final int DEFAULT_HEIGHT = 40; protected static final int DEFAULT_HEIGHT = 40;
private HSLFLine borderLeft; /* package */ HSLFLine borderLeft;
private HSLFLine borderRight; /* package */ HSLFLine borderRight;
private HSLFLine borderTop; /* package */ HSLFLine borderTop;
private HSLFLine borderBottom; /* package */ HSLFLine borderBottom;
/** /**
* Create a TableCell object and initialize it from the supplied Record container. * Create a TableCell object and initialize it from the supplied Record container.
@ -46,7 +51,7 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
* @param escherRecord EscherSpContainer which holds information about this shape * @param escherRecord EscherSpContainer which holds information about this shape
* @param parent the parent of the shape * @param parent the parent of the shape
*/ */
protected HSLFTableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){ protected HSLFTableCell(EscherContainerRecord escherRecord, HSLFTable parent){
super(escherRecord, parent); super(escherRecord, parent);
} }
@ -56,7 +61,7 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
* @param parent the parent of this Shape. For example, if this text box is a cell * @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table. * in a table then the parent is Table.
*/ */
public HSLFTableCell(ShapeContainer<HSLFShape,HSLFTextParagraph> parent){ public HSLFTableCell(HSLFTable parent){
super(parent); super(parent);
setShapeType(ShapeType.RECT); setShapeType(ShapeType.RECT);
@ -76,82 +81,320 @@ public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFSh
return _escherContainer; return _escherContainer;
} }
protected void anchorBorder(int type, HSLFLine line){ private void anchorBorder(BorderEdge edge, final HSLFLine line) {
if (line == null) {
return;
}
Rectangle cellAnchor = getAnchor(); Rectangle cellAnchor = getAnchor();
Rectangle lineAnchor = new Rectangle(); Rectangle lineAnchor = new Rectangle();
switch(type){ switch(edge){
case HSLFTable.BORDER_TOP: case top:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = cellAnchor.width; lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0; lineAnchor.height = 0;
break; break;
case HSLFTable.BORDER_RIGHT: case right:
lineAnchor.x = cellAnchor.x + cellAnchor.width; lineAnchor.x = cellAnchor.x + cellAnchor.width;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0; lineAnchor.width = 0;
lineAnchor.height = cellAnchor.height; lineAnchor.height = cellAnchor.height;
break; break;
case HSLFTable.BORDER_BOTTOM: case bottom:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y + cellAnchor.height; lineAnchor.y = cellAnchor.y + cellAnchor.height;
lineAnchor.width = cellAnchor.width; lineAnchor.width = cellAnchor.width;
lineAnchor.height = 0; lineAnchor.height = 0;
break; break;
case HSLFTable.BORDER_LEFT: case left:
lineAnchor.x = cellAnchor.x; lineAnchor.x = cellAnchor.x;
lineAnchor.y = cellAnchor.y; lineAnchor.y = cellAnchor.y;
lineAnchor.width = 0; lineAnchor.width = 0;
lineAnchor.height = cellAnchor.height; lineAnchor.height = cellAnchor.height;
break; break;
default: default:
throw new IllegalArgumentException("Unknown border type: " + type); throw new IllegalArgumentException();
} }
line.setAnchor(lineAnchor); line.setAnchor(lineAnchor);
} }
public HSLFLine getBorderLeft() {
return borderLeft;
}
public void setBorderLeft(HSLFLine line) {
if(line != null) anchorBorder(HSLFTable.BORDER_LEFT, line);
this.borderLeft = line;
}
public HSLFLine getBorderRight() {
return borderRight;
}
public void setBorderRight(HSLFLine line) {
if(line != null) anchorBorder(HSLFTable.BORDER_RIGHT, line);
this.borderRight = line;
}
public HSLFLine getBorderTop() {
return borderTop;
}
public void setBorderTop(HSLFLine line) {
if(line != null) anchorBorder(HSLFTable.BORDER_TOP, line);
this.borderTop = line;
}
public HSLFLine getBorderBottom() {
return borderBottom;
}
public void setBorderBottom(HSLFLine line) {
if(line != null) anchorBorder(HSLFTable.BORDER_BOTTOM, line);
this.borderBottom = line;
}
public void setAnchor(Rectangle anchor){ public void setAnchor(Rectangle anchor){
super.setAnchor(anchor); super.setAnchor(anchor);
if(borderTop != null) anchorBorder(HSLFTable.BORDER_TOP, borderTop); anchorBorder(BorderEdge.top, borderTop);
if(borderRight != null) anchorBorder(HSLFTable.BORDER_RIGHT, borderRight); anchorBorder(BorderEdge.right, borderRight);
if(borderBottom != null) anchorBorder(HSLFTable.BORDER_BOTTOM, borderBottom); anchorBorder(BorderEdge.bottom, borderBottom);
if(borderLeft != null) anchorBorder(HSLFTable.BORDER_LEFT, borderLeft); anchorBorder(BorderEdge.left, borderLeft);
}
@Override
public StrokeStyle getBorderStyle(final BorderEdge edge) {
final Double width = getBorderWidth(edge);
return (width == null) ? null : new StrokeStyle() {
public PaintStyle getPaint() {
return DrawPaint.createSolidPaint(getBorderColor(edge));
}
public LineCap getLineCap() {
return null;
}
public LineDash getLineDash() {
return getBorderDash(edge);
}
public LineCompound getLineCompound() {
return getBorderCompound(edge);
}
public double getLineWidth() {
return width;
}
};
}
@Override
public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
if (style == null) {
throw new IllegalArgumentException("StrokeStyle needs to be specified.");
}
// setting the line cap is not implemented, as the border lines aren't connected
LineCompound compound = style.getLineCompound();
if (compound != null) {
setBorderCompound(edge, compound);
}
LineDash dash = style.getLineDash();
if (dash != null) {
setBorderDash(edge, dash);
}
double width = style.getLineWidth();
setBorderWidth(edge, width);
}
public Double getBorderWidth(BorderEdge edge) {
HSLFLine l;
switch (edge) {
case bottom: l = borderBottom; break;
case top: l = borderTop; break;
case right: l = borderRight; break;
case left: l = borderLeft; break;
default: throw new IllegalArgumentException();
}
return (l == null) ? null : l.getLineWidth();
}
@Override
public void setBorderWidth(BorderEdge edge, double width) {
HSLFLine l = addLine(edge);
l.setLineWidth(width);
}
public Color getBorderColor(BorderEdge edge) {
HSLFLine l;
switch (edge) {
case bottom: l = borderBottom; break;
case top: l = borderTop; break;
case right: l = borderRight; break;
case left: l = borderLeft; break;
default: throw new IllegalArgumentException();
}
return (l == null) ? null : l.getLineColor();
}
@Override
public void setBorderColor(BorderEdge edge, Color color) {
if (edge == null || color == null) {
throw new IllegalArgumentException("BorderEdge and/or Color need to be specified.");
}
HSLFLine l = addLine(edge);
l.setLineColor(color);
}
public LineDash getBorderDash(BorderEdge edge) {
HSLFLine l;
switch (edge) {
case bottom: l = borderBottom; break;
case top: l = borderTop; break;
case right: l = borderRight; break;
case left: l = borderLeft; break;
default: throw new IllegalArgumentException();
}
return (l == null) ? null : l.getLineDash();
}
@Override
public void setBorderDash(BorderEdge edge, LineDash dash) {
if (edge == null || dash == null) {
throw new IllegalArgumentException("BorderEdge and/or LineDash need to be specified.");
}
HSLFLine l = addLine(edge);
l.setLineDash(dash);
}
public LineCompound getBorderCompound(BorderEdge edge) {
HSLFLine l;
switch (edge) {
case bottom: l = borderBottom; break;
case top: l = borderTop; break;
case right: l = borderRight; break;
case left: l = borderLeft; break;
default: throw new IllegalArgumentException();
}
return (l == null) ? null : l.getLineCompound();
}
@Override
public void setBorderCompound(BorderEdge edge, LineCompound compound) {
if (edge == null || compound == null) {
throw new IllegalArgumentException("BorderEdge and/or LineCompound need to be specified.");
}
HSLFLine l = addLine(edge);
l.setLineCompound(compound);
}
protected HSLFLine addLine(BorderEdge edge) {
switch (edge) {
case bottom: {
if (borderBottom == null) {
borderBottom = createBorder(edge);
HSLFTableCell c = getSiblingCell(1,0);
if (c != null) {
assert(c.borderTop == null);
c.borderTop = borderBottom;
}
}
return borderBottom;
}
case top: {
if (borderTop == null) {
borderTop = createBorder(edge);
HSLFTableCell c = getSiblingCell(-1,0);
if (c != null) {
assert(c.borderBottom == null);
c.borderBottom = borderTop;
}
}
return borderTop;
}
case right: {
if (borderRight == null) {
borderRight = createBorder(edge);
HSLFTableCell c = getSiblingCell(0,1);
if (c != null) {
assert(c.borderLeft == null);
c.borderLeft = borderRight;
}
}
return borderRight;
}
case left: {
if (borderLeft == null) {
borderLeft = createBorder(edge);
HSLFTableCell c = getSiblingCell(0,-1);
if (c != null) {
assert(c.borderRight == null);
c.borderRight = borderLeft;
}
}
return borderLeft;
}
default:
throw new IllegalArgumentException();
}
}
@Override
public void removeBorder(BorderEdge edge) {
switch (edge) {
case bottom: {
if (borderBottom == null) break;
getParent().removeShape(borderBottom);
borderBottom = null;
HSLFTableCell c = getSiblingCell(1,0);
if (c != null) {
c.borderTop = null;
}
break;
}
case top: {
if (borderTop == null) break;
getParent().removeShape(borderTop);
borderTop = null;
HSLFTableCell c = getSiblingCell(-1,0);
if (c != null) {
c.borderBottom = null;
}
break;
}
case right: {
if (borderRight == null) break;
getParent().removeShape(borderRight);
borderRight = null;
HSLFTableCell c = getSiblingCell(0,1);
if (c != null) {
c.borderLeft = null;
}
break;
}
case left: {
if (borderLeft == null) break;
getParent().removeShape(borderLeft);
borderLeft = null;
HSLFTableCell c = getSiblingCell(0,-1);
if (c != null) {
c.borderRight = null;
}
break;
}
default:
throw new IllegalArgumentException();
}
}
protected HSLFTableCell getSiblingCell(int row, int col) {
return getParent().getRelativeCell(this, row, col);
}
/**
* Create a border to format this table
*
* @return the created border
*/
private HSLFLine createBorder(BorderEdge edge) {
HSLFTable table = getParent();
HSLFLine line = new HSLFLine(table);
table.addShape(line);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1);
setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1);
setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000);
anchorBorder(edge, line);
return line;
}
protected void applyLineProperties(BorderEdge edge, HSLFLine other) {
HSLFLine line = addLine(edge);
line.setLineWidth(other.getLineWidth());
line.setLineColor(other.getLineColor());
// line.setLineCompound(other.getLineCompound());
// line.setLineDashing(other.getLineDashing());
}
@Override
public HSLFTable getParent() {
return (HSLFTable)super.getParent();
} }
} }

View File

@ -137,10 +137,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
_runs.add(run); _runs.add(run);
} }
/** @Override
* Fetch the rich text runs (runs of text with the same styling) that
* are contained within this block of text
*/
public List<HSLFTextRun> getTextRuns() { public List<HSLFTextRun> getTextRuns() {
return _runs; return _runs;
} }
@ -889,9 +886,13 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
HSLFTextParagraph htp = paragraphs.get(paragraphs.size() - 1); HSLFTextParagraph htp = paragraphs.get(paragraphs.size() - 1);
HSLFTextRun htr = htp.getTextRuns().get(htp.getTextRuns().size() - 1); HSLFTextRun htr = htp.getTextRuns().get(htp.getTextRuns().size() - 1);
boolean isFirst = !newParagraph; boolean addParagraph = newParagraph;
for (String rawText : text.split("(?<=\r)")) { for (String rawText : text.split("(?<=\r)")) {
if (!isFirst) { // special case, if last text paragraph or run is empty, we will reuse it
boolean lastRunEmpty = (htr.getLength() == 0);
boolean lastParaEmpty = lastRunEmpty && (htp.getTextRuns().size() == 1);
if (addParagraph && !lastParaEmpty) {
TextPropCollection tpc = htp.getParagraphStyle(); TextPropCollection tpc = htp.getParagraphStyle();
HSLFTextParagraph prevHtp = htp; HSLFTextParagraph prevHtp = htp;
htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom); htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom);
@ -901,11 +902,10 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
htp.supplySheet(prevHtp.getSheet()); htp.supplySheet(prevHtp.getSheet());
paragraphs.add(htp); paragraphs.add(htp);
} }
isFirst = false; addParagraph = true;
if (!lastRunEmpty) {
TextPropCollection tpc = htr.getCharacterStyle(); TextPropCollection tpc = htr.getCharacterStyle();
// special case, last text run is empty, we will reuse it
if (htr.getLength() > 0) {
htr = new HSLFTextRun(htp); htr = new HSLFTextRun(htp);
htr.getCharacterStyle().copy(tpc); htr.getCharacterStyle().copy(tpc);
htp.addTextRun(htr); htp.addTextRun(htr);

View File

@ -157,44 +157,32 @@ public final class HSLFTextRun implements TextRun {
// --------------- Friendly getters / setters on rich text properties ------- // --------------- Friendly getters / setters on rich text properties -------
/** @Override
* Is the text bold?
*/
public boolean isBold() { public boolean isBold() {
return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX); return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX);
} }
/** @Override
* Is the text bold?
*/
public void setBold(boolean bold) { public void setBold(boolean bold) {
setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold); setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold);
} }
/** @Override
* Is the text italic?
*/
public boolean isItalic() { public boolean isItalic() {
return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX); return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX);
} }
/** @Override
* Is the text italic?
*/
public void setItalic(boolean italic) { public void setItalic(boolean italic) {
setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic); setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic);
} }
/** @Override
* Is the text underlined?
*/
public boolean isUnderlined() { public boolean isUnderlined() {
return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX); return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
} }
/** @Override
* Is the text underlined?
*/
public void setUnderlined(boolean underlined) { public void setUnderlined(boolean underlined) {
setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined); setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
} }
@ -227,16 +215,12 @@ public final class HSLFTextRun implements TextRun {
setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag); setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag);
} }
/** @Override
* Gets the strikethrough flag
*/
public boolean isStrikethrough() { public boolean isStrikethrough() {
return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX); return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX);
} }
/** @Override
* Sets the strikethrough flag
*/
public void setStrikethrough(boolean flag) { public void setStrikethrough(boolean flag) {
setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag); setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag);
} }
@ -288,10 +272,7 @@ public final class HSLFTextRun implements TextRun {
setCharTextPropVal("font.index", idx); setCharTextPropVal("font.index", idx);
} }
@Override
/**
* Sets the font name to use
*/
public void setFontFamily(String fontFamily) { public void setFontFamily(String fontFamily) {
HSLFSheet sheet = parentParagraph.getSheet(); HSLFSheet sheet = parentParagraph.getSheet();
HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow(); HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
@ -301,13 +282,10 @@ public final class HSLFTextRun implements TextRun {
return; return;
} }
// Get the index for this font (adding if needed) // Get the index for this font (adding if needed)
int fontIdx = slideShow.getFontCollection().addFont(fontFamily); Integer fontIdx = (fontFamily == null) ? null : slideShow.getFontCollection().addFont(fontFamily);
setCharTextPropVal("font.index", fontIdx); setCharTextPropVal("font.index", fontIdx);
} }
/**
* Gets the font name
*/
@Override @Override
public String getFontFamily() { public String getFontFamily() {
HSLFSheet sheet = parentParagraph.getSheet(); HSLFSheet sheet = parentParagraph.getSheet();
@ -373,12 +351,14 @@ public final class HSLFTextRun implements TextRun {
return TextCap.NONE; return TextCap.NONE;
} }
@Override
public boolean isSubscript() { public boolean isSubscript() {
return false; return getSuperscript() < 0;
} }
@Override
public boolean isSuperscript() { public boolean isSuperscript() {
return false; return getSuperscript() > 0;
} }
public byte getPitchAndFamily() { public byte getPitchAndFamily() {

View File

@ -17,20 +17,37 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.apache.poi.hslf.record.RecordTypes.*; import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom;
import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.ddf.*; import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.EscherTextboxWrapper;
import org.apache.poi.hslf.record.InteractiveInfo;
import org.apache.poi.hslf.record.InteractiveInfoAtom;
import org.apache.poi.hslf.record.OEPlaceholderAtom;
import org.apache.poi.hslf.record.PPDrawing;
import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawTextShape; import org.apache.poi.sl.draw.DrawTextShape;
import org.apache.poi.sl.usermodel.*; import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
@ -57,14 +74,35 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
/* package */ static final int AnchorBottomCenteredBaseline = 9; /* package */ static final int AnchorBottomCenteredBaseline = 9;
/** /**
* How to wrap the text * Specifies that a line of text will continue on subsequent lines instead
* of extending into or beyond a margin.
* Office Excel 2007, Excel 2010, PowerPoint 97, and PowerPoint 2010 read
* and use this value properly but do not write it.
*/ */
public static final int WrapSquare = 0; public static final int WrapSquare = 0;
/**
* Specifies a wrapping rule that is equivalent to that of WrapSquare
* Excel 97, Excel 2000, Excel 2002, and Office Excel 2003 use this value.
* All other product versions listed at the beginning of this appendix ignore this value.
*/
public static final int WrapByPoints = 1; public static final int WrapByPoints = 1;
/**
* Specifies that a line of text will extend into or beyond a margin instead
* of continuing on subsequent lines.
* Excel 97, Word 97, Excel 2000, Word 2000, Excel 2002,
* and Office Excel 2003 do not use this value.
*/
public static final int WrapNone = 2; public static final int WrapNone = 2;
/**
* Specifies a wrapping rule that is undefined and MUST be ignored.
*/
public static final int WrapTopBottom = 3; public static final int WrapTopBottom = 3;
/**
* Specifies a wrapping rule that is undefined and MUST be ignored.
*/
public static final int WrapThrough = 4; public static final int WrapThrough = 4;
/** /**
* TextRun object which holds actual text and format data * TextRun object which holds actual text and format data
*/ */
@ -302,24 +340,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align2); setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align2);
} }
@Override
public VerticalAlignment getVerticalAlignment() {
int va = getAlignment();
switch (va) {
case AnchorTop:
case AnchorTopCentered:
case AnchorTopBaseline:
case AnchorTopCenteredBaseline: return VerticalAlignment.TOP;
case AnchorBottom:
case AnchorBottomCentered:
case AnchorBottomBaseline:
case AnchorBottomCenteredBaseline: return VerticalAlignment.BOTTOM;
default:
case AnchorMiddle:
case AnchorMiddleCentered: return VerticalAlignment.MIDDLE;
}
}
/** /**
* @return true, if vertical alignment is relative to baseline * @return true, if vertical alignment is relative to baseline
* this is only used for older versions less equals Office 2003 * this is only used for older versions less equals Office 2003
@ -354,22 +374,34 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
} }
} }
public void setVerticalAlignment(VerticalAlignment vAlign) { @Override
setAlignment(isHorizontalCentered(), vAlign);
}
/**
* Sets if the paragraphs are horizontal centered
*
* @param isCentered true, if the paragraphs are horizontal centered
* A {@code null} values unsets this property.
*
* @see TextShape#isHorizontalCentered()
*/
public void setHorizontalCentered(Boolean isCentered) { public void setHorizontalCentered(Boolean isCentered) {
setAlignment(isCentered, getVerticalAlignment()); setAlignment(isCentered, getVerticalAlignment());
} }
@Override
public VerticalAlignment getVerticalAlignment() {
int va = getAlignment();
switch (va) {
case AnchorTop:
case AnchorTopCentered:
case AnchorTopBaseline:
case AnchorTopCenteredBaseline: return VerticalAlignment.TOP;
case AnchorBottom:
case AnchorBottomCentered:
case AnchorBottomBaseline:
case AnchorBottomCenteredBaseline: return VerticalAlignment.BOTTOM;
default:
case AnchorMiddle:
case AnchorMiddleCentered: return VerticalAlignment.MIDDLE;
}
}
@Override
public void setVerticalAlignment(VerticalAlignment vAlign) {
setAlignment(isHorizontalCentered(), vAlign);
}
/** /**
* Returns the distance (in points) between the bottom of the text frame * 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. * and the bottom of the inscribed rectangle of the shape that contains the text.
@ -479,12 +511,6 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
setEscherProperty(propId, Units.toEMU(margin)); setEscherProperty(propId, Units.toEMU(margin));
} }
@Override
public boolean getWordWrap(){
int ww = getWordWrapEx();
return (ww != WrapNone);
}
/** /**
* Returns the value indicating word wrap. * Returns the value indicating word wrap.
* *
@ -505,10 +531,21 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
* @param wrap the value indicating how the text should be wrapped. * @param wrap the value indicating how the text should be wrapped.
* Must be one of the <code>Wrap*</code> constants defined in this class. * Must be one of the <code>Wrap*</code> constants defined in this class.
*/ */
public void setWordWrap(int wrap){ public void setWordWrapEx(int wrap){
setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap); setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
} }
@Override
public boolean getWordWrap(){
int ww = getWordWrapEx();
return (ww != WrapNone);
}
@Override
public void setWordWrap(boolean wrap) {
setWordWrapEx(wrap ? WrapSquare : WrapNone);
}
/** /**
* @return id for the text. * @return id for the text.
*/ */
@ -699,6 +736,14 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return insets; return insets;
} }
@Override
public void setInsets(Insets2D insets) {
setTopInset(insets.top);
setLeftInset(insets.left);
setBottomInset(insets.bottom);
setRightInset(insets.right);
}
@Override @Override
public double getTextHeight(){ public double getTextHeight(){
DrawFactory drawFact = DrawFactory.getInstance(null); DrawFactory drawFact = DrawFactory.getInstance(null);
@ -747,14 +792,7 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return HSLFTextParagraph.appendText(paras, text, newParagraph); return HSLFTextParagraph.appendText(paras, text, newParagraph);
} }
/** @Override
* Sets (overwrites) the current text.
* Uses the properties of the first paragraph / textrun
*
* @param text the text string used by this object.
*
* @return the last text run of the splitted text
*/
public HSLFTextRun setText(String text) { public HSLFTextRun setText(String text) {
// init paragraphs // init paragraphs
List<HSLFTextParagraph> paras = getTextParagraphs(); List<HSLFTextParagraph> paras = getTextParagraphs();
@ -783,5 +821,64 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return HSLFHyperlink.find(this); return HSLFHyperlink.find(this);
} }
@Override
public void setTextPlaceholder(TextPlaceholder placeholder) {
// TOOD: check for correct placeholder handling - see org.apache.poi.hslf.model.Placeholder
Placeholder ph = null;
int runType;
switch (placeholder) {
default:
case BODY:
runType = TextHeaderAtom.BODY_TYPE;
ph = Placeholder.BODY;
break;
case TITLE:
runType = TextHeaderAtom.TITLE_TYPE;
ph = Placeholder.TITLE;
break;
case CENTER_BODY:
runType = TextHeaderAtom.CENTRE_BODY_TYPE;
ph = Placeholder.BODY;
break;
case CENTER_TITLE:
runType = TextHeaderAtom.CENTER_TITLE_TYPE;
ph = Placeholder.TITLE;
break;
case HALF_BODY:
runType = TextHeaderAtom.HALF_BODY_TYPE;
ph = Placeholder.BODY;
break;
case QUARTER_BODY:
runType = TextHeaderAtom.QUARTER_BODY_TYPE;
ph = Placeholder.BODY;
break;
case NOTES:
runType = TextHeaderAtom.NOTES_TYPE;
break;
case OTHER:
runType = TextHeaderAtom.OTHER_TYPE;
break;
}
setRunType(runType);
if (ph != null) {
setPlaceholder(ph);
}
}
@Override
public TextPlaceholder getTextPlaceholder() {
switch (getRunType()) {
default:
case TextHeaderAtom.BODY_TYPE: return TextPlaceholder.BODY;
case TextHeaderAtom.TITLE_TYPE: return TextPlaceholder.TITLE;
case TextHeaderAtom.NOTES_TYPE: return TextPlaceholder.NOTES;
case TextHeaderAtom.OTHER_TYPE: return TextPlaceholder.OTHER;
case TextHeaderAtom.CENTRE_BODY_TYPE: return TextPlaceholder.CENTER_BODY;
case TextHeaderAtom.CENTER_TITLE_TYPE: return TextPlaceholder.CENTER_TITLE;
case TextHeaderAtom.HALF_BODY_TYPE: return TextPlaceholder.HALF_BODY;
case TextHeaderAtom.QUARTER_BODY_TYPE: return TextPlaceholder.QUARTER_BODY;
}
}
} }

View File

@ -81,27 +81,27 @@ public final class TestLine {
*/ */
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 200, 300, 0)); line.setAnchor(new java.awt.Rectangle(450, 200, 300, 0));
line.setLineDashing(LineDash.SOLID); line.setLineDash(LineDash.SOLID);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 230, 300, 0)); line.setAnchor(new java.awt.Rectangle(450, 230, 300, 0));
line.setLineDashing(LineDash.DASH); line.setLineDash(LineDash.DASH);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 260, 300, 0)); line.setAnchor(new java.awt.Rectangle(450, 260, 300, 0));
line.setLineDashing(LineDash.DOT); line.setLineDash(LineDash.DOT);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 290, 300, 0)); line.setAnchor(new java.awt.Rectangle(450, 290, 300, 0));
line.setLineDashing(LineDash.DASH_DOT); line.setLineDash(LineDash.DASH_DOT);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(450, 320, 300, 0)); line.setAnchor(new java.awt.Rectangle(450, 320, 300, 0));
line.setLineDashing(LineDash.LG_DASH_DOT_DOT); line.setLineDash(LineDash.LG_DASH_DOT_DOT);
slide.addShape(line); slide.addShape(line);
/** /**
@ -109,21 +109,21 @@ public final class TestLine {
*/ */
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 400, 300, 0)); line.setAnchor(new java.awt.Rectangle(75, 400, 300, 0));
line.setLineDashing(LineDash.DASH_DOT); line.setLineDash(LineDash.DASH_DOT);
line.setLineCompound(LineCompound.TRIPLE); line.setLineCompound(LineCompound.TRIPLE);
line.setLineWidth(5.0); line.setLineWidth(5.0);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 430, 300, 0)); line.setAnchor(new java.awt.Rectangle(75, 430, 300, 0));
line.setLineDashing(LineDash.DASH); line.setLineDash(LineDash.DASH);
line.setLineCompound(LineCompound.THICK_THIN); line.setLineCompound(LineCompound.THICK_THIN);
line.setLineWidth(4.0); line.setLineWidth(4.0);
slide.addShape(line); slide.addShape(line);
line = new HSLFLine(); line = new HSLFLine();
line.setAnchor(new java.awt.Rectangle(75, 460, 300, 0)); line.setAnchor(new java.awt.Rectangle(75, 460, 300, 0));
line.setLineDashing(LineDash.DOT); line.setLineDash(LineDash.DOT);
line.setLineCompound(LineCompound.DOUBLE); line.setLineCompound(LineCompound.DOUBLE);
line.setLineWidth(8.0); line.setLineWidth(8.0);
slide.addShape(line); slide.addShape(line);

View File

@ -91,7 +91,7 @@ public final class TestShapes {
java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60); java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60);
line.setAnchor(lineAnchor); line.setAnchor(lineAnchor);
line.setLineWidth(3); line.setLineWidth(3);
line.setLineDashing(LineDash.DASH); line.setLineDash(LineDash.DASH);
line.setLineColor(Color.red); line.setLineColor(Color.red);
slide.addShape(line); slide.addShape(line);
@ -99,7 +99,7 @@ public final class TestShapes {
java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111); java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111);
ellipse.setAnchor(ellipseAnchor); ellipse.setAnchor(ellipseAnchor);
ellipse.setLineWidth(2); ellipse.setLineWidth(2);
ellipse.setLineDashing(LineDash.SOLID); ellipse.setLineDash(LineDash.SOLID);
ellipse.setLineColor(Color.green); ellipse.setLineColor(Color.green);
ellipse.setFillColor(Color.lightGray); ellipse.setFillColor(Color.lightGray);
slide.addShape(ellipse); slide.addShape(ellipse);

View File

@ -57,15 +57,15 @@ public final class TestTable {
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
HSLFTable tbl = new HSLFTable(2, 5); HSLFTable tbl = slide.createTable(2, 5);
slide.addShape(tbl);
HSLFTableCell cell = tbl.getCell(0, 0); HSLFTableCell cell = tbl.getCell(0, 0);
//table cells have type=TextHeaderAtom.OTHER_TYPE, see bug #46033 //table cells have type=TextHeaderAtom.OTHER_TYPE, see bug #46033
assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType()); assertEquals(TextHeaderAtom.OTHER_TYPE, cell.getTextParagraphs().get(0).getRunType());
assertTrue(slide.getShapes().get(0) instanceof HSLFTable); HSLFShape tblSh = slide.getShapes().get(0);
HSLFTable tbl2 = (HSLFTable)slide.getShapes().get(0); assertTrue(tblSh instanceof HSLFTable);
HSLFTable tbl2 = (HSLFTable)tblSh;
assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns()); assertEquals(tbl.getNumberOfColumns(), tbl2.getNumberOfColumns());
assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows()); assertEquals(tbl.getNumberOfRows(), tbl2.getNumberOfRows());
@ -89,10 +89,9 @@ public final class TestTable {
HSLFSlideShow ppt = new HSLFSlideShow(); HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide(); HSLFSlide slide = ppt.createSlide();
List<HSLFShape> shapes; List<HSLFShape> shapes;
HSLFTable tbl1 = new HSLFTable(1, 5); HSLFTable tbl1 = slide.createTable(1, 5);
assertEquals(5, tbl1.getNumberOfColumns()); assertEquals(5, tbl1.getNumberOfColumns());
assertEquals(1, tbl1.getNumberOfRows()); assertEquals(1, tbl1.getNumberOfRows());
slide.addShape(tbl1);
shapes = slide.getShapes(); shapes = slide.getShapes();
assertEquals(1, shapes.size()); assertEquals(1, shapes.size());
@ -106,14 +105,16 @@ public final class TestTable {
@Test @Test
public void testIllegalCOnstruction(){ public void testIllegalCOnstruction(){
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide();
try { try {
new HSLFTable(0, 5); slide.createTable(0, 5);
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1"); fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){ } catch (IllegalArgumentException e){
} }
try { try {
new HSLFTable(5, 0); slide.createTable(5, 0);
fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1"); fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
} catch (IllegalArgumentException e){ } catch (IllegalArgumentException e){

View File

@ -19,22 +19,49 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.awt.Rectangle;
import java.util.List; import java.util.List;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.draw.DrawTableShape;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.junit.Test; import org.junit.Test;
/** /**
* Test that checks numbered list functionality. * Table related tests
*
* @author Alex Nikiforov [mailto:anikif@gmail.com]
*/ */
public class TestTable { public class TestTable {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@Test
public void moveTable() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide();
int rows = 3, cols = 5;
HSLFTable table = slide.createTable(rows, cols);
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
HSLFTableCell c = table.getCell(row, col);
c.setText("r"+row+"c"+col);
}
}
new DrawTableShape(table).setAllBorders(1.0, Color.black, StrokeStyle.LineDash.DASH_DOT);
table.setAnchor(new Rectangle(100, 100, 400, 400));
Rectangle rectExp = new Rectangle(420,367,80,133);
Rectangle rectAct = table.getCell(rows-1, cols-1).getAnchor();
assertEquals(rectExp, rectAct);
}
@Test @Test
public void testTable() throws Exception { public void testTable() throws Exception {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt")); HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("54111.ppt"));

View File

@ -571,4 +571,13 @@ public final class TestTextRun {
} }
} }
@Test
public void testAppendEmpty() throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide s = ppt.createSlide();
HSLFTextBox title = s.addTitle();
title.setText("");
title.appendText("\n", true);
title.appendText("para", true);
}
} }