support for text bullets

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@542179 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2007-05-28 09:45:09 +00:00
parent bd4852d48b
commit ff60d78860
10 changed files with 351 additions and 53 deletions

View File

@ -37,6 +37,7 @@
<li><link href="#Pictures">How to work with pictures</link></li>
<li><link href="#SlideTitle">How to set slide title</link></li>
<li><link href="#Fill">How to work with slide/shape background</link></li>
<li><link href="#Bullets">How to create bulleted lists</link></li>
</ul>
</section>
<section><title>Features</title>
@ -319,6 +320,35 @@
slide.addShape(shape);
</source>
</section>
<anchor id="Bullets"/>
<section><title>How to create bulleted lists</title>
<source>
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
TextBox shape = new TextBox();
RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
shape.setText(
"January\r" +
"February\r" +
"March\r" +
"April");
rt.setFontSize(42);
rt.setBullet(true);
rt.setBulletOffset(0); //bullet offset
rt.setTextOffset(50); //text offset (should be greater than bullet offset)
rt.setBulletChar('\u263A'); //bullet character
slide.addShape(shape);
shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300)); //position of the text box in the slide
slide.addShape(shape);
FileOutputStream out = new FileOutputStream("bullets.ppt");
ppt.write(out);
out.close();
</source>
</section>
</section>
</section>

View File

@ -0,0 +1,62 @@
/* ====================================================================
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.examples;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hslf.usermodel.RichTextRun;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextBox;
import java.io.FileOutputStream;
/**
* How to create a single-level bulleted list
* and change some of the bullet attributes
*
* @author Yegor Kozlov
*/
public class BulletsDemo {
public static void main(String[] args) throws Exception {
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
TextBox shape = new TextBox();
RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
shape.setText(
"January\r" +
"February\r" +
"March\r" +
"April");
rt.setFontSize(42);
rt.setBullet(true);
rt.setBulletOffset(0); //bullet offset
rt.setTextOffset(50); //text offset (should be greater than bullet offset)
rt.setBulletChar('\u263A'); //bullet character
slide.addShape(shape);
shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300)); //position of the text box in the slide
slide.addShape(shape);
FileOutputStream out = new FileOutputStream("bullets.ppt");
ppt.write(out);
out.close();
}
}

View File

