diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 9123d65c1..f1b71436e 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 49820 - Fix HWPF paragraph levels, so that outline levels can be properly fetched 47271 - Avoid infinite loops on broken HWPF documents with a corrupt CHP style with a parent of itself 49936 - Handle HWPF documents with problematic HeaderStories better 49933 - Support sections in Word 6 and Word 95 files (HWPFOldDocument) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java b/src/scratchpad/src/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java index a6b12ec2d..695de5964 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java @@ -337,11 +337,12 @@ public final class ParagraphSprmUncompressor } break; case 0x40: - - //newPAP._lvl = param; - if (newPAP.getIstd () >= 1 && newPAP.getIstd () <= 9) + // This condition commented out, as Word seems to set outline levels even for + // paragraph with other styles than Heading 1..9, even though specification + // does not say so. See bug 49820 for discussion. + //if (newPAP.getIstd () < 1 && newPAP.getIstd () > 9) { - newPAP.setIlvl ((byte) sprm.getOperand()); + newPAP.setLvl ((byte) sprm.getOperand()); } break; case 0x41: 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 087c6c5c1..87fe4d7f1 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Paragraph.java @@ -435,14 +435,19 @@ public class Paragraph extends Range implements Cloneable { } public int getIlfo() - { + { return _props.getIlfo(); - } + } - public int getIlvl() - { + public int getIlvl() + { return _props.getIlvl(); - } + } + + public int getLvl() + { + return _props.getLvl(); + } void setTableRowEnd(TableProperties props) { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java index 8944eb060..8ab3d904a 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/ParagraphProperties.java @@ -35,7 +35,7 @@ public final class ParagraphProperties extends PAPAbstractType implements Clonea this.field_17_fWidowControl = 1; this.field_21_lspd.setMultiLinespace((short)1); this.field_21_lspd.setDyaLine((short)240); - this.field_12_ilvl = (byte)9; + this.field_58_lvl = (byte)9; this.field_66_rgdxaTab = new int[0]; this.field_67_rgtbd = new byte[0]; this.field_63_dttmPropRMark = new DateAndTime(); diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBug49820.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBug49820.java new file mode 100644 index 000000000..4e96646f4 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBug49820.java @@ -0,0 +1,63 @@ +/* ==================================================================== + 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.usermodel; + +import java.io.IOException; +import junit.framework.TestCase; + +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.HWPFTestDataSamples; +import org.apache.poi.hwpf.model.StyleSheet; + +public final class TestBug49820 extends TestCase { + + public void test() throws IOException { + HWPFDocument doc = HWPFTestDataSamples.openSampleFile("Bug49820.doc"); + + Range documentRange = doc.getRange(); + StyleSheet styleSheet = doc.getStyleSheet(); + + // JUnit asserts + assertLevels(documentRange, styleSheet, 0, 0, 0); + assertLevels(documentRange, styleSheet, 1, 1, 1); + assertLevels(documentRange, styleSheet, 2, 2, 2); + assertLevels(documentRange, styleSheet, 3, 3, 3); + assertLevels(documentRange, styleSheet, 4, 4, 4); + assertLevels(documentRange, styleSheet, 5, 5, 5); + assertLevels(documentRange, styleSheet, 6, 6, 6); + assertLevels(documentRange, styleSheet, 7, 7, 7); + assertLevels(documentRange, styleSheet, 8, 8, 8); + assertLevels(documentRange, styleSheet, 9, 9, 9); + assertLevels(documentRange, styleSheet, 10, 9, 0); + assertLevels(documentRange, styleSheet, 11, 9, 4); + + // output to console + /*for (int i=0; i