diff --git a/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java b/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java index 7c5f3115ae..5c4c554e9c 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -31,8 +32,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.poi.hwpf.model.StyleDescription; - import org.apache.poi.POIDocument; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.HWPFDocumentCore; @@ -42,9 +41,13 @@ import org.apache.poi.hwpf.model.CHPX; import org.apache.poi.hwpf.model.FieldsDocumentPart; import org.apache.poi.hwpf.model.FileInformationBlock; import org.apache.poi.hwpf.model.GenericPropertyNode; +import org.apache.poi.hwpf.model.ListFormatOverride; +import org.apache.poi.hwpf.model.ListLevel; +import org.apache.poi.hwpf.model.ListTables; import org.apache.poi.hwpf.model.PAPFormattedDiskPage; import org.apache.poi.hwpf.model.PAPX; import org.apache.poi.hwpf.model.PlexOfCps; +import org.apache.poi.hwpf.model.StyleDescription; import org.apache.poi.hwpf.model.StyleSheet; import org.apache.poi.hwpf.model.TextPiece; import org.apache.poi.hwpf.sprm.SprmIterator; @@ -54,6 +57,7 @@ import org.apache.poi.hwpf.usermodel.Bookmarks; import org.apache.poi.hwpf.usermodel.Field; import org.apache.poi.hwpf.usermodel.OfficeDrawing; import org.apache.poi.hwpf.usermodel.Paragraph; +import org.apache.poi.hwpf.usermodel.ParagraphProperties; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.poifs.common.POIFSConstants; @@ -560,11 +564,7 @@ public final class HWPFLister { SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); - while ( sprmIt.hasNext() ) - { - SprmOperation sprm = sprmIt.next(); - System.out.println( "*** " + sprm.toString() ); - } + dumpSprms( sprmIt, "*** " ); } } @@ -578,31 +578,33 @@ public final class HWPFLister if ( papx != null && withSprms ) { SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); - while ( sprmIt.hasNext() ) - { - SprmOperation sprm = sprmIt.next(); - System.out.println( "*** " + sprm.toString() ); - } + dumpSprms( sprmIt, "*** " ); } } } + Method newParagraph = Paragraph.class.getDeclaredMethod( + "newParagraph", Range.class, PAPX.class ); + newParagraph.setAccessible( true ); + java.lang.reflect.Field _props = Paragraph.class + .getDeclaredField( "_props" ); + _props.setAccessible( true ); + for ( PAPX papx : _doc.getParagraphTable().getParagraphs() ) { System.out.println( papx ); if ( withProperties ) - System.out.println( papx.getParagraphProperties( _doc - .getStyleSheet() ) ); + { + Paragraph paragraph = (Paragraph) newParagraph.invoke( null, + _doc.getOverallRange(), papx ); + System.out.println( _props.get( paragraph ) ); + } if ( true ) { SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); - while ( sprmIt.hasNext() ) - { - SprmOperation sprm = sprmIt.next(); - System.out.println( "\t" + sprm.toString() ); - } + dumpSprms( sprmIt, "\t" ); } } } @@ -629,11 +631,7 @@ public final class HWPFLister SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); - while ( sprmIt.hasNext() ) - { - SprmOperation sprm = sprmIt.next(); - System.out.println( "** " + sprm.toString() ); - } + dumpSprms( sprmIt, "** " ); } } if ( !hasAssotiatedPapx ) @@ -645,6 +643,15 @@ public final class HWPFLister } } + protected void dumpSprms( SprmIterator sprmIt, String linePrefix ) + { + while ( sprmIt.hasNext() ) + { + SprmOperation sprm = sprmIt.next(); + System.out.println( linePrefix + sprm.toString() ); + } + } + public void dumpParagraphsDom( boolean withText ) { Range range = _doc.getOverallRange(); @@ -682,6 +689,8 @@ public final class HWPFLister return; } HWPFDocument hwpfDocument = (HWPFDocument) _doc; + ListTables listTables = hwpfDocument.getListTables(); + for ( int s = 0; s < hwpfDocument.getStyleSheet().numStyles(); s++ ) { StyleDescription styleDescription = hwpfDocument.getStyleSheet() @@ -692,8 +701,44 @@ public final class HWPFLister System.out.println( "=== Style #" + s + " '" + styleDescription.getName() + "' ===" ); System.out.println( styleDescription ); - System.out.println( "PAP:" + styleDescription.getPAP() ); - System.out.println( "CHP:" + styleDescription.getCHP() ); + + ParagraphProperties paragraph = styleDescription.getPAP(); + System.out.println( "PAP: " + paragraph ); + if ( paragraph != null ) + { + dumpParagraphLevels( listTables, paragraph ); + } + System.out.println( "CHP: " + styleDescription.getCHP() ); + } + } + + protected void dumpParagraphLevels( ListTables listTables, + ParagraphProperties paragraph ) + { + if ( paragraph.getIlfo() != 0 ) + { + final ListFormatOverride listFormatOverride = listTables + .getOverride( paragraph.getIlfo() ); + + System.out.println( "PAP's LFO: " + listFormatOverride ); + + final ListLevel listLevel = listTables.getLevel( + listFormatOverride.getLsid(), paragraph.getIlvl() ); + + System.out.println( "PAP's ListLevel: " + listLevel ); + if ( listLevel.getGrpprlPapx() != null ) + { + System.out.println( "PAP's ListLevel PAPX:" ); + dumpSprms( new SprmIterator( listLevel.getGrpprlPapx(), 0 ), + "* " ); + } + + if ( listLevel.getGrpprlPapx() != null ) + { + System.out.println( "PAP's ListLevel CHPX:" ); + dumpSprms( new SprmIterator( listLevel.getGrpprlChpx(), 0 ), + "* " ); + } } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/LFO.java b/src/scratchpad/src/org/apache/poi/hwpf/model/LFO.java new file mode 100644 index 0000000000..e561173c0b --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/LFO.java @@ -0,0 +1,85 @@ +/* ==================================================================== + 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; + +import org.apache.poi.hwpf.model.types.LFOAbstractType; + +/** + * "The LFO structure specifies the LSTF element that corresponds to a list that + * contains a paragraph. An LFO can also specify formatting information that + * overrides the LSTF element to which it corresponds." -- [MS-DOC] -- v20110315 + * Word (.doc) Binary File Format + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ +@Internal +class LFO extends LFOAbstractType +{ + + public LFO() + { + } + + public LFO( byte[] std, int offset ) + { + fillFields( std, offset ); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + return true; + if ( obj == null ) + return false; + if ( getClass() != obj.getClass() ) + return false; + LFO other = (LFO) obj; + if ( field_1_lsid != other.field_1_lsid ) + return false; + if ( field_2_reserved1 != other.field_2_reserved1 ) + return false; + if ( field_3_reserved2 != other.field_3_reserved2 ) + return false; + if ( field_4_clfolvl != other.field_4_clfolvl ) + return false; + if ( field_5_ibstFltAutoNum != other.field_5_ibstFltAutoNum ) + return false; + if ( field_6_grfhic != other.field_6_grfhic ) + return false; + if ( field_7_reserved3 != other.field_7_reserved3 ) + return false; + return true; + } + + @Override + public int hashCode() + { + 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_4_clfolvl; + result = prime * result + field_5_ibstFltAutoNum; + result = prime * result + field_6_grfhic; + result = prime * result + field_7_reserved3; + return result; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ListFormatOverride.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ListFormatOverride.java index 7cdf119b2c..2e1597c30a 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/ListFormatOverride.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ListFormatOverride.java @@ -17,24 +17,26 @@ package org.apache.poi.hwpf.model; -import org.apache.poi.hwpf.model.types.LFOAbstractType; import org.apache.poi.util.Internal; @Internal -public final class ListFormatOverride extends LFOAbstractType +public final class ListFormatOverride { + private ListFormatOverrideLevel[] _levelOverrides; + private LFO _lfo; + public ListFormatOverride( byte[] buf, int offset ) { - fillFields( buf, offset ); - - _levelOverrides = new ListFormatOverrideLevel[getClfolvl()]; + _lfo = new LFO( buf, offset ); + _levelOverrides = new ListFormatOverrideLevel[_lfo.getClfolvl()]; } public ListFormatOverride( int lsid ) { - setLsid( lsid ); + _lfo = new LFO(); + _lfo.setLsid( lsid ); _levelOverrides = new ListFormatOverrideLevel[0]; } @@ -43,6 +45,11 @@ public final class ListFormatOverride extends LFOAbstractType return _levelOverrides; } + public int getLsid() + { + return _lfo.getLsid(); + } + public ListFormatOverrideLevel getOverrideLevel( int level ) { @@ -60,7 +67,12 @@ public final class ListFormatOverride extends LFOAbstractType public int numOverrides() { - return getClfolvl(); + return _lfo.getClfolvl(); + } + + public void setLsid( int lsid ) + { + _lfo.setLsid( lsid ); } public void setOverride( int index, ListFormatOverrideLevel lfolvl ) @@ -70,8 +82,6 @@ public final class ListFormatOverride extends LFOAbstractType public byte[] toByteArray() { - byte[] bs = new byte[getSize()]; - serialize( bs, 0 ); - return bs; + return _lfo.serialize(); } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java index bae770dead..790de01e6d 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java @@ -31,34 +31,18 @@ import org.apache.poi.util.LittleEndian; * See page 170 for details. */ @Internal -public final class ListLevel +public final class ListLevel { -// private int _iStartAt; -// private byte _nfc; -// private byte _info; -// /* */private static BitField _jc; -// /* */private static BitField _fLegal; -// /* */private static BitField _fNoRestart; -// /* */private static BitField _fPrev; -// /* */private static BitField _fPrevSpace; -// /* */private static BitField _fWord6; -// private byte[] _rgbxchNums; -// private byte _ixchFollow; -// private int _dxaSpace; -// private int _dxaIndent; -// private int _cbGrpprlChpx; -// private int _cbGrpprlPapx; -// private short _reserved; - private LVLF _lvlf; - private byte[] _grpprlPapx; private byte[] _grpprlChpx; + private byte[] _grpprlPapx; + private LVLF _lvlf; private char[] _numberText = null; public ListLevel( final byte[] buf, final int originalOffset ) { int offset = originalOffset; - _lvlf = new LVLF(buf, offset); + _lvlf = new LVLF( buf, offset ); offset += LVLF.getSize(); _grpprlPapx = new byte[_lvlf.getCbGrpprlPapx()]; @@ -92,7 +76,7 @@ public final class ListLevel _grpprlPapx = new byte[0]; _grpprlChpx = new byte[0]; _numberText = new char[0]; - + if ( numbered ) { _lvlf.getRgbxchNums()[0] = 1; @@ -136,6 +120,16 @@ public final class ListLevel return _lvlf.getJc(); } + public byte[] getGrpprlChpx() + { + return _grpprlChpx; + } + + public byte[] getGrpprlPapx() + { + return _grpprlPapx; + } + public byte[] getLevelProperties() { return _grpprlPapx; @@ -245,4 +239,12 @@ public final class ListLevel return buf; } + @Override + public String toString() + { + return "ListLevel: " + ( "\n" + _lvlf ).replaceAll( "\n", "\n " ) + + "\n" + + ( "PAPX's grpprl: " + Arrays.toString( _grpprlPapx ) + "\n" ) + + ( "CHPX's grpprl: " + Arrays.toString( _grpprlChpx ) + "\n" ); + } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/PAPX.java b/src/scratchpad/src/org/apache/poi/hwpf/model/PAPX.java index 53c8d1fe5e..0f5e847dcc 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/PAPX.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/PAPX.java @@ -134,6 +134,8 @@ public final class PAPX extends BytePropertyNode { return (SprmBuffer)_buf; } + @Deprecated + @Internal public ParagraphProperties getParagraphProperties(StyleSheet ss) { if(ss == null) { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java index 565d71202c..636b743000 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java @@ -20,8 +20,6 @@ package org.apache.poi.hwpf.model; import java.io.UnsupportedEncodingException; import java.util.Arrays; -import org.apache.poi.hwpf.sprm.SprmIterator; - import org.apache.poi.hwpf.usermodel.CharacterProperties; import org.apache.poi.hwpf.usermodel.ParagraphProperties; import org.apache.poi.util.Internal; @@ -51,7 +49,9 @@ public final class StyleDescription implements HDFType UPX[] _upxs; String _name; + @Deprecated ParagraphProperties _pap; + @Deprecated CharacterProperties _chp; public StyleDescription() @@ -173,18 +173,22 @@ public final class StyleDescription implements HDFType return null; } } + @Deprecated public ParagraphProperties getPAP() { return _pap; } + @Deprecated public CharacterProperties getCHP() { return _chp; } + @Deprecated void setPAP(ParagraphProperties pap) { _pap = pap; } + @Deprecated void setCHP(CharacterProperties chp) { _chp = chp; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java index 6fbf298711..c6891a7e3d 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java @@ -47,9 +47,13 @@ public final class StyleSheet implements HDFType { private static final int SEP_TYPE = 4; private static final int TAP_TYPE = 5; + @Deprecated + private final static ParagraphProperties NIL_PAP = new ParagraphProperties(); + @Deprecated + private final static CharacterProperties NIL_CHP = new CharacterProperties(); - private final static ParagraphProperties NIL_PAP = new ParagraphProperties(); - private final static CharacterProperties NIL_CHP = new CharacterProperties(); + private final static byte[] NIL_CHPX = new byte[] {}; + private final static byte[] NIL_PAPX = new byte[] {0, 0}; /** * Size of the STSHI structure @@ -205,6 +209,7 @@ public final class StyleSheet implements HDFType { * @param istd The index of the StyleDescription to create the * ParagraphProperties from (and also place the finished PAP in) */ + @Deprecated private void createPap(int istd) { StyleDescription sd = _styleDescriptions[istd]; @@ -248,6 +253,7 @@ public final class StyleSheet implements HDFType { * @param istd The index of the StyleDescription to create the * CharacterProperties object from. */ + @Deprecated private void createChp(int istd) { StyleDescription sd = _styleDescriptions[istd]; @@ -292,48 +298,107 @@ public final class StyleSheet implements HDFType { return _styleDescriptions.length; } - /** - * Gets the StyleDescription at index x. - * - * @param x the index of the desired StyleDescription. - */ - public StyleDescription getStyleDescription(int x) - { - return _styleDescriptions[x]; - } - - public CharacterProperties getCharacterStyle(int x) - { - if (x == NIL_STYLE) + /** + * Gets the StyleDescription at index x. + * + * @param styleIndex + * the index of the desired StyleDescription. + */ + public StyleDescription getStyleDescription( int styleIndex ) { - return NIL_CHP; + return _styleDescriptions[styleIndex]; } - if (x>=_styleDescriptions.length) { - return NIL_CHP; + @Deprecated + public CharacterProperties getCharacterStyle( int styleIndex ) + { + if ( styleIndex == NIL_STYLE ) + { + return NIL_CHP; + } + + if ( styleIndex >= _styleDescriptions.length ) + { + return NIL_CHP; + } + + return ( _styleDescriptions[styleIndex] != null ? _styleDescriptions[styleIndex] + .getCHP() : NIL_CHP ); } - return (_styleDescriptions[x] != null ? _styleDescriptions[x].getCHP() : NIL_CHP); - } + @Deprecated + public ParagraphProperties getParagraphStyle( int styleIndex ) + { + if ( styleIndex == NIL_STYLE ) + { + return NIL_PAP; + } - public ParagraphProperties getParagraphStyle(int x) - { - if (x == NIL_STYLE) { - return NIL_PAP; + if ( styleIndex >= _styleDescriptions.length ) + { + return NIL_PAP; + } + + if ( _styleDescriptions[styleIndex] == null ) + { + return NIL_PAP; + } + + if ( _styleDescriptions[styleIndex].getPAP() == null ) + { + return NIL_PAP; + } + + return _styleDescriptions[styleIndex].getPAP(); } - if (x >= _styleDescriptions.length) { - return NIL_PAP; + public byte[] getCHPX( int styleIndex ) + { + if ( styleIndex == NIL_STYLE ) + { + return NIL_CHPX; + } + + if ( styleIndex >= _styleDescriptions.length ) + { + return NIL_CHPX; + } + + if ( _styleDescriptions[styleIndex] == null ) + { + return NIL_CHPX; + } + + if ( _styleDescriptions[styleIndex].getCHPX() == null ) + { + return NIL_CHPX; + } + + return _styleDescriptions[styleIndex].getCHPX(); } - if (_styleDescriptions[x]==null) { - return NIL_PAP; - } + public byte[] getPAPX( int styleIndex ) + { + if ( styleIndex == NIL_STYLE ) + { + return NIL_PAPX; + } - if (_styleDescriptions[x].getPAP()==null) { - return NIL_PAP; - } + if ( styleIndex >= _styleDescriptions.length ) + { + return NIL_PAPX; + } - return _styleDescriptions[x].getPAP(); - } + if ( _styleDescriptions[styleIndex] == null ) + { + return NIL_PAPX; + } + + if ( _styleDescriptions[styleIndex].getPAPX() == null ) + { + return NIL_PAPX; + } + + return _styleDescriptions[styleIndex].getPAPX(); + } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/types/LFOAbstractType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/types/LFOAbstractType.java index d3dca54fd0..88714972ca 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/types/LFOAbstractType.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/types/LFOAbstractType.java @@ -21,16 +21,19 @@ import org.apache.poi.util.Internal; import org.apache.poi.util.LittleEndian; /** - * List Format Override (LFO). + * List Format Override (LFO).

Class and fields descriptions are quoted from + Microsoft Office Word 97-2007 Binary File Format + *

- * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 - * Binary File Format - * - * NOTE: This source is automatically generated please do not modify this file. - * Either subclass or remove the record in src/types/definitions. - * - * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary - * File Format Specification [*.doc] + * NOTE: This source is automatically generated please do not modify this file. Either subclass or + * remove the record in src/types/definitions. + *

+ * 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] + */ @Internal public abstract class LFOAbstractType @@ -42,16 +45,14 @@ public abstract class LFOAbstractType protected byte field_4_clfolvl; protected byte field_5_ibstFltAutoNum; protected byte field_6_grfhic; - /**/private static BitField fHtmlChecked = new BitField( 0x01 ); - /**/private static BitField fHtmlUnsupported = new BitField( 0x02 ); - /**/private static BitField fHtmlListTextNotSharpDot = new BitField( 0x04 ); - /**/private static BitField fHtmlNotPeriod = new BitField( 0x08 ); - /**/private static BitField fHtmlFirstLineMismatch = new BitField( 0x10 ); - /**/private static BitField fHtmlTabLeftIndentMismatch = new BitField( - 0x20 ); - /**/private static BitField fHtmlHangingIndentBeneathNumber = new BitField( - 0x40 ); - /**/private static BitField fHtmlBuiltInBullet = new BitField( 0x80 ); + /**/private static final BitField fHtmlChecked = new BitField(0x01); + /**/private static final BitField fHtmlUnsupported = new BitField(0x02); + /**/private static final BitField fHtmlListTextNotSharpDot = new BitField(0x04); + /**/private static final BitField fHtmlNotPeriod = new BitField(0x08); + /**/private static final BitField fHtmlFirstLineMismatch = new BitField(0x10); + /**/private static final BitField fHtmlTabLeftIndentMismatch = new BitField(0x20); + /**/private static final BitField fHtmlHangingIndentBeneathNumber = new BitField(0x40); + /**/private static final BitField fHtmlBuiltInBullet = new BitField(0x80); protected byte field_7_reserved3; protected LFOAbstractType() @@ -60,13 +61,13 @@ 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 = data[0xe + offset]; - field_7_reserved3 = data[0xf + 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 = data[ 0xe + offset ]; + field_7_reserved3 = data[ 0xf + offset ]; } public void serialize( byte[] data, int offset ) @@ -74,10 +75,17 @@ public abstract class LFOAbstractType 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; - data[0xe + offset] = field_6_grfhic; - data[0xf + offset] = field_7_reserved3; + data[ 0xc + offset ] = field_4_clfolvl; + data[ 0xd + offset ] = field_5_ibstFltAutoNum; + data[ 0xe + offset ] = field_6_grfhic; + data[ 0xf + offset ] = field_7_reserved3; + } + + public byte[] serialize() + { + final byte[] result = new byte[ getSize() ]; + serialize( result, 0 ); + return result; } /** @@ -91,45 +99,38 @@ public abstract class LFOAbstractType 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( " .fHtmlChecked = " ) - .append( isFHtmlChecked() ).append( '\n' ); - builder.append( " .fHtmlUnsupported = " ) - .append( isFHtmlUnsupported() ).append( '\n' ); - builder.append( " .fHtmlListTextNotSharpDot = " ) - .append( isFHtmlListTextNotSharpDot() ).append( '\n' ); - builder.append( " .fHtmlNotPeriod = " ) - .append( isFHtmlNotPeriod() ).append( '\n' ); - builder.append( " .fHtmlFirstLineMismatch = " ) - .append( isFHtmlFirstLineMismatch() ).append( '\n' ); - builder.append( " .fHtmlTabLeftIndentMismatch = " ) - .append( isFHtmlTabLeftIndentMismatch() ).append( '\n' ); - builder.append( " .fHtmlHangingIndentBeneathNumber = " ) - .append( isFHtmlHangingIndentBeneathNumber() ).append( '\n' ); - builder.append( " .fHtmlBuiltInBullet = " ) - .append( isFHtmlBuiltInBullet() ).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(" .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(" .fHtmlChecked = ").append(isFHtmlChecked()).append('\n'); + builder.append(" .fHtmlUnsupported = ").append(isFHtmlUnsupported()).append('\n'); + builder.append(" .fHtmlListTextNotSharpDot = ").append(isFHtmlListTextNotSharpDot()).append('\n'); + builder.append(" .fHtmlNotPeriod = ").append(isFHtmlNotPeriod()).append('\n'); + builder.append(" .fHtmlFirstLineMismatch = ").append(isFHtmlFirstLineMismatch()).append('\n'); + builder.append(" .fHtmlTabLeftIndentMismatch = ").append(isFHtmlTabLeftIndentMismatch()).append('\n'); + builder.append(" .fHtmlHangingIndentBeneathNumber = ").append(isFHtmlHangingIndentBeneathNumber()).append('\n'); + builder.append(" .fHtmlBuiltInBullet = ").append(isFHtmlBuiltInBullet()).append('\n'); + builder.append(" .reserved3 = "); + builder.append(" (").append(getReserved3()).append(" )\n"); - builder.append( "[/LFO]\n" ); + builder.append("[/LFO]\n"); return builder.toString(); } /** * List ID of corresponding LSTF (see LSTF). */ + @Internal public int getLsid() { return field_1_lsid; @@ -138,6 +139,7 @@ public abstract class LFOAbstractType /** * List ID of corresponding LSTF (see LSTF). */ + @Internal public void setLsid( int field_1_lsid ) { this.field_1_lsid = field_1_lsid; @@ -146,6 +148,7 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public int getReserved1() { return field_2_reserved1; @@ -154,6 +157,7 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public void setReserved1( int field_2_reserved1 ) { this.field_2_reserved1 = field_2_reserved1; @@ -162,6 +166,7 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public int getReserved2() { return field_3_reserved2; @@ -170,6 +175,7 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public void setReserved2( int field_3_reserved2 ) { this.field_3_reserved2 = field_3_reserved2; @@ -178,6 +184,7 @@ public abstract class LFOAbstractType /** * Count of levels whose format is overridden (see LFOLVL). */ + @Internal public byte getClfolvl() { return field_4_clfolvl; @@ -186,6 +193,7 @@ public abstract class LFOAbstractType /** * Count of levels whose format is overridden (see LFOLVL). */ + @Internal public void setClfolvl( byte field_4_clfolvl ) { this.field_4_clfolvl = field_4_clfolvl; @@ -194,6 +202,7 @@ public abstract class LFOAbstractType /** * Used for AUTONUM field emulation. */ + @Internal public byte getIbstFltAutoNum() { return field_5_ibstFltAutoNum; @@ -202,6 +211,7 @@ public abstract class LFOAbstractType /** * Used for AUTONUM field emulation. */ + @Internal public void setIbstFltAutoNum( byte field_5_ibstFltAutoNum ) { this.field_5_ibstFltAutoNum = field_5_ibstFltAutoNum; @@ -210,6 +220,7 @@ public abstract class LFOAbstractType /** * HTML compatibility flags. */ + @Internal public byte getGrfhic() { return field_6_grfhic; @@ -218,6 +229,7 @@ public abstract class LFOAbstractType /** * HTML compatibility flags. */ + @Internal public void setGrfhic( byte field_6_grfhic ) { this.field_6_grfhic = field_6_grfhic; @@ -226,6 +238,7 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public byte getReserved3() { return field_7_reserved3; @@ -234,164 +247,170 @@ public abstract class LFOAbstractType /** * Reserved. */ + @Internal public void setReserved3( byte field_7_reserved3 ) { this.field_7_reserved3 = field_7_reserved3; } /** - * Sets the fHtmlChecked field value. Checked + * Sets the fHtmlChecked field value. + * Checked */ + @Internal public void setFHtmlChecked( boolean value ) { - field_6_grfhic = (byte) fHtmlChecked.setBoolean( field_6_grfhic, value ); + field_6_grfhic = (byte)fHtmlChecked.setBoolean(field_6_grfhic, value); } /** * Checked - * - * @return the fHtmlChecked field value. + * @return the fHtmlChecked field value. */ + @Internal public boolean isFHtmlChecked() { - return fHtmlChecked.isSet( field_6_grfhic ); + return fHtmlChecked.isSet(field_6_grfhic); } /** - * Sets the fHtmlUnsupported field value. The numbering sequence or format - * is unsupported (includes tab & size) + * Sets the fHtmlUnsupported field value. + * The numbering sequence or format is unsupported (includes tab & size) */ + @Internal public void setFHtmlUnsupported( boolean value ) { - field_6_grfhic = (byte) fHtmlUnsupported.setBoolean( field_6_grfhic, - value ); + field_6_grfhic = (byte)fHtmlUnsupported.setBoolean(field_6_grfhic, value); } /** * The numbering sequence or format is unsupported (includes tab & size) - * - * @return the fHtmlUnsupported field value. + * @return the fHtmlUnsupported field value. */ + @Internal public boolean isFHtmlUnsupported() { - return fHtmlUnsupported.isSet( field_6_grfhic ); + return fHtmlUnsupported.isSet(field_6_grfhic); } /** - * Sets the fHtmlListTextNotSharpDot field value. The list text is not "#." + * Sets the fHtmlListTextNotSharpDot field value. + * The list text is not "#." */ + @Internal public void setFHtmlListTextNotSharpDot( boolean value ) { - field_6_grfhic = (byte) fHtmlListTextNotSharpDot.setBoolean( - field_6_grfhic, value ); + field_6_grfhic = (byte)fHtmlListTextNotSharpDot.setBoolean(field_6_grfhic, value); } /** * The list text is not "#." - * - * @return the fHtmlListTextNotSharpDot field value. + * @return the fHtmlListTextNotSharpDot field value. */ + @Internal public boolean isFHtmlListTextNotSharpDot() { - return fHtmlListTextNotSharpDot.isSet( field_6_grfhic ); + return fHtmlListTextNotSharpDot.isSet(field_6_grfhic); } /** - * Sets the fHtmlNotPeriod field value. Something other than a period is - * used + * Sets the fHtmlNotPeriod field value. + * Something other than a period is used */ + @Internal public void setFHtmlNotPeriod( boolean value ) { - field_6_grfhic = (byte) fHtmlNotPeriod.setBoolean( field_6_grfhic, - value ); + field_6_grfhic = (byte)fHtmlNotPeriod.setBoolean(field_6_grfhic, value); } /** * Something other than a period is used - * - * @return the fHtmlNotPeriod field value. + * @return the fHtmlNotPeriod field value. */ + @Internal public boolean isFHtmlNotPeriod() { - return fHtmlNotPeriod.isSet( field_6_grfhic ); + return fHtmlNotPeriod.isSet(field_6_grfhic); } /** - * Sets the fHtmlFirstLineMismatch field value. First line indent mismatch + * Sets the fHtmlFirstLineMismatch field value. + * First line indent mismatch */ + @Internal public void setFHtmlFirstLineMismatch( boolean value ) { - field_6_grfhic = (byte) fHtmlFirstLineMismatch.setBoolean( - field_6_grfhic, value ); + field_6_grfhic = (byte)fHtmlFirstLineMismatch.setBoolean(field_6_grfhic, value); } /** * First line indent mismatch - * - * @return the fHtmlFirstLineMismatch field value. + * @return the fHtmlFirstLineMismatch field value. */ + @Internal public boolean isFHtmlFirstLineMismatch() { - return fHtmlFirstLineMismatch.isSet( field_6_grfhic ); + return fHtmlFirstLineMismatch.isSet(field_6_grfhic); } /** - * Sets the fHtmlTabLeftIndentMismatch field value. The list tab and the - * dxaLeft don't match (need table?) + * Sets the fHtmlTabLeftIndentMismatch field value. + * The list tab and the dxaLeft don't match (need table?) */ + @Internal public void setFHtmlTabLeftIndentMismatch( boolean value ) { - field_6_grfhic = (byte) fHtmlTabLeftIndentMismatch.setBoolean( - field_6_grfhic, value ); + field_6_grfhic = (byte)fHtmlTabLeftIndentMismatch.setBoolean(field_6_grfhic, value); } /** * The list tab and the dxaLeft don't match (need table?) - * - * @return the fHtmlTabLeftIndentMismatch field value. + * @return the fHtmlTabLeftIndentMismatch field value. */ + @Internal public boolean isFHtmlTabLeftIndentMismatch() { - return fHtmlTabLeftIndentMismatch.isSet( field_6_grfhic ); + return fHtmlTabLeftIndentMismatch.isSet(field_6_grfhic); } /** - * Sets the fHtmlHangingIndentBeneathNumber field value. The hanging indent - * falls beneath the number (need plain text) + * Sets the fHtmlHangingIndentBeneathNumber field value. + * The hanging indent falls beneath the number (need plain text) */ + @Internal public void setFHtmlHangingIndentBeneathNumber( boolean value ) { - field_6_grfhic = (byte) fHtmlHangingIndentBeneathNumber.setBoolean( - field_6_grfhic, value ); + field_6_grfhic = (byte)fHtmlHangingIndentBeneathNumber.setBoolean(field_6_grfhic, value); } /** * The hanging indent falls beneath the number (need plain text) - * - * @return the fHtmlHangingIndentBeneathNumber field value. + * @return the fHtmlHangingIndentBeneathNumber field value. */ + @Internal public boolean isFHtmlHangingIndentBeneathNumber() { - return fHtmlHangingIndentBeneathNumber.isSet( field_6_grfhic ); + return fHtmlHangingIndentBeneathNumber.isSet(field_6_grfhic); } /** - * Sets the fHtmlBuiltInBullet field value. A built-in HTML bullet + * Sets the fHtmlBuiltInBullet field value. + * A built-in HTML bullet */ + @Internal public void setFHtmlBuiltInBullet( boolean value ) { - field_6_grfhic = (byte) fHtmlBuiltInBullet.setBoolean( field_6_grfhic, - value ); + field_6_grfhic = (byte)fHtmlBuiltInBullet.setBoolean(field_6_grfhic, value); } /** * A built-in HTML bullet - * - * @return the fHtmlBuiltInBullet field value. + * @return the fHtmlBuiltInBullet field value. */ + @Internal public boolean isFHtmlBuiltInBullet() { - return fHtmlBuiltInBullet.isSet( field_6_grfhic ); + return fHtmlBuiltInBullet.isSet(field_6_grfhic); } -} // END OF CLASS +} // END OF CLASS diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java index ba5bec75b5..25b41da777 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java @@ -22,6 +22,7 @@ import org.apache.poi.hwpf.model.ListFormatOverrideLevel; import org.apache.poi.hwpf.model.ListLevel; import org.apache.poi.hwpf.model.ListTables; import org.apache.poi.hwpf.model.PAPX; +import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -33,6 +34,27 @@ public final class ListEntry ListLevel _level; ListFormatOverrideLevel _overrideLevel; + @Internal + ListEntry( PAPX papx, ParagraphProperties properties, Range parent ) + { + super( papx, properties, parent ); + + final ListTables tables = parent._doc.getListTables(); + if ( tables != null && _props.getIlfo() < tables.getOverrideCount() ) + { + ListFormatOverride override = tables.getOverride( _props.getIlfo() ); + _overrideLevel = override.getOverrideLevel( _props.getIlvl() ); + _level = tables.getLevel( override.getLsid(), _props.getIlvl() ); + } + else + { + log.log( POILogger.WARN, + "No ListTables found for ListEntry - document probably partly corrupt, " + + "and you may experience problems" ); + } + } + + @Deprecated ListEntry(PAPX papx, Range parent, ListTables tables) { super(papx, parent); @@ -46,6 +68,7 @@ public final class ListEntry } } + @Deprecated public int type() { return TYPE_LISTENTRY; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java index 995d893cfd..1e741eb39c 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java @@ -17,9 +17,17 @@ package org.apache.poi.hwpf.usermodel; +import org.apache.poi.hwpf.HWPFDocumentCore; + +import org.apache.poi.hwpf.model.ListFormatOverride; +import org.apache.poi.hwpf.model.ListLevel; +import org.apache.poi.hwpf.model.ListTables; import org.apache.poi.hwpf.model.PAPX; +import org.apache.poi.hwpf.model.StyleSheet; +import org.apache.poi.hwpf.sprm.ParagraphSprmUncompressor; import org.apache.poi.hwpf.sprm.SprmBuffer; import org.apache.poi.hwpf.sprm.TableSprmCompressor; +import org.apache.poi.util.Internal; public class Paragraph extends Range implements Cloneable { public final static short SPRM_JC = 0x2403; @@ -80,11 +88,55 @@ public class Paragraph extends Range implements Cloneable { public final static short SPRM_USEPGSUSETTINGS = 0x2447; public final static short SPRM_FADJUSTRIGHT = 0x2448; + @Internal + static Paragraph newParagraph( Range parent, PAPX papx ) + { + HWPFDocumentCore doc = parent._doc; + ListTables listTables = doc.getListTables(); + StyleSheet styleSheet = doc.getStyleSheet(); + + ParagraphProperties properties = new ParagraphProperties(); + properties.setIstd( papx.getIstd() ); + + if ( styleSheet != null ) + { + int style = papx.getIstd(); + byte[] grpprl = styleSheet.getPAPX( style ); + properties = ParagraphSprmUncompressor.uncompressPAP( properties, + grpprl, 2 ); + } + + properties = ParagraphSprmUncompressor.uncompressPAP( properties, + papx.getGrpprl(), 2 ); + + if ( properties.getIlfo() != 0 && listTables != null ) + { + final ListFormatOverride listFormatOverride = listTables + .getOverride( properties.getIlfo() ); + final ListLevel listLevel = listTables.getLevel( + listFormatOverride.getLsid(), properties.getIlvl() ); + + if ( listLevel.getGrpprlPapx() != null ) + { + properties = ParagraphSprmUncompressor.uncompressPAP( + properties, listLevel.getGrpprlPapx(), 0 ); + // reapply PAPX properties + properties = ParagraphSprmUncompressor.uncompressPAP( + properties, papx.getGrpprl(), 2 ); + } + } + + if ( properties.getIlfo() > 0 ) + return new ListEntry( papx, properties, parent ); + + return new Paragraph( papx, properties, parent ); + } protected short _istd; protected ParagraphProperties _props; protected SprmBuffer _papx; + @Deprecated protected Paragraph( int startIdxInclusive, int endIdxExclusive, Table parent ) { @@ -97,27 +149,42 @@ public class Paragraph extends Range implements Cloneable { _istd = papx.getIstd(); } - protected Paragraph(PAPX papx, Range parent) - { - super(Math.max(parent._start, papx.getStart()), Math.min(parent._end, papx.getEnd()), parent); - _props = papx.getParagraphProperties(_doc.getStyleSheet()); - _papx = papx.getSprmBuf(); - _istd = papx.getIstd(); - } + @Deprecated + protected Paragraph( PAPX papx, Range parent ) + { + super( Math.max( parent._start, papx.getStart() ), Math.min( + parent._end, papx.getEnd() ), parent ); + _props = papx.getParagraphProperties( _doc.getStyleSheet() ); + _papx = papx.getSprmBuf(); + _istd = papx.getIstd(); + } - protected Paragraph(PAPX papx, Range parent, int start) - { - super(Math.max(parent._start, start), Math.min(parent._end, papx.getEnd()), parent); - _props = papx.getParagraphProperties(_doc.getStyleSheet()); - _papx = papx.getSprmBuf(); - _istd = papx.getIstd(); - } + @Deprecated + protected Paragraph( PAPX papx, Range parent, int start ) + { + super( Math.max( parent._start, start ), Math.min( parent._end, + papx.getEnd() ), parent ); + _props = papx.getParagraphProperties( _doc.getStyleSheet() ); + _papx = papx.getSprmBuf(); + _istd = papx.getIstd(); + } - public short getStyleIndex() + @Internal + Paragraph( PAPX papx, ParagraphProperties properties, Range parent ) + { + super( Math.max( parent._start, papx.getStart() ), Math.min( + parent._end, papx.getEnd() ), parent ); + _props = properties; + _papx = papx.getSprmBuf(); + _istd = papx.getIstd(); + } + +public short getStyleIndex() { return _istd; } + @Deprecated public int type() { return TYPE_PARAGRAPH; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java index 7c662fae1a..b690d400d7 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java @@ -60,12 +60,19 @@ public class Range { // TODO -instantiable superclass private POILogger logger = POILogFactory.getLogger( Range.class ); + @Deprecated public static final int TYPE_PARAGRAPH = 0; + @Deprecated public static final int TYPE_CHARACTER = 1; + @Deprecated public static final int TYPE_SECTION = 2; + @Deprecated public static final int TYPE_TEXT = 3; + @Deprecated public static final int TYPE_LISTENTRY = 4; + @Deprecated public static final int TYPE_TABLE = 5; + @Deprecated public static final int TYPE_UNDEFINED = 6; /** Needed so inserts and deletes will ripple up through containing Ranges */ @@ -880,20 +887,7 @@ public class Range { // TODO -instantiable superclass + "; " + _parEnd + ")" ); PAPX papx = _paragraphs.get(index + _parStart); - - ParagraphProperties props = papx.getParagraphProperties(_doc.getStyleSheet()); - Paragraph pap = null; - if (props.getIlfo() > 0) { - pap = new ListEntry(papx, this, _doc.getListTables()); - } else { - if (((index + _parStart)==0) && papx.getStart()>0) { - pap = new Paragraph(papx, this, 0); - } else { - pap = new Paragraph(papx, this); - } - } - - return pap; + return Paragraph.newParagraph( this, papx ); } /** @@ -902,6 +896,7 @@ public class Range { // TODO -instantiable superclass * * @return A TYPE constant. */ + @Deprecated public int type() { return TYPE_UNDEFINED; } @@ -930,8 +925,8 @@ public class Range { // TODO -instantiable superclass if ( r._parStart != 0 ) { - Paragraph previous = new Paragraph( - _paragraphs.get( r._parStart - 1 ), this ); + Paragraph previous = Paragraph.newParagraph( this, + _paragraphs.get( r._parStart - 1 ) ); if ( previous.isInTable() && // previous.getTableLevel() == tableLevel // && previous._sectionEnd >= r._sectionStart ) @@ -945,8 +940,8 @@ public class Range { // TODO -instantiable superclass int limit = _paragraphs.size(); for ( ; tableEndInclusive < limit - 1; tableEndInclusive++ ) { - Paragraph next = new Paragraph( - _paragraphs.get( tableEndInclusive + 1 ), overallRange ); + Paragraph next = Paragraph.newParagraph( overallRange, + _paragraphs.get( tableEndInclusive + 1 ) ); if ( !next.isInTable() || next.getTableLevel() < tableLevel ) break; }