@ -32,8 +32,9 @@ public class CharFlagsTextProp extends BitMaskTextProp {
public static final int ENABLE_NUMBERING_1_IDX = 11;
public static final int ENABLE_NUMBERING_2_IDX = 12;
public static String NAME = "char_flags";
public CharFlagsTextProp() {
super(2,0xffff, "char_flags", new String[] {
super(2,0xffff, NAME, new String[] {
"bold", // 0x0001
"italic", // 0x0002
"underline", // 0x0004

View File

@ -0,0 +1,41 @@
/* ====================================================================
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.textproperties;
/**
* Definition for the common paragraph text property bitset.
*
* @author Yegor Kozlov
*/
public class ParagraphFlagsTextProp extends BitMaskTextProp {
public static final int BULLET_IDX = 0;
public static final int BULLET_HARDFONT_IDX = 1;
public static final int BULLET_HARDCOLOR_IDX = 2;
public static final int BULLET_HARDSIZE_IDX = 4;
public static String NAME = "paragraph_flags";
public ParagraphFlagsTextProp() {
super(2, 0xF, NAME, new String[] {
"bullet",
"bullet.hardfont",
"bullet.hardcolor",
"bullet.hardsize"}
);
}
}

View File

@ -19,11 +19,7 @@
package org.apache.poi.hslf.record;
import org.apache.poi.hslf.model.textproperties.AlignmentTextProp;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.*;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -95,18 +91,15 @@ public class StyleTextPropAtom extends RecordAtom
/** All the different kinds of paragraph properties we might handle */
public static TextProp[] paragraphTextPropTypes = new TextProp[] {
new BitMaskTextProp(2, 0xF, "paragraph_flags", new String[] {
"bullet", "bullet.hardfont",
"bullet.hardcolor", "bullet.hardsize"}
),
new ParagraphFlagsTextProp(),
new TextProp(2, 0x80, "bullet.char"),
new TextProp(2, 0x10, "bullet.font"),
new TextProp(4, 0x20, "bullet.color"),
new TextProp(2, 0x40, "bullet.size"),
new AlignmentTextProp(),
new TextProp(2, 0x400, "bullet.offset"),
new TextProp(2, 0x200, "para_unknown_2"),
new TextProp(2, 0x100, "text.offset"),
new TextProp(2, 0x200, "para_unknown_2"),
new TextProp(2, 0x400, "bullet.offset"),
new TextProp(2, 0x1000, "linespacing"),
new TextProp(2, 0x2000, "spacebefore"),
new TextProp(2, 0x4000, "spaceafter"),

View File

@ -23,10 +23,7 @@ import org.apache.poi.util.LittleEndian;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.*;
/**
* TxMasterStyleAtom atom (4003).
@ -177,10 +174,7 @@ public class TxMasterStyleAtom extends RecordAtom {
return StyleTextPropAtom.paragraphTextPropTypes;
} else {
return new TextProp[] {
new BitMaskTextProp(2, 0xF, "paragraph_flags", new String[] {
"bullet", "bullet.hardfont",
"bullet.hardcolor", "bullet.hardsize"}
),
new ParagraphFlagsTextProp(),
new TextProp(2, 0x80, "bullet.char"),
new TextProp(2, 0x10, "bullet.font"),
new TextProp(2, 0x40, "bullet.size"),

View File

@ -20,18 +20,15 @@
package org.apache.poi.hslf.usermodel;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.Sheet;
import org.apache.poi.hslf.model.SlideMaster;
import org.apache.poi.hslf.model.MasterSheet;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.model.Shape;
import org.apache.poi.hslf.model.textproperties.*;
import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.exceptions.HSLFException;
import java.awt.*;
/**
* Represents a run of text, all with the same style
*
@ -164,37 +161,64 @@ public class RichTextRun
* text property won't be set if there's no CharFlagsTextProp.
*/
private boolean isCharFlagsTextPropVal(int index) {
CharFlagsTextProp cftp = null;
if (characterStyle != null){
cftp = (CharFlagsTextProp)characterStyle.findByName("char_flags");
return getFlag(true, index);
}
private boolean getFlag(boolean isCharacter, int index) {
TextPropCollection props;
String propname;
if (isCharacter){
props = characterStyle;
propname = CharFlagsTextProp.NAME;
} else {
props = paragraphStyle;
propname = ParagraphFlagsTextProp.NAME;
}
if (cftp == null){
BitMaskTextProp prop = null;
if (props != null){
prop = (BitMaskTextProp)props.findByName(propname);
}
if (prop == null){
Sheet sheet = parentRun.getSheet();
int txtype = parentRun.getRunType();
MasterSheet master = sheet.getMasterSheet();
if (master != null)
cftp = (CharFlagsTextProp)master.getStyleAttribute(txtype, getIndentLevel(), "char_flags", true);
prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
}
return cftp == null ? false : cftp.getSubValue(index);
}
return prop == null ? false : prop.getSubValue(index);
}
/**
* Set the value of the given flag in the CharFlagsTextProp, adding
* it if required.
*/
private void setCharFlagsTextPropVal(int index, boolean value) {
// Ensure we have the StyleTextProp atom we're going to need
if(characterStyle == null) {
parentRun.ensureStyleAtomPresent();
// characterStyle will now be defined
}
CharFlagsTextProp cftp = (CharFlagsTextProp)
fetchOrAddTextProp(characterStyle, "char_flags");
cftp.setSubValue(value,index);
setFlag(true, index, value);
}
private void setFlag(boolean isCharacter, int index, boolean value) {
TextPropCollection props;
String propname;
if (isCharacter){
props = characterStyle;
propname = CharFlagsTextProp.NAME;
} else {
props = paragraphStyle;
propname = ParagraphFlagsTextProp.NAME;
}
// Ensure we have the StyleTextProp atom we're going to need
if(props == null) {
parentRun.ensureStyleAtomPresent();
props = isCharacter ? characterStyle : paragraphStyle;
}
BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(props, propname);
prop.setSubValue(value,index);
}
/**
* Returns the named TextProp, either by fetching it (if it exists) or adding it
* (if it didn't)
@ -396,7 +420,62 @@ public class RichTextRun
public int getIndentLevel() {
return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
}
/**
* Sets whether this rich text run has bullets
*/
public void setBullet(boolean flag) {
setFlag(false, ParagraphFlagsTextProp.BULLET_IDX, flag);
}
/**
* Returns whether this rich text run has bullets
*/
public boolean isBullet() {
return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
}
/**
* Sets the bullet character
*/
public void setBulletChar(char c) {
setParaTextPropVal("bullet.char", c);
}
/**
* Returns the bullet character
*/
public char getBulletChar() {
return (char)getParaTextPropVal("bullet.char");
}
/**
* Sets the bullet offset
*/
public void setBulletOffset(int offset) {
setParaTextPropVal("bullet.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
}
/**
* Returns the bullet offset
*/
public int getBulletOffset() {
return getParaTextPropVal("bullet.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
}
/**
* Sets the text offset
*/
public void setTextOffset(int offset) {
setParaTextPropVal("text.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
}
/**
* Returns the text offset
*/
public int getTextOffset() {
return getParaTextPropVal("text.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
}
// --------------- Internal HSLF methods, not intended for end-user use! -------
/**

View File

@ -119,7 +119,14 @@ public class SlideShow
public SlideShow() throws IOException {
this(new HSLFSlideShow());
}
/**
* Constructs a Powerpoint document from an input stream.
*/
public SlideShow(InputStream inputStream) throws IOException {
this(new HSLFSlideShow(inputStream));
}
/**
* Find the records that are parent-aware, and tell them
* who their parent is

View File

@ -16,15 +16,11 @@
*/
package org.apache.poi.hslf.usermodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.File;
import java.io.*;
import java.awt.*;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.SlideMaster;
import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.SlideListWithText;
@ -458,4 +454,99 @@ if(false) {
}
}
}
public void testReadParagraphStyles() throws Exception {
FileInputStream is = new FileInputStream(new File(System.getProperty("HSLF.testdata.path"), "bullets.ppt"));
SlideShow ppt = new SlideShow(is);
is.close();
assertTrue("No Exceptions while reading file", true);
RichTextRun rt;
TextRun[] txt;
Slide[] slide = ppt.getSlides();
assertEquals(2, slide.length);
txt = slide[0].getTextRuns();
assertEquals(2, txt.length);
assertEquals("Title text", txt[0].getRawText());
assertEquals(1, txt[0].getRichTextRuns().length);
rt = txt[0].getRichTextRuns()[0];
assertFalse(rt.isBullet());
assertEquals(
"This is a text placeholder that \r" +
"follows the design pattern\r" +
"Defined in the slide master\r" +
"and has bullets by default", txt[1].getRawText());
assertEquals(1, txt[1].getRichTextRuns().length);
rt = txt[1].getRichTextRuns()[0];
assertEquals('\u2022', rt.getBulletChar());
assertTrue(rt.isBullet());
txt = slide[1].getTextRuns();
assertEquals(2, txt.length);
assertEquals(
"Im a text box\r" +
"With bullets\r" +
"That follow the design pattern\r" +
"From the slide master", txt[0].getRawText());
assertEquals(1, txt[0].getRichTextRuns().length);
rt = txt[0].getRichTextRuns()[0];
assertTrue(rt.isBullet());
assertEquals('\u2022', rt.getBulletChar());
assertEquals(
"Im a text box with user-defined\r" +
"bullet character", txt[1].getRawText());
assertEquals(1, txt[1].getRichTextRuns().length);
rt = txt[1].getRichTextRuns()[0];
assertTrue(rt.isBullet());
assertEquals('\u263A', rt.getBulletChar());
}
public void testSetParagraphStyles() throws Exception {
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
TextBox shape = new TextBox();
RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
shape.setText(
"Hello, World!\r" +
"This should be\r" +
"Multiline text");
rt.setFontSize(42);
rt.setBullet(true);
rt.setTextOffset(50);
rt.setBulletOffset(0);
rt.setBulletChar('\u263A');
slide.addShape(shape);
assertEquals(42, rt.getFontSize());
assertEquals(true, rt.isBullet());
assertEquals(50, rt.getTextOffset());
assertEquals(0, rt.getBulletOffset());
assertEquals('\u263A', rt.getBulletChar());
shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));
slide.addShape(shape);
//serialize and read again
ByteArrayOutputStream out = new ByteArrayOutputStream();
ppt.write(out);
out.close();
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
slide = ppt.getSlides()[0];
shape = (TextBox)slide.getShapes()[0];
rt = shape.getTextRun().getRichTextRuns()[0];
assertEquals(42, rt.getFontSize());
assertEquals(true, rt.isBullet());
assertEquals(50, rt.getTextOffset());
assertEquals(0, rt.getBulletOffset());
assertEquals('\u263A', rt.getBulletChar());
}
}