From 8a0c521503d2f4198f7fa2d453e9ca0647041a9e Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sat, 9 Aug 2008 20:31:48 +0000 Subject: [PATCH] Improve FIB updating on range changes, and add passing tests for non unicode paragraph properties git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684336 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hwpf/HWPFDocument.java | 4 + .../poi/hwpf/usermodel/HeaderStories.java | 31 +++++++ .../org/apache/poi/hwpf/usermodel/Range.java | 51 ++++++++--- .../hwpf/usermodel/TestRangeProperties.java | 91 ++++++++++++++++++- 4 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index 9a0cdb5cca..b0f7af334a 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -288,6 +288,10 @@ public class HWPFDocument extends POIDocument { return _fib; } + public CPSplitCalculator getCPSplitCalculator() + { + return _cpSplit; + } public DocumentProperties getDocProperties() { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java new file mode 100644 index 0000000000..65924d3e61 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java @@ -0,0 +1,31 @@ +/* ==================================================================== + 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; + +/** + * A HeaderStory is a Header, a Footer, or footnote/endnote + * separator. + * All the Header Stories get stored in the same Range in the + * document, and this handles getting out all the individual + * parts. + */ +public class HeaderStories { + private Range headerStories; + public HeaderStories(Range headerStories) { + this.headerStories = headerStories; + } +} 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 c37e9be98a..0b75a1da63 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java @@ -29,6 +29,8 @@ import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.ParagraphProperties; import org.apache.poi.hwpf.usermodel.Section; +import org.apache.poi.hwpf.model.CPSplitCalculator; +import org.apache.poi.hwpf.model.FileInformationBlock; import org.apache.poi.hwpf.model.PropertyNode; import org.apache.poi.hwpf.model.StyleSheet; import org.apache.poi.hwpf.model.CHPX; @@ -41,6 +43,8 @@ import org.apache.poi.hwpf.sprm.CharacterSprmCompressor; import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor; import org.apache.poi.hwpf.sprm.SprmBuffer; +import sun.security.krb5.internal.aj; + import java.util.List; import java.util.NoSuchElementException; @@ -340,7 +344,7 @@ public class Range _doc.getSectionTable().adjustForInsert(_sectionStart, adjustedLength); adjustForInsert(adjustedLength); - // update the FIB.CCPText field + // update the FIB.CCPText + friends fields adjustFIB(text.length()); return getCharacterRun(0); @@ -551,11 +555,8 @@ public class Range piece.adjustForDelete(_start, _end - _start); } - // update the FIB.CCPText field - if (usesUnicode()) - adjustFIB(-((_end - _start) / 2)); - else - adjustFIB(-(_end - _start)); + // update the FIB.CCPText + friends field + adjustFIB(-(_end - _start)); } /** @@ -934,18 +935,44 @@ public class Range } /** - * Adjust the value of FIB.CCPText after an insert or a delete... - * - * TODO - handle other kinds of text, eg Headers + * Adjust the value of the various FIB character count fields, + * eg FIB.CCPText after an insert or a delete... + * + * Works on all CCP fields from this range onwards * - * @param adjustment The (signed) value that should be added to FIB.CCPText + * @param adjustment The (signed) value that should be added to the FIB CCP fields */ protected void adjustFIB(int adjustment) { - // update the FIB.CCPText field (this should happen once per adjustment, so we don't want it in // adjustForInsert() or it would get updated multiple times if the range has a parent) // without this, OpenOffice.org (v. 2.2.x) does not see all the text in the document - _doc.getFileInformationBlock().setCcpText(_doc.getFileInformationBlock().getCcpText() + adjustment); + + CPSplitCalculator cpS = _doc.getCPSplitCalculator(); + FileInformationBlock fib = _doc.getFileInformationBlock(); + + // Do for each affected part + if(_start < cpS.getMainDocumentEnd()) { + fib.setCcpText(fib.getCcpText() + adjustment); + } + + if(_start < cpS.getCommentsEnd()) { + fib.setCcpAtn(fib.getCcpAtn() + adjustment); + } + if(_start < cpS.getEndNoteEnd()) { + fib.setCcpEdn(fib.getCcpEdn() + adjustment); + } + if(_start < cpS.getFootnoteEnd()) { + fib.setCcpFtn(fib.getCcpFtn() + adjustment); + } + if(_start < cpS.getHeaderStoryEnd()) { + fib.setCcpHdd(fib.getCcpHdd() + adjustment); + } + if(_start < cpS.getHeaderTextboxEnd()) { + fib.setCcpHdrTxtBx(fib.getCcpHdrTxtBx() + adjustment); + } + if(_start < cpS.getMainTextboxEnd()) { + fib.setCcpTxtBx(fib.getCcpTxtBx() + adjustment); + } } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeProperties.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeProperties.java index 6c841e87a3..19829926f6 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeProperties.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeProperties.java @@ -19,7 +19,6 @@ package org.apache.poi.hwpf.usermodel; import java.io.File; import java.io.FileInputStream; -import org.apache.poi.hwpf.HWPFDocFixture; import org.apache.poi.hwpf.HWPFDocument; import junit.framework.TestCase; @@ -48,8 +47,19 @@ public class TestRangeProperties extends TestCase { "This is page two. Les Pr\u00e9cieuses ridicules. The end.\r" ; + private static final String a_page_1 = + "I am a test document\r" + + "This is page 1\r" + + "I am Calibri (Body) in font size 11\r" + ; + private static final String a_page_2 = + "This is page two\r" + + "It\u2019s Arial Black in 16 point\r" + + "It\u2019s also in blue\r" + ; + private HWPFDocument u; - // TODO - a non unicode document too + private HWPFDocument a; private String dirname; @@ -58,7 +68,79 @@ public class TestRangeProperties extends TestCase { u = new HWPFDocument( new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc")) ); + a = new HWPFDocument( + new FileInputStream(new File(dirname, "SampleDoc.doc")) + ); + } + + + public void testAsciiTextParagraphs() throws Exception { + Range r = a.getRange(); + assertEquals( + a_page_1 + + page_break + "\r" + + a_page_2, + r.text() + ); + + assertEquals( + 7, + r.numParagraphs() + ); + String[] p1_parts = a_page_1.split("\r"); + String[] p2_parts = a_page_2.split("\r"); + + // Check paragraph contents + assertEquals( + p1_parts[0] + "\r", + r.getParagraph(0).text() + ); + assertEquals( + p1_parts[1] + "\r", + r.getParagraph(1).text() + ); + assertEquals( + p1_parts[2] + "\r", + r.getParagraph(2).text() + ); + + assertEquals( + page_break + "\r", + r.getParagraph(3).text() + ); + + assertEquals( + p2_parts[0] + "\r", + r.getParagraph(4).text() + ); + assertEquals( + p2_parts[1] + "\r", + r.getParagraph(5).text() + ); + assertEquals( + p2_parts[2] + "\r", + r.getParagraph(6).text() + ); + } + + public void testAsciiStyling() throws Exception { + Range r = a.getRange(); + + Paragraph p1 = r.getParagraph(0); + Paragraph p7 = r.getParagraph(6); + + assertEquals(1, p1.numCharacterRuns()); + assertEquals(1, p7.numCharacterRuns()); + + CharacterRun c1 = p1.getCharacterRun(0); + CharacterRun c7 = p7.getCharacterRun(0); + + assertEquals("Times New Roman", c1.getFontName()); // No Calibri + assertEquals("Arial Black", c7.getFontName()); + assertEquals(22, c1.getFontSize()); + assertEquals(32, c7.getFontSize()); } + public void testUnicodeTextParagraphs() throws Exception { Range r = u.getRange(); @@ -73,10 +155,13 @@ public class TestRangeProperties extends TestCase { 5, r.numParagraphs() ); + String[] p1_parts = u_page_1.split("\r"); + String[] p2_parts = u_page_2.split("\r"); System.out.println(r.getParagraph(2).text()); + // TODO } public void testUnicodeStyling() throws Exception { - + // TODO } } -- 2.39.5