com.lowagie.text.rtf.list.RtfList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rtf-gen Show documentation
Show all versions of rtf-gen Show documentation
RTF generation library derived from iText-2.1.7. All PDF features and RTF parsing are removed. Code is modernized for Java 8.
/*
* $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $
*
* Copyright 2008 Howard Shank ([email protected])
*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or under the terms of the GNU
* Library General Public License as published by the Free Software Foundation;
* either version 2 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* https://github.com/osobolev/rtf-gen
*/
package com.lowagie.text.rtf.list;
import com.lowagie.text.*;
import com.lowagie.text.factories.RomanAlphabetFactory;
import com.lowagie.text.factories.RomanNumberFactory;
import com.lowagie.text.rtf.RtfBasicElement;
import com.lowagie.text.rtf.RtfElement;
import com.lowagie.text.rtf.RtfExtendedElement;
import com.lowagie.text.rtf.document.RtfDocument;
import com.lowagie.text.rtf.style.RtfFont;
import com.lowagie.text.rtf.style.RtfFontList;
import com.lowagie.text.rtf.text.RtfParagraph;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.ArrayList;
/**
* The RtfList stores one List. It also provides the methods to write the
* list declaration and the list data.
*
* @author Mark Hall ([email protected])
* @author Howard Shank ([email protected])
* @version $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $
* @since 2.1.3
*/
public class RtfList extends RtfElement implements RtfExtendedElement {
/**
* Constant for the list number
*
* @since 2.1.3
*/
public static final byte[] LIST_NUMBER = DocWriter.getISOBytes("\\ls");
/**
* Constant for the list
*/
private static final byte[] LIST = DocWriter.getISOBytes("\\list");
/**
* Constant for the list id
*
* @since 2.1.3
*/
public static final byte[] LIST_ID = DocWriter.getISOBytes("\\listid");
/**
* Constant for the list template id
*/
private static final byte[] LIST_TEMPLATE_ID = DocWriter.getISOBytes("\\listtemplateid");
/**
* Constant for the simple list
*/
private static final byte[] LIST_SIMPLE = DocWriter.getISOBytes("\\listsimple");
/**
* Constant for the hybrid list
*/
private static final byte[] LIST_HYBRID = DocWriter.getISOBytes("\\listhybrid");
/**
* Constant to indicate if the list restarts at each section. Word 7 compatiblity
*/
private static final byte[] LIST_RESTARTHDN = DocWriter.getISOBytes("\\listrestarthdn");
/**
* Constant for the name of this list
*/
private static final byte[] LIST_NAME = DocWriter.getISOBytes("\\listname");
/**
* Constant for the identifier of the style of this list. Mutually exclusive with \\liststylename
*/
private static final byte[] LIST_STYLEID = DocWriter.getISOBytes("\\liststyleid");
/**
* Constant for the identifier of the style of this list. Mutually exclusive with \\liststyleid
*/
private static final byte[] LIST_STYLENAME = DocWriter.getISOBytes("\\liststylename");
// character properties
/**
* Constant for the list level value
*
* @since 2.1.3
*/
public static final byte[] LIST_LEVEL_NUMBER = DocWriter.getISOBytes("\\ilvl");
/**
* Constant for the old list text
*
* @since 2.1.3
*/
public static final byte[] LIST_TEXT = DocWriter.getISOBytes("\\listtext");
/**
* Constant for the old list number end
*
* @since 2.1.3
*/
public static final byte[] LIST_NUMBER_END = DocWriter.getISOBytes(".");
/**
* Constant for a tab character
*
* @since 2.1.3
*/
public static final byte[] TAB = DocWriter.getISOBytes("\\tab");
/**
* The subitems of this RtfList
*/
private final java.util.List items;
/**
* The parent list if there is one.
*/
private RtfList parentList = null;
/**
* The list id
*/
private int listID = -1;
/**
* List type of NORMAL - no control word
*
* @since 2.1.3
*/
public static final int LIST_TYPE_NORMAL = 0; /* Normal list type */
/**
* List type of listsimple
*
* @since 2.1.3
*/
public static final int LIST_TYPE_SIMPLE = 1; /* Simple list type */
/**
* List type of listhybrid
*
* @since 2.1.3
*/
public static final int LIST_TYPE_HYBRID = 2; /* Hybrid list type */
/**
* This RtfList type
*/
private int listType = LIST_TYPE_HYBRID;
/**
* The name of the list if it exists
*/
private String name = null;
/**
* The list number of this RtfList
*/
private int listNumber = -1;
/**
* The RtfList lists managed by this RtfListTable
*/
private final java.util.List listLevels = new ArrayList<>();
/**
* Constructs an empty RtfList object.
*
* @since 2.1.3
*/
public RtfList() {
super(null);
createDefaultLevels();
this.items = null;
}
/**
* Set the document.
*
* @param doc The RtfDocument
* @since 2.1.3
*/
public void setDocument(RtfDocument doc) {
this.document = doc;
// get the list number or create a new one adding it to the table
this.listNumber = document.getDocumentHeader().getListNumber(this);
}
/**
* Constructs an empty RtfList object.
*
* @param doc The RtfDocument this RtfList belongs to
* @since 2.1.3
*/
public RtfList(RtfDocument doc) {
super(doc);
createDefaultLevels();
this.items = null;
// get the list number or create a new one adding it to the table
this.listNumber = document.getDocumentHeader().getListNumber(this);
}
/**
* Constructs a new RtfList for the specified List.
*
* @param doc The RtfDocument this RtfList belongs to
* @param list The List this RtfList is based on
* @since 2.1.3
*/
public RtfList(RtfDocument doc, List list) {
// setup the listlevels
// Then, setup the list data below
// setup 1 listlevel if it's a simple list
// setup 9 if it's a regular list
// setup 9 if it's a hybrid list (default)
super(doc);
createDefaultLevels();
this.items = new ArrayList<>(); // list content
RtfListLevel ll = this.listLevels.get(0);
// get the list number or create a new one adding it to the table
this.listNumber = document.getDocumentHeader().getListNumber(this);
if (list.getSymbolIndent() > 0 && list.getIndentationLeft() > 0) {
ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1));
ll.setLeftIndent((int) ((list.getIndentationLeft() + list.getSymbolIndent()) * RtfElement.TWIPS_FACTOR));
} else if (list.getSymbolIndent() > 0) {
ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1));
ll.setLeftIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR));
} else if (list.getIndentationLeft() > 0) {
ll.setFirstIndent(0);
ll.setLeftIndent((int) (list.getIndentationLeft() * RtfElement.TWIPS_FACTOR));
} else {
ll.setFirstIndent(0);
ll.setLeftIndent(0);
}
ll.setRightIndent((int) (list.getIndentationRight() * RtfElement.TWIPS_FACTOR));
ll.setSymbolIndent((int) ((list.getSymbolIndent() + list.getIndentationLeft()) * RtfElement.TWIPS_FACTOR));
ll.correctIndentation();
ll.setTentative(false);
if (list instanceof RomanList) {
if (list.isLowercase()) {
ll.setListType(RtfListLevel.LIST_TYPE_LOWER_ROMAN);
} else {
ll.setListType(RtfListLevel.LIST_TYPE_UPPER_ROMAN);
}
} else if (list.isNumbered()) {
ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED);
} else if (list.isLettered()) {
if (list.isLowercase()) {
ll.setListType(RtfListLevel.LIST_TYPE_LOWER_LETTERS);
} else {
ll.setListType(RtfListLevel.LIST_TYPE_UPPER_LETTERS);
}
} else {
ll.setBulletCharacter(list.getPreSymbol() + list.getSymbol().getContent() + list.getPostSymbol());
ll.setListType(RtfListLevel.LIST_TYPE_BULLET);
}
// now setup the actual list contents.
for (int i = 0; i < list.getItems().size(); i++) {
try {
Element element = list.getItems().get(i);
if (element.type() == Element.CHUNK) {
element = new ListItem((Chunk) element);
}
if (element instanceof ListItem) {
ll.setAlignment(((ListItem) element).getAlignment());
}
RtfBasicElement[] rtfElements = doc.getMapper().mapElement(element);
for (RtfBasicElement rtfElement : rtfElements) {
if (rtfElement instanceof RtfList) {
((RtfList) rtfElement).setParentList(this);
} else if (rtfElement instanceof RtfListItem) {
((RtfListItem) rtfElement).setParent(ll);
}
ll.setFontNumber(new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))));
if (list.getSymbol() != null && list.getSymbol().getFont() != null && !list.getSymbol().getContent().startsWith("-") && list.getSymbol().getContent().length() > 0) {
// only set this to bullet symbol is not default
ll.setBulletFont(list.getSymbol().getFont());
ll.setBulletCharacter(list.getSymbol().getContent().substring(0, 1));
} else if (list.getSymbol() != null && list.getSymbol().getFont() != null) {
ll.setBulletFont(list.getSymbol().getFont());
} else {
ll.setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0)));
}
items.add(rtfElement);
}
} catch (DocumentException de) {
doc.log(de);
}
}
}
/**
* Writes the definition part of this list level
*
* @param result
* @throws IOException
* @since 2.1.3
*/
@Override
public void writeDefinition(OutputStream result) throws IOException {
result.write(OPEN_GROUP);
result.write(LIST);
result.write(LIST_TEMPLATE_ID);
result.write(intToByteArray(document.getRandomInt()));
int levelsToWrite = -1;
switch (this.listType) {
case LIST_TYPE_NORMAL:
levelsToWrite = listLevels.size();
break;
case LIST_TYPE_SIMPLE:
result.write(LIST_SIMPLE);
result.write(intToByteArray(1));
levelsToWrite = 1;
break;
case LIST_TYPE_HYBRID:
result.write(LIST_HYBRID);
levelsToWrite = listLevels.size();
break;
default:
break;
}
this.document.outputDebugLinebreak(result);
// TODO: Figure out hybrid because multi-level hybrid does not work.
// Seems hybrid is mixed type all single level - Simple = single level
// SIMPLE1/HYRBID
// 1. Line 1
// 2. Line 2
// MULTI-LEVEL LISTS Are Simple0 - 9 levels (0-8) all single digit
// 1. Line 1
// 1.1. Line 1.1
// 1.2. Line 1.2
// 2. Line 2
// write the listlevels here
for (int i = 0; i < levelsToWrite; i++) {
listLevels.get(i).writeDefinition(result);
this.document.outputDebugLinebreak(result);
}
result.write(LIST_ID);
result.write(intToByteArray(this.listID));
result.write(CLOSE_GROUP);
this.document.outputDebugLinebreak(result);
if (items != null) {
for (RtfBasicElement rtfElement : items) {
if (rtfElement instanceof RtfList) {
RtfList rl = (RtfList) rtfElement;
rl.writeDefinition(result);
break;
} else if (rtfElement instanceof RtfListItem) {
RtfListItem rli = (RtfListItem) rtfElement;
if (rli.writeDefinition(result))
break;
}
}
}
}
/**
* Writes the content of the RtfList
*
* @since 2.1.3
*/
@Override
public void writeContent(OutputStream result) throws IOException {
if (!this.inTable) {
result.write(OPEN_GROUP);
}
if (items != null) {
int itemNr = 0;
for (int i = 0; i < items.size(); i++) {
RtfElement thisRtfElement = (RtfElement) items.get(i);
if (thisRtfElement instanceof RtfListItem) {
itemNr++;
RtfListItem rtfElement = (RtfListItem) thisRtfElement;
RtfListLevel listLevel = rtfElement.getParent();
if (listLevel.getListLevel() == 0) {
correctIndentation();
}
if (i == 0) {
listLevel.writeListBeginning(result);
writeListNumbers(result);
}
writeListTextBlock(result, itemNr, listLevel);
rtfElement.writeContent(result);
if (i < (items.size() - 1) || !this.inTable || listLevel.getListType() > 0) { // TODO Fix no paragraph on last list item in tables
result.write(RtfParagraph.PARAGRAPH);
}
this.document.outputDebugLinebreak(result);
} else if (thisRtfElement instanceof RtfList) {
thisRtfElement.writeContent(result);
writeListNumbers(result);
this.document.outputDebugLinebreak(result);
}
}
}
if (!this.inTable) {
result.write(CLOSE_GROUP);
}
result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
}
/**
* @param result
* @param itemNr
* @param listLevel
* @throws IOException
* @since 2.1.3
*/
protected void writeListTextBlock(OutputStream result, int itemNr, RtfListLevel listLevel)
throws IOException {
result.write(OPEN_GROUP);
result.write(LIST_TEXT);
result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
if (this.inTable) {
result.write(RtfParagraph.IN_TABLE);
}
result.write(RtfFontList.FONT_NUMBER);
if (listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) {
result.write(intToByteArray(listLevel.getFontNumber().getFontNumber()));
} else {
result.write(intToByteArray(listLevel.getFontBullet().getFontNumber()));
}
listLevel.writeIndentation(result);
result.write(DELIMITER);
if (listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) {
switch (listLevel.getListType()) {
case RtfListLevel.LIST_TYPE_NUMBERED:
result.write(intToByteArray(itemNr));
break;
case RtfListLevel.LIST_TYPE_UPPER_LETTERS:
result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getUpperCaseString(itemNr)));
break;
case RtfListLevel.LIST_TYPE_LOWER_LETTERS:
result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getLowerCaseString(itemNr)));
break;
case RtfListLevel.LIST_TYPE_UPPER_ROMAN:
result.write(DocWriter.getISOBytes(RomanNumberFactory.getUpperCaseString(itemNr)));
break;
case RtfListLevel.LIST_TYPE_LOWER_ROMAN:
result.write(DocWriter.getISOBytes(RomanNumberFactory.getLowerCaseString(itemNr)));
break;
}
result.write(LIST_NUMBER_END);
} else {
this.document.filterSpecialChar(result, listLevel.getBulletCharacter(), true, false);
}
result.write(TAB);
result.write(CLOSE_GROUP);
}
/**
* Writes only the list number and list level number.
*
* @param result The OutputStream
to write to
* @throws IOException On i/o errors.
* @since 2.1.3
*/
protected void writeListNumbers(OutputStream result) throws IOException {
result.write(LIST_NUMBER);
result.write(intToByteArray(listNumber));
}
/**
* Create a default set of listlevels
*
* @since 2.1.3
*/
protected void createDefaultLevels() {
for (int i = 0; i <= 8; i++) {
// create a list level
RtfListLevel ll = new RtfListLevel(this.document);
ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED);
ll.setFirstIndent(0);
ll.setLeftIndent(0);
ll.setLevelTextNumber(i);
ll.setTentative(true);
ll.correctIndentation();
this.listLevels.add(ll);
}
}
/**
* Gets the id of this list
*
* @return Returns the list number.
* @since 2.1.3
*/
public int getListNumber() {
return listNumber;
}
/**
* Sets the id of this list
*
* @param listNumber The list number to set.
* @since 2.1.3
*/
public void setListNumber(int listNumber) {
this.listNumber = listNumber;
}
/**
* Sets whether this RtfList is in a table. Sets the correct inTable setting for all
* child elements.
*
* @param inTable True
if this RtfList is in a table, false
otherwise
* @since 2.1.3
*/
@Override
public void setInTable(boolean inTable) {
super.setInTable(inTable);
for (RtfBasicElement item : this.items) {
item.setInTable(inTable);
}
for (RtfListLevel listLevel : this.listLevels) {
listLevel.setInTable(inTable);
}
}
/**
* Sets whether this RtfList is in a header. Sets the correct inTable setting for all
* child elements.
*
* @param inHeader True
if this RtfList is in a header, false
otherwise
* @since 2.1.3
*/
@Override
public void setInHeader(boolean inHeader) {
super.setInHeader(inHeader);
for (RtfBasicElement item : this.items) {
item.setInHeader(inHeader);
}
}
/**
* Correct the indentation of this RtfList by adding left/first line indentation
* from the parent RtfList. Also calls correctIndentation on all child RtfLists.
*
* @since 2.1.3
*/
protected void correctIndentation() {
// TODO: Fix
// if(this.parentList != null) {
// this.leftIndent = this.leftIndent + this.parentList.getLeftIndent() + this.parentList.getFirstIndent();
// }
for (RtfBasicElement item : this.items) {
if (item instanceof RtfList) {
((RtfList) item).correctIndentation();
} else if (item instanceof RtfListItem) {
((RtfListItem) item).correctIndentation();
}
}
}
/**
* Set the list ID number
*
* @param id
* @since 2.1.3
*/
public void setID(int id) {
this.listID = id;
}
/**
* Get the list ID number
*
* @return this list id
* @since 2.1.3
*/
public int getID() {
return this.listID;
}
/**
* @return the listType
* @see RtfList#LIST_TYPE_NORMAL
* @see RtfList#LIST_TYPE_SIMPLE
* @see RtfList#LIST_TYPE_HYBRID
* @since 2.1.3
*/
public int getListType() {
return listType;
}
/**
* @param listType the listType to set
* @see RtfList#LIST_TYPE_NORMAL
* @see RtfList#LIST_TYPE_SIMPLE
* @see RtfList#LIST_TYPE_HYBRID
* @since 2.1.3
*/
public void setListType(int listType) throws InvalidParameterException {
if (listType == LIST_TYPE_NORMAL ||
listType == LIST_TYPE_SIMPLE ||
listType == LIST_TYPE_HYBRID) {
this.listType = listType;
} else {
throw new InvalidParameterException("Invalid listType value.");
}
}
/**
* @return the parentList
* @since 2.1.3
*/
public RtfList getParentList() {
return parentList;
}
/**
* @param parentList the parentList to set
* @since 2.1.3
*/
public void setParentList(RtfList parentList) {
this.parentList = parentList;
}
/**
* @return the name
* @since 2.1.3
*/
public String getName() {
return name;
}
/**
* @param name the name to set
* @since 2.1.3
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the list at the index
* @since 2.1.3
*/
public RtfListLevel getListLevel(int index) {
return this.listLevels.get(index);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy