Browse Source

fixed bug #45720: cloneSheet breaks autofilters.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692893 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_2_FINAL
Yegor Kozlov 15 years ago
parent
commit
a0cef40211

+ 1
- 0
src/documentation/content/xdocs/changes.xml View File

@@ -37,6 +37,7 @@

<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
<action dev="POI-DEVELOPERS" type="fix">45728 Fix for SlideShow.reorderSlide in HSLF</action>
<action dev="POI-DEVELOPERS" type="add">Initial support for embedded movies and controls in HSLF</action>
<action dev="POI-DEVELOPERS" type="fix">45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF()</action>

+ 1
- 0
src/documentation/content/xdocs/status.xml View File

@@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
<action dev="POI-DEVELOPERS" type="fix">45728 Fix for SlideShow.reorderSlide in HSLF</action>
<action dev="POI-DEVELOPERS" type="add">Initial support for embedded movies and controls in HSLF</action>
<action dev="POI-DEVELOPERS" type="fix">45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF()</action>

+ 17
- 0
src/java/org/apache/poi/ddf/EscherContainerRecord.java View File

@@ -235,4 +235,21 @@ public class EscherContainerRecord extends EscherRecord
return null;
}

/**
* Recursively find records with the specified record ID
*
* @param out - list to store found records
*/
public void getRecordsById(short recordId, List out){
for(Iterator it = childRecords.iterator(); it.hasNext();) {
Object er = it.next();
if(er instanceof EscherContainerRecord) {
EscherContainerRecord c = (EscherContainerRecord)er;
c.getRecordsById(recordId, out );
} else if (er instanceof EscherSpRecord){
out.add(er);
}
}
}

}

+ 11
- 3
src/java/org/apache/poi/hssf/model/DrawingManager2.java View File

@@ -67,6 +67,17 @@ public class DrawingManager2
* @return a new shape id.
*/
public int allocateShapeId(short drawingGroupId)
{
EscherDgRecord dg = getDrawingGroup(drawingGroupId);
return allocateShapeId(drawingGroupId, dg);
}

/**
* Allocates new shape id for the new drawing group id.
*
* @return a new shape id.
*/
public int allocateShapeId(short drawingGroupId, EscherDgRecord dg)
{
dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );

@@ -78,7 +89,6 @@ public class DrawingManager2
{
int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
c.incrementShapeId();
EscherDgRecord dg = getDrawingGroup(drawingGroupId);
dg.setNumShapes( dg.getNumShapes() + 1 );
dg.setLastMSOSPID( result );
if (result >= dgg.getShapeIdMax())
@@ -90,7 +100,6 @@ public class DrawingManager2
// Create new cluster
dgg.addCluster( drawingGroupId, 0 );
dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
EscherDgRecord dg = getDrawingGroup(drawingGroupId);
dg.setNumShapes( dg.getNumShapes() + 1 );
int result = (1024 * dgg.getFileIdClusters().length);
dg.setLastMSOSPID( result );
@@ -98,7 +107,6 @@ public class DrawingManager2
dgg.setShapeIdMax( result + 1 );
return result;
}

