git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1389038 13f79535-47bb-0310-9956-ffa450edef68tags/3.10-beta1
@@ -20,6 +20,8 @@ import java.io.File; | |||
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; | |||
@@ -27,10 +29,8 @@ import org.apache.poi.hwpf.HWPFDocument; | |||
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; | |||
@@ -226,32 +226,39 @@ public class AbstractWordUtils | |||
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 | |||
{ | |||
@@ -259,7 +266,7 @@ public class AbstractWordUtils | |||
} | |||
} | |||
byte follow = listLevel.getTypeOfCharFollowingTheNumber(); | |||
byte follow = list.getTypeOfCharFollowingTheNumber(level); | |||
switch ( follow ) | |||
{ | |||
case 0: |
@@ -120,7 +120,9 @@ public final class FIBFieldHandler | |||
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; |
@@ -229,7 +229,7 @@ public final class FileInformationBlock implements Cloneable | |||
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 | |||
@@ -457,29 +457,78 @@ public final class FileInformationBlock implements Cloneable | |||
_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() |
@@ -29,7 +29,7 @@ import org.apache.poi.hwpf.model.types.LFOAbstractType; | |||
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) | |||
*/ | |||
@Internal | |||
class LFO extends LFOAbstractType | |||
public class LFO extends LFOAbstractType | |||
{ | |||
public LFO() | |||
{ |
@@ -1,97 +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.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(); | |||
} | |||
} |
@@ -21,31 +21,32 @@ import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.LittleEndian; | |||
/** | |||
* List Format Override (LFO). <p>Class and fields descriptions are quoted from | |||
Microsoft Office Word 97-2007 Binary File Format | |||
* List Format Override (LFO). | |||
* <p> | |||
* NOTE: This source is automatically generated please do not modify this file. Either subclass or | |||
* remove the record in src/types/definitions. | |||
* Class and fields descriptions are quoted from [MS-DOC] --v20110315; Word | |||
* (.doc) Binary File Format | |||
* | |||
* <p> | |||
* This class is internal. It content or properties may change without notice | |||
* NOTE: This source is automatically generated please do not modify this file. | |||
* Either subclass or remove the record in src/types/definitions. | |||
* <p> | |||
* This class is internal. It content or properties may change without notice | |||
* due to changes in our knowledge of internal Microsoft Word binary structures. | |||
* @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format | |||
Specification [*.doc] | |||
* | |||
* @author Sergey Vladimirov; according to [MS-DOC] --v20110315; Word (.doc) | |||
* Binary File Format; Copyright (c) Microsoft Corporation | |||
*/ | |||
@Internal | |||
public abstract class LFOAbstractType | |||
{ | |||
protected int field_1_lsid; | |||
protected int field_2_reserved1; | |||
protected int field_3_reserved2; | |||
protected int field_2_unused1; | |||
protected int field_3_unused2; | |||
protected byte field_4_clfolvl; | |||
protected byte field_5_ibstFltAutoNum; | |||
protected Grfhic field_6_grfhic; | |||
protected byte field_7_reserved3; | |||
protected byte field_7_unused3; | |||
protected LFOAbstractType() | |||
{ | |||
@@ -54,29 +55,29 @@ public abstract class LFOAbstractType | |||
protected void fillFields( byte[] data, int offset ) | |||
{ | |||
field_1_lsid = LittleEndian.getInt( data, 0x0 + offset ); | |||
field_2_reserved1 = LittleEndian.getInt( data, 0x4 + offset ); | |||
field_3_reserved2 = LittleEndian.getInt( data, 0x8 + offset ); | |||
field_4_clfolvl = data[ 0xc + offset ]; | |||
field_5_ibstFltAutoNum = data[ 0xd + offset ]; | |||
field_6_grfhic = new Grfhic( data, 0xe + offset ); | |||
field_7_reserved3 = data[ 0xf + offset ]; | |||
field_1_lsid = LittleEndian.getInt( data, 0x0 + offset ); | |||
field_2_unused1 = LittleEndian.getInt( data, 0x4 + offset ); | |||
field_3_unused2 = LittleEndian.getInt( data, 0x8 + offset ); | |||
field_4_clfolvl = data[0xc + offset]; | |||
field_5_ibstFltAutoNum = data[0xd + offset]; | |||
field_6_grfhic = new Grfhic( data, 0xe + offset ); | |||
field_7_unused3 = data[0xf + offset]; | |||
} | |||
public void serialize( byte[] data, int offset ) | |||
{ | |||
LittleEndian.putInt( data, 0x0 + offset, field_1_lsid ); | |||
LittleEndian.putInt( data, 0x4 + offset, field_2_reserved1 ); | |||
LittleEndian.putInt( data, 0x8 + offset, field_3_reserved2 ); | |||
data[ 0xc + offset ] = field_4_clfolvl; | |||
data[ 0xd + offset ] = field_5_ibstFltAutoNum; | |||
LittleEndian.putInt( data, 0x4 + offset, field_2_unused1 ); | |||
LittleEndian.putInt( data, 0x8 + offset, field_3_unused2 ); | |||
data[0xc + offset] = field_4_clfolvl; | |||
data[0xd + offset] = field_5_ibstFltAutoNum; | |||
field_6_grfhic.serialize( data, 0xe + offset ); | |||
data[ 0xf + offset ] = field_7_reserved3; | |||
data[0xf + offset] = field_7_unused3; | |||
} | |||
public byte[] serialize() | |||
{ | |||
final byte[] result = new byte[ getSize() ]; | |||
final byte[] result = new byte[getSize()]; | |||
serialize( result, 0 ); | |||
return result; | |||
} | |||
@@ -101,9 +102,9 @@ public abstract class LFOAbstractType | |||
LFOAbstractType other = (LFOAbstractType) obj; | |||
if ( field_1_lsid != other.field_1_lsid ) | |||
return false; | |||
if ( field_2_reserved1 != other.field_2_reserved1 ) | |||
if ( field_2_unused1 != other.field_2_unused1 ) | |||
return false; | |||
if ( field_3_reserved2 != other.field_3_reserved2 ) | |||
if ( field_3_unused2 != other.field_3_unused2 ) | |||
return false; | |||
if ( field_4_clfolvl != other.field_4_clfolvl ) | |||
return false; | |||
@@ -116,7 +117,7 @@ public abstract class LFOAbstractType | |||
} | |||
else if ( !field_6_grfhic.equals( other.field_6_grfhic ) ) | |||
return false; | |||
if ( field_7_reserved3 != other.field_7_reserved3 ) | |||
if ( field_7_unused3 != other.field_7_unused3 ) | |||
return false; | |||
return true; | |||
} | |||
@@ -127,40 +128,42 @@ public abstract class LFOAbstractType | |||
final int prime = 31; | |||
int result = 1; | |||
result = prime * result + field_1_lsid; | |||
result = prime * result + field_2_reserved1; | |||
result = prime * result + field_3_reserved2; | |||
result = prime * result + field_2_unused1; | |||
result = prime * result + field_3_unused2; | |||
result = prime * result + field_4_clfolvl; | |||
result = prime * result + field_5_ibstFltAutoNum; | |||
result = prime * result + field_6_grfhic.hashCode(); | |||
result = prime * result + field_7_reserved3; | |||
result = prime * result + field_7_unused3; | |||
return result; | |||
} | |||
public String toString() | |||
{ | |||
StringBuilder builder = new StringBuilder(); | |||
builder.append("[LFO]\n"); | |||
builder.append(" .lsid = "); | |||
builder.append(" (").append(getLsid()).append(" )\n"); | |||
builder.append(" .reserved1 = "); | |||
builder.append(" (").append(getReserved1()).append(" )\n"); | |||
builder.append(" .reserved2 = "); | |||
builder.append(" (").append(getReserved2()).append(" )\n"); | |||
builder.append(" .clfolvl = "); | |||
builder.append(" (").append(getClfolvl()).append(" )\n"); | |||
builder.append(" .ibstFltAutoNum = "); | |||
builder.append(" (").append(getIbstFltAutoNum()).append(" )\n"); | |||
builder.append(" .grfhic = "); | |||
builder.append(" (").append(getGrfhic()).append(" )\n"); | |||
builder.append(" .reserved3 = "); | |||
builder.append(" (").append(getReserved3()).append(" )\n"); | |||
builder.append( "[LFO]\n" ); | |||
builder.append( " .lsid = " ); | |||
builder.append( " (" ).append( getLsid() ).append( " )\n" ); | |||
builder.append( " .unused1 = " ); | |||
builder.append( " (" ).append( getUnused1() ).append( " )\n" ); | |||
builder.append( " .unused2 = " ); | |||
builder.append( " (" ).append( getUnused2() ).append( " )\n" ); | |||
builder.append( " .clfolvl = " ); | |||
builder.append( " (" ).append( getClfolvl() ).append( " )\n" ); | |||
builder.append( " .ibstFltAutoNum = " ); | |||
builder.append( " (" ).append( getIbstFltAutoNum() ).append( " )\n" ); | |||
builder.append( " .grfhic = " ); | |||
builder.append( " (" ).append( getGrfhic() ).append( " )\n" ); | |||
builder.append( " .unused3 = " ); | |||
builder.append( " (" ).append( getUnused3() ).append( " )\n" ); | |||
builder.append("[/LFO]\n"); | |||
builder.append( "[/LFO]\n" ); | |||
return builder.toString(); | |||
} | |||
/** | |||
* List ID of corresponding LSTF (see LSTF). | |||
* A signed integer that specifies the list identifier of an LSTF. This LFO | |||
* corresponds to the LSTF in PlfLst.rgLstf that has an lsid whose value is | |||
* equal to this value.. | |||
*/ | |||
@Internal | |||
public int getLsid() | |||
@@ -169,7 +172,9 @@ public abstract class LFOAbstractType | |||
} | |||
/** | |||
* List ID of corresponding LSTF (see LSTF). | |||
* A signed integer that specifies the list identifier of an LSTF. This LFO | |||
* corresponds to the LSTF in PlfLst.rgLstf that has an lsid whose value is | |||
* equal to this value.. | |||
*/ | |||
@Internal | |||
public void setLsid( int field_1_lsid ) | |||
@@ -178,43 +183,43 @@ public abstract class LFOAbstractType | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public int getReserved1() | |||
public int getUnused1() | |||
{ | |||
return field_2_reserved1; | |||
return field_2_unused1; | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public void setReserved1( int field_2_reserved1 ) | |||
public void setUnused1( int field_2_unused1 ) | |||
{ | |||
this.field_2_reserved1 = field_2_reserved1; | |||
this.field_2_unused1 = field_2_unused1; | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public int getReserved2() | |||
public int getUnused2() | |||
{ | |||
return field_3_reserved2; | |||
return field_3_unused2; | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public void setReserved2( int field_3_reserved2 ) | |||
public void setUnused2( int field_3_unused2 ) | |||
{ | |||
this.field_3_reserved2 = field_3_reserved2; | |||
this.field_3_unused2 = field_3_unused2; | |||
} | |||
/** | |||
* Count of levels whose format is overridden (see LFOLVL). | |||
* An unsigned integer that specifies the field that this LFO represents.. | |||
*/ | |||
@Internal | |||
public byte getClfolvl() | |||
@@ -223,7 +228,7 @@ public abstract class LFOAbstractType | |||
} | |||
/** | |||
* Count of levels whose format is overridden (see LFOLVL). | |||
* An unsigned integer that specifies the field that this LFO represents.. | |||
*/ | |||
@Internal | |||
public void setClfolvl( byte field_4_clfolvl ) | |||
@@ -268,21 +273,21 @@ public abstract class LFOAbstractType | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public byte getReserved3() | |||
public byte getUnused3() | |||
{ | |||
return field_7_reserved3; | |||
return field_7_unused3; | |||
} | |||
/** | |||
* Reserved. | |||
* This field MUST be ignored. | |||
*/ | |||
@Internal | |||
public void setReserved3( byte field_7_reserved3 ) | |||
public void setUnused3( byte field_7_unused3 ) | |||
{ | |||
this.field_7_reserved3 = field_7_reserved3; | |||
this.field_7_unused3 = field_7_unused3; | |||
} | |||
} // END OF CLASS | |||
} // END OF CLASS |
@@ -17,94 +17,218 @@ | |||
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 ); | |||
} | |||
} |