diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index c355afd44..9c1529aa5 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -36,6 +36,7 @@ + 28627 / 44580 - Fix Range.delete() in HWPF 44539 - Support for area references in formulas of rows >= 32768 44536 - Improved support for detecting read-only recommended files 43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index c59cae1a3..367c6b0c7 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 28627 / 44580 - Fix Range.delete() in HWPF 44539 - Support for area references in formulas of rows >= 32768 44536 - Improved support for detecting read-only recommended files 43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/TextPiece.java b/src/scratchpad/src/org/apache/poi/hwpf/model/TextPiece.java index 593214b18..67c634d9f 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/TextPiece.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/TextPiece.java @@ -90,7 +90,19 @@ public class TextPiece extends PropertyNode implements Comparable public void adjustForDelete(int start, int length) { + int myStart = getStart(); + int myEnd = getEnd(); + int end = start + length; + /* do we have to delete from this text piece? */ + if (start <= myEnd && end >= myStart) { + /* find where the deleted area overlaps with this text piece */ + int overlapStart = Math.max(myStart, start); + int overlapEnd = Math.min(myEnd, end); + ((StringBuffer)_buf).delete(overlapStart, overlapEnd); + + super.adjustForDelete(start, length); + } } public int characterLength() 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 60e00f325..f2d9a615f 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java @@ -494,6 +494,7 @@ public class Range int numSections = _sections.size(); int numRuns = _characters.size(); int numParagraphs = _paragraphs.size(); + int numTextPieces = _text.size(); for (int x = _charStart; x < numRuns; x++) { @@ -512,6 +513,12 @@ public class Range SEPX sepx = (SEPX)_sections.get(x); sepx.adjustForDelete(_start, _end - _start); } + + for (int x = _textStart; x < numTextPieces; x++) + { + TextPiece piece = (TextPiece)_text.get(x); + piece.adjustForDelete(_start, _end - _start); + } } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/Bug28627.doc b/src/scratchpad/testcases/org/apache/poi/hwpf/data/Bug28627.doc new file mode 100644 index 000000000..91b031d1d Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hwpf/data/Bug28627.doc differ diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java index e82c4d130..23681486f 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java @@ -16,19 +16,14 @@ */ package org.apache.poi.hwpf.usermodel; -import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; -import java.util.Iterator; -import java.util.List; +import java.io.FileOutputStream; + +import junit.framework.TestCase; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.model.StyleSheet; -import org.apache.poi.hwpf.model.TextPiece; -import org.apache.poi.hwpf.usermodel.Paragraph; -import org.apache.poi.hwpf.usermodel.Range; -import org.apache.poi.util.LittleEndian; - -import junit.framework.TestCase; /** * Test various problem documents @@ -36,16 +31,18 @@ import junit.framework.TestCase; * @author Nick Burch (nick at torchbox dot com) */ public class TestProblems extends TestCase { + private String dirname = System.getProperty("HWPF.testdata.path"); protected void setUp() throws Exception { - } - + } + /** * ListEntry passed no ListTable */ public void testListEntryNoListTable() throws Exception { - HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/ListEntryNoListTable.doc")); + HWPFDocument doc = new HWPFDocument(new FileInputStream( + new File(dirname, "ListEntryNoListTable.doc"))); Range r = doc.getRange(); StyleSheet styleSheet = doc.getStyleSheet(); @@ -62,7 +59,8 @@ public class TestProblems extends TestCase { * AIOOB for TableSprmUncompressor.unCompressTAPOperation */ public void testSprmAIOOB() throws Exception { - HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/AIOOB-Tap.doc")); + HWPFDocument doc = new HWPFDocument(new FileInputStream( + new File(dirname, "AIOOB-Tap.doc"))); Range r = doc.getRange(); StyleSheet styleSheet = doc.getStyleSheet(); @@ -79,7 +77,8 @@ public class TestProblems extends TestCase { * Test for TableCell not skipping the last paragraph */ public void testTableCellLastParagraph() throws Exception { - HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/Bug44292.doc")); + HWPFDocument doc = new HWPFDocument(new FileInputStream( + new File(dirname, "Bug44292.doc"))); Range r = doc.getRange(); //get the table @@ -104,4 +103,39 @@ public class TestProblems extends TestCase { // Last cell should have one paragraph assertEquals(1, cell.numParagraphs()); } + + public void testRangeDelete() throws Exception { + HWPFDocument doc = new HWPFDocument(new FileInputStream( + new File(dirname, "Bug28627.doc"))); + + Range range = doc.getRange(); + int numParagraphs = range.numParagraphs(); + + int totalLength = 0, deletedLength = 0; + + for (int i = 0; i < numParagraphs; i++) { + Paragraph para = range.getParagraph(i); + String text = para.text(); + + totalLength += text.length(); + if (text.indexOf("{delete me}") > -1) { + para.delete(); + deletedLength = text.length(); + } + } + + // check the text length after deletion + int newLength = 0; + range = doc.getRange(); + numParagraphs = range.numParagraphs(); + + for (int i = 0; i < numParagraphs; i++) { + Paragraph para = range.getParagraph(i); + String text = para.text(); + + newLength += text.length(); + } + + assertEquals(newLength, totalLength - deletedLength); + } }