//////////// Non-public methods /////////////
/**

+ 58
- 57
src/java/org/apache/poi/hssf/model/Workbook.java View File

@@ -22,57 +22,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherRGBProperty;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherSplitMenuColorsRecord;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.BookBoolRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.CodepageRecord;
import org.apache.poi.hssf.record.CountryRecord;
import org.apache.poi.hssf.record.DSFRecord;
import org.apache.poi.hssf.record.DateWindow1904Record;
import org.apache.poi.hssf.record.DrawingGroupRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.ExtSSTRecord;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.ExternSheetRecord;
import org.apache.poi.hssf.record.FileSharingRecord;
import org.apache.poi.hssf.record.FnGroupCountRecord;
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.record.FormatRecord;
import org.apache.poi.hssf.record.HideObjRecord;
import org.apache.poi.hssf.record.HyperlinkRecord;
import org.apache.poi.hssf.record.InterfaceEndRecord;
import org.apache.poi.hssf.record.InterfaceHdrRecord;
import org.apache.poi.hssf.record.MMSRecord;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.PaletteRecord;
import org.apache.poi.hssf.record.PasswordRecord;
import org.apache.poi.hssf.record.PasswordRev4Record;
import org.apache.poi.hssf.record.PrecisionRecord;
import org.apache.poi.hssf.record.ProtectRecord;
import org.apache.poi.hssf.record.ProtectionRev4Record;
import org.apache.poi.hssf.record.RecalcIdRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RefreshAllRecord;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StyleRecord;
import org.apache.poi.hssf.record.SupBookRecord;
import org.apache.poi.hssf.record.TabIdRecord;
import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.record.UseSelFSRecord;
import org.apache.poi.hssf.record.WindowOneRecord;
import org.apache.poi.hssf.record.WindowProtectRecord;
import org.apache.poi.hssf.record.WriteAccessRecord;
import org.apache.poi.hssf.record.WriteProtectRecord;
import org.apache.poi.ddf.*;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.SheetReferences;
@@ -2206,17 +2157,17 @@ public final class Workbook implements Model {
// contains a EscherDggRecord
for(Iterator rit = records.iterator(); rit.hasNext();) {
Record r = (Record)rit.next();
if(r instanceof DrawingGroupRecord) {
DrawingGroupRecord dg = (DrawingGroupRecord)r;
dg.processChildRecords();
EscherContainerRecord cr =
dg.getEscherContainer();
if(cr == null) {
continue;
}
EscherDggRecord dgg = null;
for(Iterator it = cr.getChildRecords().iterator(); it.hasNext();) {
Object er = it.next();
@@ -2224,7 +2175,7 @@ public final class Workbook implements Model {
dgg = (EscherDggRecord)er;
}
}
if(dgg != null) {
drawingManager = new DrawingManager2(dgg);
return;
@@ -2234,7 +2185,7 @@ public final class Workbook implements Model {

// Look for the DrawingGroup record
int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid);
// If there is one, does it have a EscherDggRecord?
if(dgLoc != -1) {
DrawingGroupRecord dg =
@@ -2246,7 +2197,7 @@ public final class Workbook implements Model {
dgg = (EscherDggRecord)er;
}
}
if(dgg != null) {
drawingManager = new DrawingManager2(dgg);
}
@@ -2455,4 +2406,54 @@ public final class Workbook implements Model {
public NameXPtg getNameXPtg(String name) {
return getOrCreateLinkTable().getNameXPtg(name);
}

/**
* Check if the cloned sheet has drawings. If yes, then allocate a new drawing group ID and
* re-generate shape IDs
*
* @param sheet the cloned sheet
*/
public void cloneDrawings(Sheet sheet){

findDrawingGroup();

if(drawingManager == null) {
//this workbook does not have drawings
return;
}

//check if the cloned sheet has drawings
int aggLoc = sheet.aggregateDrawingRecords(drawingManager, false);
if(aggLoc != -1) {
EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid);

EscherDggRecord dgg = drawingManager.getDgg();

//register a new drawing group for the cloned sheet
int dgId = drawingManager.findNewDrawingGroupId();
dgg.addCluster( dgId, 0 );
dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);

EscherDgRecord dg = null;
for(Iterator it = agg.getEscherContainer().getChildRecords().iterator(); it.hasNext();) {
Object er = it.next();
if(er instanceof EscherDgRecord) {
dg = (EscherDgRecord)er;
//update id of the drawing in the cloned sheet
dg.setOptions( (short) ( dgId << 4 ) );
} else if (er instanceof EscherContainerRecord){
//recursively find shape records and re-generate shapeId
ArrayList spRecords = new ArrayList();
EscherContainerRecord cp = (EscherContainerRecord)er;
cp.getRecordsById(EscherSpRecord.RECORD_ID, spRecords);
for(Iterator spIt = spRecords.iterator(); spIt.hasNext();) {
EscherSpRecord sp = (EscherSpRecord)spIt.next();
int shapeId = drawingManager.allocateShapeId((short)dgId, dg);
sp.setShapeId(shapeId);
}
}
}

}
}
}

+ 3
- 2
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java View File

@@ -35,6 +35,7 @@ import org.apache.poi.ddf.EscherBlipRecord;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.record.AbstractEscherHolderRecord;
import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.DrawingGroupRecord;
@@ -705,8 +706,8 @@ public class HSSFWorkbook extends POIDocument
newNameRecord.setHidden(true);
HSSFName newName = new HSSFName(this, newNameRecord);
names.add(newName);
// TODO - when an Autofilter is present, there are some DrawingRecords which also need adjusting
// In particular, some IDs of some EscherSpRecords need changing. See bug 45720
workbook.cloneDrawings(clonedSheet.getSheet());
}
// TODO - maybe same logic required for other/all built-in name records

BIN
src/testcases/org/apache/poi/hssf/data/45720.xls View File


+ 848
- 817
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
File diff suppressed because it is too large
View File


Loading…
Cancel
Save