<changes>
<release version="3.9-beta1" date="2012-??-??">
+ <action dev="poi-developers" type="fix">52311 - Conversion to html : Problem in titles number </action>
<action dev="poi-developers" type="fix">53914 - TableRow#getTopBorder() return bottom's border</action>
<action dev="poi-developers" type="fix">53282 - Avoid exception when parsing OPC relationships with non-breaking spaces</action>
<action dev="poi-developers" type="fix">54016 - Avoid exception when parsing workbooks with DConRefRecord in row aggregate</action>
return stringBuilder.toString();
}
- public static class NumberingState {
-
+ public static class NumberingState
+ {
+
private final Map<String, Integer> levels = new HashMap<String, Integer>();
-
+
}
-
- public static String getBulletText(NumberingState numberingState, HWPFList list, char level )
+
+ public static String getBulletText( NumberingState numberingState,
+ HWPFList list, char level )
{
StringBuffer bulletBuffer = new StringBuffer();
char[] xst = list.getNumberText( level ).toCharArray();
{
if ( element < 9 )
{
- final String key = list.getLsid() + "#" + ( (int) element );
+ int lsid = list.getLsid();
+ final String key = lsid + "#" + ( (int) element );
int num;
- if ( numberingState.levels.containsKey( key ) )
+
+ if ( !list.isStartAtOverriden( element )
+ && numberingState.levels.containsKey( key ) )
{
num = numberingState.levels.get( key ).intValue();
+ if ( level == element )
+ {
+ num++;
+ numberingState.levels.put( key, Integer.valueOf( num ) );
+ }
}
else
{
- num = list.getStartAt( level );
+ num = list.getStartAt( element );
numberingState.levels.put( key, Integer.valueOf( num ) );
}
- bulletBuffer.append( NumberFormatter.getNumber( num,
- list.getNumberFormat( level ) ) );
-
if ( level == element )
{
- numberingState.levels.put( key, Integer.valueOf( num + 1 ) );
+ // cleaning states of nested levels to reset numbering
+ for ( int i = element + 1; i < 9; i++ )
+ {
+ final String childKey = lsid + "#" + i;
+ numberingState.levels.remove( childKey );
+ }
}
+
+ bulletBuffer.append( NumberFormatter.getNumber( num,
+ list.getNumberFormat( level ) ) );
}
else
{
}
}
- byte follow = list.getTypeOfCharFollowingTheNumber(level);
+ byte follow = list.getTypeOfCharFollowingTheNumber( level );
switch ( follow )
{
case 0:
See the License for the specific language governing permissions and\r
limitations under the License.\r
==================================================================== */\r
+\r
package org.apache.poi.hwpf.model.types;\r
\r
\r
-import org.apache.poi.util.BitField;\r
-import org.apache.poi.util.Internal;\r
+import org.apache.poi.hwpf.usermodel.*;\r
+import org.apache.poi.util.*;\r
\r
/**\r
* The grfhic structure is a set of HTML incompatibility flags that specify the HTML\r
public String toString()\r
{\r
StringBuilder builder = new StringBuilder();\r
+\r
builder.append("[Grfhic]\n");\r
- builder.append(" .grfhic = ");\r
- builder.append(" (").append(getGrfhic()).append(" )\n");\r
+ builder.append( " .grfhic = " );\r
+ builder.append(" ( ").append( field_1_grfhic ).append( " )\n" );\r
builder.append(" .fHtmlChecked = ").append(isFHtmlChecked()).append('\n');\r
builder.append(" .fHtmlUnsupported = ").append(isFHtmlUnsupported()).append('\n');\r
builder.append(" .fHtmlListTextNotSharpDot = ").append(isFHtmlListTextNotSharpDot()).append('\n');\r
builder.append(" .fHtmlHangingIndentBeneathNumber = ").append(isFHtmlHangingIndentBeneathNumber()).append('\n');\r
builder.append(" .fHtmlBuiltInBullet = ").append(isFHtmlBuiltInBullet()).append('\n');\r
\r
- builder.append("[/Grfhic]\n");\r
+ builder.append("[/Grfhic]");\r
return builder.toString();\r
}\r
\r
import org.apache.poi.util.LittleEndian;\r
\r
/**\r
- * List Format Override (LFO).\r
+ * List Format Override (LFO). <p>Class and fields descriptions are quoted from\r
+ [MS-DOC] --v20110315; Word (.doc) Binary File Format\r
+ \r
* <p>\r
- * Class and fields descriptions are quoted from [MS-DOC] --v20110315; Word\r
- * (.doc) Binary File Format\r
- * \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
* <p>\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
+ * 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 [MS-DOC] --v20110315; Word (.doc)\r
- * Binary File Format; Copyright (c) Microsoft Corporation\r
+\r
+ * @author Sergey Vladimirov; according to [MS-DOC] --v20110315; Word (.doc) Binary File Format;\r
+ Copyright (c) Microsoft Corporation\r
+ \r
*/\r
@Internal\r
public abstract class LFOAbstractType\r
\r
protected void fillFields( byte[] data, int offset )\r
{\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
+ 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
LittleEndian.putInt( data, 0x0 + offset, field_1_lsid );\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
+ 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_unused3;\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
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\r
+ + ((field_6_grfhic == null) ? 0 : field_6_grfhic.hashCode());\r
result = prime * result + field_7_unused3;\r
return result;\r
}\r
public String toString()\r
{\r
StringBuilder builder = new StringBuilder();\r
- builder.append( "[LFO]\n" );\r
+\r
+ builder.append("[LFO]\n");\r
builder.append( " .lsid = " );\r
- builder.append( " (" ).append( getLsid() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_1_lsid ).append( " )\n" );\r
builder.append( " .unused1 = " );\r
- builder.append( " (" ).append( getUnused1() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_2_unused1 ).append( " )\n" );\r
builder.append( " .unused2 = " );\r
- builder.append( " (" ).append( getUnused2() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_3_unused2 ).append( " )\n" );\r
builder.append( " .clfolvl = " );\r
- builder.append( " (" ).append( getClfolvl() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_4_clfolvl ).append( " )\n" );\r
builder.append( " .ibstFltAutoNum = " );\r
- builder.append( " (" ).append( getIbstFltAutoNum() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_5_ibstFltAutoNum ).append( " )\n" );\r
builder.append( " .grfhic = " );\r
- builder.append( " (" ).append( getGrfhic() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_6_grfhic == null ? "null" : field_6_grfhic.toString().replaceAll( "\n", "\n " ) ).append( " )\n" );\r
builder.append( " .unused3 = " );\r
- builder.append( " (" ).append( getUnused3() ).append( " )\n" );\r
+ builder.append(" ( ").append( field_7_unused3 ).append( " )\n" );\r
\r
- builder.append( "[/LFO]\n" );\r
+ builder.append("[/LFO]");\r
return builder.toString();\r
}\r
\r
/**\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
+ * 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..\r
*/\r
@Internal\r
public int getLsid()\r
}\r
\r
/**\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
+ * 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..\r
*/\r
@Internal\r
public void setLsid( int field_1_lsid )\r
this.field_7_unused3 = field_7_unused3;\r
}\r
\r
-} // END OF CLASS\r
+} // END OF CLASS\r
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.ListFormatOverrideLevel;
import org.apache.poi.hwpf.model.ListLevel;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.sprm.CharacterSprmCompressor;
public int getStartAt( char level )
{
+ if ( isStartAtOverriden( level ) )
+ {
+ return _lfoData.getRgLfoLvl()[level].getIStartAt();
+ }
+
return getLVL( level ).getStartAt();
}
return _ignoreLogicalLeftIdentation;
}
+ public boolean isStartAtOverriden( char level )
+ {
+ ListFormatOverrideLevel lfolvl = _lfoData.getRgLfoLvl().length > level ? _lfoData
+ .getRgLfoLvl()[level] : null;
+
+ return lfolvl != null && lfolvl.getIStartAt() != 0
+ && !lfolvl.isFormatting();
+ }
+
public void setIgnoreLogicalLeftIdentation(
boolean ignoreLogicalLeftIdentation )
{
.contains( "Soak the rice in water for three to four hours" ) );
}
+ public void testBug52311() throws Exception
+ {
+ HWPFDocument doc = HWPFTestDataSamples.openSampleFile( "Bug52311.doc" );
+ String result = WordToTextConverter.getText( doc );
+
+ assertTrue( result.contains( "2.1\tHeader 2.1" ) );
+ assertTrue( result.contains( "2.2\tHeader 2.2" ) );
+ assertTrue( result.contains( "2.3\tHeader 2.3" ) );
+ assertTrue( result.contains( "2.3.1\tHeader 2.3.1" ) );
+ assertTrue( result.contains( "2.99\tHeader 2.99" ) );
+ assertTrue( result.contains( "2.99.1\tHeader 2.99.1" ) );
+ assertTrue( result.contains( "2.100\tHeader 2.100" ) );
+ assertTrue( result.contains( "2.101\tHeader 2.101" ) );
+ }
+
public void testBug53380_3() throws Exception
{
HWPFDocument doc = HWPFTestDataSamples
<xsl:call-template name="linebreak"/>
<xsl:call-template name="linebreak"/>
- <xsl:call-template name="indent"/>
- <xsl:text>public String toString()
- {
- StringBuilder builder = new StringBuilder();
-</xsl:text>
- <xsl:call-template name="indent"/>
- <xsl:call-template name="indent"/>
- <xsl:text>builder.append("[</xsl:text>
- <xsl:value-of select="@name"/>
- <xsl:text>]\n");</xsl:text>
- <xsl:call-template name="linebreak"/>
- <xsl:apply-templates select="//field" mode="tostring"/>
- <xsl:call-template name="linebreak"/>
- <xsl:call-template name="indent"/>
- <xsl:call-template name="indent"/>
- <xsl:text>builder.append("[/</xsl:text>
- <xsl:value-of select="@name"/>
- <xsl:text>]\n");
- return builder.toString();
- }
-</xsl:text>
+
+ <xsl:call-template name="toString" />
<xsl:apply-templates select="//field" mode="getset"/>
<xsl:apply-templates select="//field" mode="bits"/>
}
</xsl:template>
- <xsl:template match="field" mode="tostring">
- <xsl:call-template name="indent"/>
- <xsl:call-template name="indent"/>
- <xsl:text>builder.append(" .</xsl:text>
- <xsl:value-of select="recutil:getFieldName(@name,20)"/>
- <xsl:text> = ");</xsl:text>
- <xsl:call-template name="linebreak"/>
- <xsl:call-template name="indent"/>
- <xsl:call-template name="indent"/>
- <xsl:text>builder.append(" (").append(get</xsl:text>
- <xsl:value-of select="recutil:getFieldName1stCap(@name,0)"/>
- <xsl:text>()).append(" )\n");</xsl:text>
- <xsl:call-template name="linebreak"/>
- <xsl:apply-templates select="bit" mode="bittostring"/>
- </xsl:template>
+ <xsl:template name="toString">
+ <xsl:call-template name="indent" />
+ <xsl:text>public String toString()</xsl:text>
+ <xsl:call-template name="linebreak" />
+
+ <xsl:call-template name="indent" />
+ <xsl:text>{</xsl:text>
+ <xsl:call-template name="linebreak" />
+
+ <xsl:call-template name="indent" />
+ <xsl:call-template name="indent" />
+ <xsl:text>StringBuilder builder = new StringBuilder();</xsl:text>
+ <xsl:call-template name="linebreak" />
+ <xsl:call-template name="linebreak" />
+
+ <xsl:call-template name="indent" />
+ <xsl:call-template name="indent" />
+ <xsl:text>builder.append("[</xsl:text>
+ <xsl:value-of select="@name" />
+ <xsl:text>]\n");</xsl:text>
+ <xsl:call-template name="linebreak" />
+
+ <xsl:apply-templates select="//field" mode="tostring" />
+
+ <xsl:call-template name="linebreak" />
+ <xsl:call-template name="indent" />
+ <xsl:call-template name="indent" />
+ <xsl:text>builder.append("[/</xsl:text>
+ <xsl:value-of select="@name" />
+ <xsl:text>]");
+ return builder.toString();
+ }
+</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="field" mode="tostring">
+ <xsl:variable name="fieldName"
+ select="recutil:getFieldName(position(),@name,0)" />
+
+ <xsl:call-template name="indent" />
+ <xsl:call-template name="indent" />
+ <xsl:text>builder.append( " .</xsl:text>
+ <xsl:value-of select="recutil:getFieldName(@name,20)" />
+ <xsl:text> = " );</xsl:text>
+ <xsl:call-template name="linebreak" />
+
+ <xsl:call-template name="indent" />
+ <xsl:call-template name="indent" />
+ <xsl:text>builder.append(" ( ").append( </xsl:text>
+ <xsl:choose>
+ <xsl:when
+ test="@type='boolean' or @type='byte' or @type='double' or @type='int' or @type='long' or @type='short'">
+ <xsl:value-of select="$fieldName" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fieldName" />
+ <xsl:text> == null ? "null" : </xsl:text>
+ <xsl:value-of select="$fieldName" />
+ <xsl:text>.toString().replaceAll( "\n", "\n " )</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> ).append( " )\n" );</xsl:text>
+ <xsl:call-template name="linebreak" />
+
+ <xsl:apply-templates select="bit" mode="bittostring" />
+ </xsl:template>
<xsl:template match="bit" mode="bittostring">
<xsl:call-template name="indent"/>