mirror of https://github.com/apache/poi.git
fixed bug #45720: cloneSheet breaks autofilters.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692893 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ba665e8b75
commit
a0cef40211
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.1.1-alpha1" date="2008-??-??">
|
<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="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="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>
|
<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>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.1.1-alpha1" date="2008-??-??">
|
<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="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="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>
|
<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>
|
||||||
|
|
|
@ -235,4 +235,21 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
return null;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,17 @@ public class DrawingManager2
|
||||||
* @return a new shape id.
|
* @return a new shape id.
|
||||||
*/
|
*/
|
||||||
public int allocateShapeId(short drawingGroupId)
|
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 );
|
dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
|
||||||
|
|
||||||
|
@ -78,7 +89,6 @@ public class DrawingManager2
|
||||||
{
|
{
|
||||||
int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
|
int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
|
||||||
c.incrementShapeId();
|
c.incrementShapeId();
|
||||||
EscherDgRecord dg = getDrawingGroup(drawingGroupId);
|
|
||||||
dg.setNumShapes( dg.getNumShapes() + 1 );
|
dg.setNumShapes( dg.getNumShapes() + 1 );
|
||||||
dg.setLastMSOSPID( result );
|
dg.setLastMSOSPID( result );
|
||||||
if (result >= dgg.getShapeIdMax())
|
if (result >= dgg.getShapeIdMax())
|
||||||
|
@ -90,7 +100,6 @@ public class DrawingManager2
|
||||||
// Create new cluster
|
// Create new cluster
|
||||||
dgg.addCluster( drawingGroupId, 0 );
|
dgg.addCluster( drawingGroupId, 0 );
|
||||||
dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
|
dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
|
||||||
EscherDgRecord dg = getDrawingGroup(drawingGroupId);
|
|
||||||
dg.setNumShapes( dg.getNumShapes() + 1 );
|
dg.setNumShapes( dg.getNumShapes() + 1 );
|
||||||
int result = (1024 * dgg.getFileIdClusters().length);
|
int result = (1024 * dgg.getFileIdClusters().length);
|
||||||
dg.setLastMSOSPID( result );
|
dg.setLastMSOSPID( result );
|
||||||
|
@ -98,7 +107,6 @@ public class DrawingManager2
|
||||||
dgg.setShapeIdMax( result + 1 );
|
dgg.setShapeIdMax( result + 1 );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////// Non-public methods /////////////
|
//////////// Non-public methods /////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,57 +22,8 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherBSERecord;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.ddf.EscherBoolProperty;
|
import org.apache.poi.hssf.record.*;
|
||||||
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.hssf.record.formula.NameXPtg;
|
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||||
import org.apache.poi.hssf.util.HSSFColor;
|
import org.apache.poi.hssf.util.HSSFColor;
|
||||||
import org.apache.poi.hssf.util.SheetReferences;
|
import org.apache.poi.hssf.util.SheetReferences;
|
||||||
|
@ -2455,4 +2406,54 @@ public final class Workbook implements Model {
|
||||||
public NameXPtg getNameXPtg(String name) {
|
public NameXPtg getNameXPtg(String name) {
|
||||||
return getOrCreateLinkTable().getNameXPtg(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.poi.ddf.EscherBlipRecord;
|
||||||
import org.apache.poi.ddf.EscherRecord;
|
import org.apache.poi.ddf.EscherRecord;
|
||||||
import org.apache.poi.hssf.model.Sheet;
|
import org.apache.poi.hssf.model.Sheet;
|
||||||
import org.apache.poi.hssf.model.Workbook;
|
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.AbstractEscherHolderRecord;
|
||||||
import org.apache.poi.hssf.record.BackupRecord;
|
import org.apache.poi.hssf.record.BackupRecord;
|
||||||
import org.apache.poi.hssf.record.DrawingGroupRecord;
|
import org.apache.poi.hssf.record.DrawingGroupRecord;
|
||||||
|
@ -705,8 +706,8 @@ public class HSSFWorkbook extends POIDocument
|
||||||
newNameRecord.setHidden(true);
|
newNameRecord.setHidden(true);
|
||||||
HSSFName newName = new HSSFName(this, newNameRecord);
|
HSSFName newName = new HSSFName(this, newNameRecord);
|
||||||
names.add(newName);
|
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
|
// TODO - maybe same logic required for other/all built-in name records
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -28,14 +28,10 @@ import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.model.Sheet;
|
import org.apache.poi.hssf.model.Sheet;
|
||||||
import org.apache.poi.hssf.record.HCenterRecord;
|
import org.apache.poi.hssf.model.DrawingManager2;
|
||||||
import org.apache.poi.hssf.record.PasswordRecord;
|
import org.apache.poi.hssf.record.*;
|
||||||
import org.apache.poi.hssf.record.ProtectRecord;
|
|
||||||
import org.apache.poi.hssf.record.SCLRecord;
|
|
||||||
import org.apache.poi.hssf.record.VCenterRecord;
|
|
||||||
import org.apache.poi.hssf.record.WSBoolRecord;
|
|
||||||
import org.apache.poi.hssf.record.WindowTwoRecord;
|
|
||||||
import org.apache.poi.hssf.util.CellRangeAddress;
|
import org.apache.poi.hssf.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.ddf.EscherDgRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests HSSFSheet. This test case is very incomplete at the moment.
|
* Tests HSSFSheet. This test case is very incomplete at the moment.
|
||||||
|
@ -856,4 +852,39 @@ public final class TestHSSFSheet extends TestCase {
|
||||||
|
|
||||||
HSSFTestDataSamples.writeOutAndReadBack(wb);
|
HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we clone a sheet containing drawings,
|
||||||
|
* we must allocate a new ID of the drawing group and re-create shape IDs
|
||||||
|
*
|
||||||
|
* See bug #45720.
|
||||||
|
*/
|
||||||
|
public void testCloneSheetWithDrawings() {
|
||||||
|
HSSFWorkbook wb1 = HSSFTestDataSamples.openSampleWorkbook("45720.xls");
|
||||||
|
|
||||||
|
HSSFSheet sheet1 = wb1.getSheetAt(0);
|
||||||
|
|
||||||
|
wb1.getWorkbook().findDrawingGroup();
|
||||||
|
DrawingManager2 dm1 = wb1.getWorkbook().getDrawingManager();
|
||||||
|
|
||||||
|
wb1.cloneSheet(0);
|
||||||
|
|
||||||
|
HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
|
||||||
|
wb2.getWorkbook().findDrawingGroup();
|
||||||
|
DrawingManager2 dm2 = wb2.getWorkbook().getDrawingManager();
|
||||||
|
|
||||||
|
//check EscherDggRecord - a workbook-level registry of drawing objects
|
||||||
|
assertEquals(dm1.getDgg().getMaxDrawingGroupId() + 1, dm2.getDgg().getMaxDrawingGroupId());
|
||||||
|
|
||||||
|
HSSFSheet sheet2 = wb2.getSheetAt(1);
|
||||||
|
|
||||||
|
//check that id of the drawing group was updated
|
||||||
|
EscherDgRecord dg1 = (EscherDgRecord)sheet1.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
|
||||||
|
EscherDgRecord dg2 = (EscherDgRecord)sheet2.getDrawingEscherAggregate().findFirstWithId(EscherDgRecord.RECORD_ID);
|
||||||
|
int dg_id_1 = dg1.getOptions() >> 4;
|
||||||
|
int dg_id_2 = dg2.getOptions() >> 4;
|
||||||
|
assertEquals(dg_id_1 + 1, dg_id_2);
|
||||||
|
|
||||||
|
//TODO: check shapeId in the cloned sheet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue