import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.poi.hwpf.HWPFDocumentCore;
import org.apache.poi.hwpf.HWPFOldDocument;
import org.apache.poi.hwpf.OldWordFileFormatException;
-import org.apache.poi.hwpf.model.ListLevel;
-import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.usermodel.BorderCode;
-import org.apache.poi.hwpf.usermodel.Paragraph;
+import org.apache.poi.hwpf.usermodel.HWPFList;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableRow;
return stringBuilder.toString();
}
- public static String getBulletText( ListTables listTables,
- Paragraph paragraph, int listId )
+ public static class NumberingState {
+
+ private final Map<String, Integer> levels = new HashMap<String, Integer>();
+
+ }
+
+ public static String getBulletText(NumberingState numberingState, HWPFList list, char level )
{
- final ListLevel listLevel = listTables.getLevel( listId,
- paragraph.getIlvl() );
-
- if ( listLevel==null || listLevel.getNumberText() == null )
- return EMPTY;
-
StringBuffer bulletBuffer = new StringBuffer();
- char[] xst = listLevel.getNumberText().toCharArray();
+ char[] xst = list.getNumberText( level ).toCharArray();
for ( char element : xst )
{
if ( element < 9 )
{
- ListLevel numLevel = listTables.getLevel( listId, element );
+ final String key = list.getLsid() + "#" + ( (int) element );
+ int num;
+ if ( numberingState.levels.containsKey( key ) )
+ {
+ num = numberingState.levels.get( key ).intValue();
+ }
+ else
+ {
+ num = list.getStartAt( level );
+ numberingState.levels.put( key, Integer.valueOf( num ) );
+ }
- int num = numLevel.getStartAt();
bulletBuffer.append( NumberFormatter.getNumber( num,
- listLevel.getNumberFormat() ) );
+ list.getNumberFormat( level ) ) );
- if ( numLevel == listLevel )
+ if ( level == element )
{
- numLevel.setStartAt( numLevel.getStartAt() + 1 );
+ numberingState.levels.put( key, Integer.valueOf( num + 1 ) );
}
-
}
else
{
}
}
- byte follow = listLevel.getTypeOfCharFollowingTheNumber();
+ byte follow = list.getTypeOfCharFollowingTheNumber(level);
switch ( follow )
{
case 0:
public static final int ROUTESLIP = 70;
public static final int STTBSAVEDBY = 71;
public static final int STTBFNM = 72;
- public static final int PLCFLST = 73;
+ public static final int PLFLST = 73;
+ @Deprecated
+ public static final int PLCFLST = PLFLST;
public static final int PLFLFO = 74;
public static final int PLCFTXBXBKD = 75;//validated
public static final int PLCFTXBXHDRBKD = 76;
knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLCFBTECHPX ) );
knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLCFBTEPAPX ) );
knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLCFSED ) );
- knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLCFLST ) );
+ knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLFLST ) );
knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLFLFO ) );
// field info
_fieldHandler.setFieldSize(FIBFieldHandler.PLCFSED, lcbPlcfSed);
}
+ @Deprecated
public int getFcPlcfLst()
{
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFLST);
}
+ /**
+ * An unsigned integer that specifies an offset in the Table Stream. A
+ * PlfLst that contains list formatting information begins at this offset.
+ * An array of LVLs is appended to the PlfLst. lcbPlfLst does not account
+ * for the array of LVLs. The size of the array of LVLs is specified by the
+ * LSTFs in PlfLst. For each LSTF whose fSimpleList is set to 0x1, there is
+ * one LVL in the array of LVLs that specifies the level formatting of the
+ * single level in the list which corresponds to the LSTF. And, for each
+ * LSTF whose fSimpleList is set to 0x0, there are 9 LVLs in the array of
+ * LVLs that specify the level formatting of the respective levels in the
+ * list which corresponds to the LSTF. This array of LVLs is in the same
+ * respective order as the LSTFs in PlfLst. If lcbPlfLst is 0, fcPlfLst is
+ * undefined and MUST be ignored.
+ * <p>
+ * Quote from
+ * "[MS-DOC] -- v20110315, Word (.doc) Binary File Format; page 76 / 621"
+ */
+ public int getFcPlfLst()
+ {
+ return _fieldHandler.getFieldOffset( FIBFieldHandler.PLFLST );
+ }
+
+ @Deprecated
public int getLcbPlcfLst()
{
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFLST);
}
- public void setFcPlcfLst(int fcPlcfLst)
+ public int getLcbPlfLst()
+ {
+ return _fieldHandler.getFieldSize( FIBFieldHandler.PLFLST );
+ }
+
+ @Deprecated
+ public void setFcPlcfLst( int fcPlcfLst )
{
- _fieldHandler.setFieldOffset(FIBFieldHandler.PLCFLST, fcPlcfLst);
+ _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFLST, fcPlcfLst );
}
- public void setLcbPlcfLst(int lcbPlcfLst)
+ public void setFcPlfLst( int fcPlfLst )
{
- _fieldHandler.setFieldSize(FIBFieldHandler.PLCFLST, lcbPlcfLst);
+ _fieldHandler.setFieldOffset( FIBFieldHandler.PLFLST, fcPlfLst );
}
+ @Deprecated
+ public void setLcbPlcfLst( int lcbPlcfLst )
+ {
+ _fieldHandler.setFieldSize( FIBFieldHandler.PLCFLST, lcbPlcfLst );
+ }
+
+ public void setLcbPlfLst( int lcbPlfLst )
+ {
+ _fieldHandler.setFieldSize( FIBFieldHandler.PLFLST, lcbPlfLst );
+ }
+
+ /**
+ * An unsigned integer that specifies an offset in the Table Stream. A
+ * PlfLfo that contains list formatting override information begins at this
+ * offset. If lcbPlfLfo is zero, fcPlfLfo is undefined and MUST be ignored.
+ * <p>
+ * Quote from
+ * "[MS-DOC] -- v20110315, Word (.doc) Binary File Format; page 76 / 621"
+ */
public int getFcPlfLfo()
{
- return _fieldHandler.getFieldOffset(FIBFieldHandler.PLFLFO);
+ return _fieldHandler.getFieldOffset( FIBFieldHandler.PLFLFO );
}
public int getLcbPlfLfo()
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
*/
@Internal
-class LFO extends LFOAbstractType
+public class LFO extends LFOAbstractType
{
public LFO()
{
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hwpf.model;
-
-import org.apache.poi.util.Internal;
-
-@Internal
-public final class ListFormatOverride
-{
- private LFO _lfo;
-
- private LFOData _lfoData;
-
- public ListFormatOverride( byte[] buf, int offset )
- {
- _lfo = new LFO( buf, offset );
- }
-
- public ListFormatOverride( int lsid )
- {
- _lfo = new LFO();
- _lfo.setLsid( lsid );
- }
-
- public ListFormatOverrideLevel[] getLevelOverrides()
- {
- return _lfoData.getRgLfoLvl();
- }
-
- LFO getLfo()
- {
- return _lfo;
- }
-
- LFOData getLfoData()
- {
- return _lfoData;
- }
-
- public int getLsid()
- {
- return _lfo.getLsid();
- }
-
- public ListFormatOverrideLevel getOverrideLevel( int level )
- {
- ListFormatOverrideLevel retLevel = null;
- for ( int x = 0; x < getLevelOverrides().length; x++ )
- {
- if ( getLevelOverrides()[x].getLevelNum() == level )
- {
- retLevel = getLevelOverrides()[x];
- }
- }
- return retLevel;
- }
-
- public int numOverrides()
- {
- return _lfo.getClfolvl();
- }
-
- void setLfoData( LFOData _lfoData )
- {
- this._lfoData = _lfoData;
- }
-
- public void setLsid( int lsid )
- {
- _lfo.setLsid( lsid );
- }
-
- public void setOverride( int index, ListFormatOverrideLevel lfolvl )
- {
- getLevelOverrides()[index] = lfolvl;
- }
-
- public byte[] toByteArray()
- {
- return _lfo.serialize();
- }
-}
import org.apache.poi.util.LittleEndian;\r
\r
/**\r
- * List Format Override (LFO). <p>Class and fields descriptions are quoted from\r
- Microsoft Office Word 97-2007 Binary File Format\r
- \r
+ * List Format Override (LFO).\r
* <p>\r
- * NOTE: This source is automatically generated please do not modify this file. Either subclass or\r
- * remove the record in src/types/definitions.\r
+ * Class and fields descriptions are quoted from [MS-DOC] --v20110315; Word\r
+ * (.doc) Binary File Format\r
+ * \r
* <p>\r
- * This class is internal. It content or properties may change without notice \r
+ * NOTE: This source is automatically generated please do not modify this file.\r
+ * Either subclass or remove the record in src/types/definitions.\r
+ * <p>\r
+ * This class is internal. It content or properties may change without notice\r
* due to changes in our knowledge of internal Microsoft Word binary structures.\r
-\r
- * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format\r
- Specification [*.doc]\r
- \r
+ * \r
+ * @author Sergey Vladimirov; according to [MS-DOC] --v20110315; Word (.doc)\r
+ * Binary File Format; Copyright (c) Microsoft Corporation\r
*/\r
@Internal\r
public abstract class LFOAbstractType\r
{\r
\r
protected int field_1_lsid;\r
- protected int field_2_reserved1;\r
- protected int field_3_reserved2;\r
+ protected int field_2_unused1;\r
+ protected int field_3_unused2;\r
protected byte field_4_clfolvl;\r
protected byte field_5_ibstFltAutoNum;\r
protected Grfhic field_6_grfhic;\r
- protected byte field_7_reserved3;\r
+ protected byte field_7_unused3;\r
\r
protected LFOAbstractType()\r
{\r
\r
protected void fillFields( byte[] data, int offset )\r
{\r
- field_1_lsid = LittleEndian.getInt( data, 0x0 + offset );\r
- field_2_reserved1 = LittleEndian.getInt( data, 0x4 + offset );\r
- field_3_reserved2 = LittleEndian.getInt( data, 0x8 + offset );\r
- field_4_clfolvl = data[ 0xc + offset ];\r
- field_5_ibstFltAutoNum = data[ 0xd + offset ];\r
- field_6_grfhic = new Grfhic( data, 0xe + offset );\r
- field_7_reserved3 = data[ 0xf + offset ];\r
+ field_1_lsid = LittleEndian.getInt( data, 0x0 + offset );\r
+ field_2_unused1 = LittleEndian.getInt( data, 0x4 + offset );\r
+ field_3_unused2 = LittleEndian.getInt( data, 0x8 + offset );\r
+ field_4_clfolvl = data[0xc + offset];\r
+ field_5_ibstFltAutoNum = data[0xd + offset];\r
+ field_6_grfhic = new Grfhic( data, 0xe + offset );\r
+ field_7_unused3 = data[0xf + offset];\r
}\r
\r
public void serialize( byte[] data, int offset )\r
{\r
LittleEndian.putInt( data, 0x0 + offset, field_1_lsid );\r
- LittleEndian.putInt( data, 0x4 + offset, field_2_reserved1 );\r
- LittleEndian.putInt( data, 0x8 + offset, field_3_reserved2 );\r
- data[ 0xc + offset ] = field_4_clfolvl;\r
- data[ 0xd + offset ] = field_5_ibstFltAutoNum;\r
+ LittleEndian.putInt( data, 0x4 + offset, field_2_unused1 );\r
+ LittleEndian.putInt( data, 0x8 + offset, field_3_unused2 );\r
+ data[0xc + offset] = field_4_clfolvl;\r
+ data[0xd + offset] = field_5_ibstFltAutoNum;\r
field_6_grfhic.serialize( data, 0xe + offset );\r
- data[ 0xf + offset ] = field_7_reserved3;\r
+ data[0xf + offset] = field_7_unused3;\r
}\r
\r
public byte[] serialize()\r
{\r
- final byte[] result = new byte[ getSize() ];\r
+ final byte[] result = new byte[getSize()];\r
serialize( result, 0 );\r
return result;\r
}\r
LFOAbstractType other = (LFOAbstractType) obj;\r
if ( field_1_lsid != other.field_1_lsid )\r
return false;\r
- if ( field_2_reserved1 != other.field_2_reserved1 )\r
+ if ( field_2_unused1 != other.field_2_unused1 )\r
return false;\r
- if ( field_3_reserved2 != other.field_3_reserved2 )\r
+ if ( field_3_unused2 != other.field_3_unused2 )\r
return false;\r
if ( field_4_clfolvl != other.field_4_clfolvl )\r
return false;\r
}\r
else if ( !field_6_grfhic.equals( other.field_6_grfhic ) )\r
return false;\r
- if ( field_7_reserved3 != other.field_7_reserved3 )\r
+ if ( field_7_unused3 != other.field_7_unused3 )\r
return false;\r
return true;\r
}\r
final int prime = 31;\r
int result = 1;\r
result = prime * result + field_1_lsid;\r
- result = prime * result + field_2_reserved1;\r
- result = prime * result + field_3_reserved2;\r
+ result = prime * result + field_2_unused1;\r
+ result = prime * result + field_3_unused2;\r
result = prime * result + field_4_clfolvl;\r
result = prime * result + field_5_ibstFltAutoNum;\r
result = prime * result + field_6_grfhic.hashCode();\r
- result = prime * result + field_7_reserved3;\r
+ result = prime * result + field_7_unused3;\r
return result;\r
}\r
\r
public String toString()\r
{\r
StringBuilder builder = new StringBuilder();\r
- builder.append("[LFO]\n");\r
- builder.append(" .lsid = ");\r
- builder.append(" (").append(getLsid()).append(" )\n");\r
- builder.append(" .reserved1 = ");\r
- builder.append(" (").append(getReserved1()).append(" )\n");\r
- builder.append(" .reserved2 = ");\r
- builder.append(" (").append(getReserved2()).append(" )\n");\r
- builder.append(" .clfolvl = ");\r
- builder.append(" (").append(getClfolvl()).append(" )\n");\r
- builder.append(" .ibstFltAutoNum = ");\r
- builder.append(" (").append(getIbstFltAutoNum()).append(" )\n");\r
- builder.append(" .grfhic = ");\r
- builder.append(" (").append(getGrfhic()).append(" )\n");\r
- builder.append(" .reserved3 = ");\r
- builder.append(" (").append(getReserved3()).append(" )\n");\r
+ builder.append( "[LFO]\n" );\r
+ builder.append( " .lsid = " );\r
+ builder.append( " (" ).append( getLsid() ).append( " )\n" );\r
+ builder.append( " .unused1 = " );\r
+ builder.append( " (" ).append( getUnused1() ).append( " )\n" );\r
+ builder.append( " .unused2 = " );\r
+ builder.append( " (" ).append( getUnused2() ).append( " )\n" );\r
+ builder.append( " .clfolvl = " );\r
+ builder.append( " (" ).append( getClfolvl() ).append( " )\n" );\r
+ builder.append( " .ibstFltAutoNum = " );\r
+ builder.append( " (" ).append( getIbstFltAutoNum() ).append( " )\n" );\r
+ builder.append( " .grfhic = " );\r
+ builder.append( " (" ).append( getGrfhic() ).append( " )\n" );\r
+ builder.append( " .unused3 = " );\r
+ builder.append( " (" ).append( getUnused3() ).append( " )\n" );\r
\r
- builder.append("[/LFO]\n");\r
+ builder.append( "[/LFO]\n" );\r
return builder.toString();\r
}\r
\r
/**\r
- * List ID of corresponding LSTF (see LSTF).\r
+ * A signed integer that specifies the list identifier of an LSTF. This LFO\r
+ * corresponds to the LSTF in PlfLst.rgLstf that has an lsid whose value is\r
+ * equal to this value..\r
*/\r
@Internal\r
public int getLsid()\r
}\r
\r
/**\r
- * List ID of corresponding LSTF (see LSTF).\r
+ * A signed integer that specifies the list identifier of an LSTF. This LFO\r
+ * corresponds to the LSTF in PlfLst.rgLstf that has an lsid whose value is\r
+ * equal to this value..\r
*/\r
@Internal\r
public void setLsid( int field_1_lsid )\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public int getReserved1()\r
+ public int getUnused1()\r
{\r
- return field_2_reserved1;\r
+ return field_2_unused1;\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public void setReserved1( int field_2_reserved1 )\r
+ public void setUnused1( int field_2_unused1 )\r
{\r
- this.field_2_reserved1 = field_2_reserved1;\r
+ this.field_2_unused1 = field_2_unused1;\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public int getReserved2()\r
+ public int getUnused2()\r
{\r
- return field_3_reserved2;\r
+ return field_3_unused2;\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public void setReserved2( int field_3_reserved2 )\r
+ public void setUnused2( int field_3_unused2 )\r
{\r
- this.field_3_reserved2 = field_3_reserved2;\r
+ this.field_3_unused2 = field_3_unused2;\r
}\r
\r
/**\r
- * Count of levels whose format is overridden (see LFOLVL).\r
+ * An unsigned integer that specifies the field that this LFO represents..\r
*/\r
@Internal\r
public byte getClfolvl()\r
}\r
\r
/**\r
- * Count of levels whose format is overridden (see LFOLVL).\r
+ * An unsigned integer that specifies the field that this LFO represents..\r
*/\r
@Internal\r
public void setClfolvl( byte field_4_clfolvl )\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public byte getReserved3()\r
+ public byte getUnused3()\r
{\r
- return field_7_reserved3;\r
+ return field_7_unused3;\r
}\r
\r
/**\r
- * Reserved.\r
+ * This field MUST be ignored.\r
*/\r
@Internal\r
- public void setReserved3( byte field_7_reserved3 )\r
+ public void setUnused3( byte field_7_unused3 )\r
{\r
- this.field_7_reserved3 = field_7_reserved3;\r
+ this.field_7_unused3 = field_7_unused3;\r
}\r
\r
-} // END OF CLASS\r
+} // END OF CLASS\r
package org.apache.poi.hwpf.usermodel;
-import org.apache.poi.hwpf.model.ListLevel;
+import org.apache.poi.util.POILogFactory;
+
+import org.apache.poi.util.POILogger;
+
+import org.apache.poi.hwpf.model.ListTables;
+
+import org.apache.poi.util.Internal;
+
+import org.apache.poi.hwpf.model.LFO;
+import org.apache.poi.hwpf.model.LFOData;
import org.apache.poi.hwpf.model.ListData;
-import org.apache.poi.hwpf.model.ListFormatOverride;
+import org.apache.poi.hwpf.model.ListLevel;
import org.apache.poi.hwpf.model.StyleSheet;
-
import org.apache.poi.hwpf.sprm.CharacterSprmCompressor;
import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor;
/**
* This class is used to create a list in a Word document. It is used in
- * conjunction with {@link
- * org.apache.poi.hwpf.HWPFDocument#registerList(HWPFList) registerList} in
- * {@link org.apache.poi.hwpf.HWPFDocument HWPFDocument}.
- *
- * In Word, lists are not ranged entities, meaning you can't actually add one
- * to the document. Lists only act as properties for list entries. Once you
+ * conjunction with
+ * {@link org.apache.poi.hwpf.HWPFDocument#registerList(HWPFList) registerList}
+ * in {@link org.apache.poi.hwpf.HWPFDocument HWPFDocument}.
+ *
+ * In Word, lists are not ranged entities, meaning you can't actually add one to
+ * the document. Lists only act as properties for list entries. Once you
* register a list, you can add list entries to a document that are a part of
* the list.
- *
+ *
* The only benefit of this that I see, is that you can add a list entry
* anywhere in the document and continue numbering from the previous list.
- *
+ *
* @author Ryan Ackley
*/
-public final class HWPFList {
- private ListData _listData;
- private ListFormatOverride _override;
- private boolean _registered;
- private StyleSheet _styleSheet;
-
- /**
- *
- * @param numbered true if the list should be numbered; false if it should be
- * bulleted.
- * @param styleSheet The document's stylesheet.
- */
- public HWPFList(boolean numbered, StyleSheet styleSheet)
- {
- _listData = new ListData((int)(Math.random() * System.currentTimeMillis()), numbered);
- _override = new ListFormatOverride(_listData.getLsid());
- _styleSheet = styleSheet;
- }
-
- /**
- * Sets the character properties of the list numbers.
- *
- * @param level the level number that the properties should apply to.
- * @param chp The character properties.
- */
- public void setLevelNumberProperties(int level, CharacterProperties chp)
- {
- ListLevel listLevel = _listData.getLevel(level);
- int styleIndex = _listData.getLevelStyle(level);
- CharacterProperties base = _styleSheet.getCharacterStyle(styleIndex);
-
- byte[] grpprl = CharacterSprmCompressor.compressCharacterProperty(chp, base);
- listLevel.setNumberProperties(grpprl);
- }
-
- /**
- * Sets the paragraph properties for a particular level of the list.
- *
- * @param level The level number.
- * @param pap The paragraph properties
- */
- public void setLevelParagraphProperties(int level, ParagraphProperties pap)
- {
- ListLevel listLevel = _listData.getLevel(level);
- int styleIndex = _listData.getLevelStyle(level);
- ParagraphProperties base = _styleSheet.getParagraphStyle(styleIndex);
-
- byte[] grpprl = ParagraphSprmCompressor.compressParagraphProperty(pap, base);
- listLevel.setLevelProperties(grpprl);
- }
-
- public void setLevelStyle(int level, int styleIndex)
- {
- _listData.setLevelStyle(level, styleIndex);
- }
-
- public ListData getListData()
- {
- return _listData;
- }
-
- public ListFormatOverride getOverride()
- {
- return _override;
- }
+public final class HWPFList
+{
+ private static POILogger log = POILogFactory.getLogger( HWPFList.class );
+
+ private boolean _ignoreLogicalLeftIdentation = false;
+ private LFO _lfo;
+ private LFOData _lfoData;
+ private ListData _listData;
+ private ListTables _listTables;
+ private boolean _registered;
+ private StyleSheet _styleSheet;
+
+ /**
+ *
+ * @param numbered
+ * true if the list should be numbered; false if it should be
+ * bulleted.
+ * @param styleSheet
+ * The document's stylesheet.
+ */
+ public HWPFList( boolean numbered, StyleSheet styleSheet )
+ {
+ _listData = new ListData(
+ (int) ( Math.random() * System.currentTimeMillis() ), numbered );
+ _lfo = new LFO();
+ _lfo.setLsid( _listData.getLsid() );
+ _lfoData = new LFOData();
+ _styleSheet = styleSheet;
+ }
+
+ public HWPFList( StyleSheet styleSheet, ListTables listTables, int ilfo )
+ {
+ _listTables = listTables;
+ _styleSheet = styleSheet;
+ _registered = true;
+
+ /* See documentation for sprmPIlfo (0x460B) */
+ if ( ilfo == 0 || ilfo == 0xF801 )
+ {
+ throw new IllegalArgumentException( "Paragraph not in list" );
+ }
+ else if ( 0x0001 <= ilfo && ilfo <= 0x07FE )
+ {
+ _lfo = listTables.getLfo( ilfo );
+ _lfoData = listTables.getLfoData( ilfo );
+ }
+ else if ( 0xF802 <= ilfo && ilfo <= 0xFFFF )
+ {
+ int nilfo = ilfo ^ 0xFFFF;
+ _lfo = listTables.getLfo( nilfo );
+ _lfoData = listTables.getLfoData( nilfo );
+ _ignoreLogicalLeftIdentation = true;
+ }
+ else
+ {
+ throw new IllegalArgumentException( "Incorrect ilfo: " + ilfo );
+ }
+
+ _listData = listTables.getListData( _lfo.getLsid() );
+ }
+
+ @Internal
+ public LFO getLFO()
+ {
+ return _lfo;
+ }
+
+ @Internal
+ public LFOData getLFOData()
+ {
+ return _lfoData;
+ }
+
+ @Internal
+ public ListData getListData()
+ {
+ return _listData;
+ }
+
+ public int getLsid()
+ {
+ return _lfo.getLsid();
+ }
+
+ @Internal
+ ListLevel getLVL( char level )
+ {
+ if ( level >= _listData.numLevels() )
+ {
+ throw new IllegalArgumentException( "Required level "
+ + ( (int) level )
+ + " is more than number of level for list ("
+ + _listData.numLevels() + ")" );
+ }
+ ListLevel lvl = _listData.getLevels()[level];
+ return lvl;
+ }
+
+ /**
+ * An MSONFC, as specified in [MS-OSHARED] section 2.2.1.3, that specifies
+ * the format of the level numbers that replace the placeholders for this
+ * level in the xst fields of the LVLs in this list. This value MUST not be
+ * equal to 0x08, 0x09, 0x0F, or 0x13. If this is equal to 0xFF or 0x17,
+ * this level does not have a number sequence and therefore has no number
+ * formatting. If this is equal to 0x17, the level uses bullets.
+ */
+ public int getNumberFormat( char level )
+ {
+ return getLVL( level ).getNumberFormat();
+ }
+
+ public String getNumberText( char level )
+ {
+ return getLVL( level ).getNumberText();
+ }
+
+ public int getStartAt( char level )
+ {
+ return getLVL( level ).getStartAt();
+ }
+
+ /**
+ * "The type of character following the number text for the paragraph: 0 == tab, 1 == space, 2 == nothing."
+ */
+ public byte getTypeOfCharFollowingTheNumber( char level )
+ {
+ return getLVL( level ).getTypeOfCharFollowingTheNumber();
+ }
+
+ public boolean isIgnoreLogicalLeftIdentation()
+ {
+ return _ignoreLogicalLeftIdentation;
+ }
+
+ public void setIgnoreLogicalLeftIdentation(
+ boolean ignoreLogicalLeftIdentation )
+ {
+ this._ignoreLogicalLeftIdentation = ignoreLogicalLeftIdentation;
+ }
+
+ /**
+ * Sets the character properties of the list numbers.
+ *
+ * @param level
+ * the level number that the properties should apply to.
+ * @param chp
+ * The character properties.
+ */
+ public void setLevelNumberProperties( int level, CharacterProperties chp )
+ {
+ ListLevel listLevel = _listData.getLevel( level );
+ int styleIndex = _listData.getLevelStyle( level );
+ CharacterProperties base = _styleSheet.getCharacterStyle( styleIndex );
+
+ byte[] grpprl = CharacterSprmCompressor.compressCharacterProperty( chp,
+ base );
+ listLevel.setNumberProperties( grpprl );
+ }
+
+ /**
+ * Sets the paragraph properties for a particular level of the list.
+ *
+ * @param level
+ * The level number.
+ * @param pap
+ * The paragraph properties
+ */
+ public void setLevelParagraphProperties( int level, ParagraphProperties pap )
+ {
+ ListLevel listLevel = _listData.getLevel( level );
+ int styleIndex = _listData.getLevelStyle( level );
+ ParagraphProperties base = _styleSheet.getParagraphStyle( styleIndex );
+
+ byte[] grpprl = ParagraphSprmCompressor.compressParagraphProperty( pap,
+ base );
+ listLevel.setLevelProperties( grpprl );
+ }
+ public void setLevelStyle( int level, int styleIndex )
+ {
+ _listData.setLevelStyle( level, styleIndex );
+ }
}