Fix for bug 40414 - update selected/active sheet after removing sheet from workbook

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@657167 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-05-16 18:55:02 +00:00
parent e5828d77dc
commit 3ee85ee6a9
4 changed files with 121 additions and 6 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.1-beta2" date="2008-05-??">
<action dev="POI-DEVELOPERS" type="fix">40414 - fixed selected/active sheet after removing sheet from workbook</action>
<action dev="POI-DEVELOPERS" type="fix">44523 - fixed workbook sheet selection and focus</action>
<action dev="POI-DEVELOPERS" type="fix">45000 - Fixed NPE in ListLevel when numberText is null</action>
<action dev="POI-DEVELOPERS" type="fix">44985 - Properly update TextSpecInfoAtom when the parent text is changed</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1-beta2" date="2008-05-??">
<action dev="POI-DEVELOPERS" type="fix">40414 - fixed selected/active sheet after removing sheet from workbook</action>
<action dev="POI-DEVELOPERS" type="fix">44523 - fixed workbook sheet selection and focus</action>
<action dev="POI-DEVELOPERS" type="fix">45000 - Fixed NPE in ListLevel when numberText is null</action>
<action dev="POI-DEVELOPERS" type="fix">44985 - Properly update TextSpecInfoAtom when the parent text is changed</action>

View File

@ -754,14 +754,54 @@ public class HSSFWorkbook extends POIDocument
}
/**
* removes sheet at the given index
* Removes sheet at the given index.<p/>
*
* Care must be taken if the removed sheet is the currently active or only selected sheet in
* the workbook. There are a few situations when Excel must have a selection and/or active
* sheet. (For example when printing - see Bug 40414).<br/>
*
* This method makes sure that if the removed sheet was active, another sheet will become
* active in its place. Furthermore, if the removed sheet was the only selected sheet, another
* sheet will become selected. The newly active/selected sheet will have the same index, or
* one less if the removed sheet was the last in the workbook.
*
* @param index of the sheet (0-based)
*/
public void removeSheetAt(int index) {
validateSheetIndex(index);
boolean wasActive = getSheetAt(index).isActive();
boolean wasSelected = getSheetAt(index).isSelected();
public void removeSheetAt(int index)
{
sheets.remove(index);
workbook.removeSheet(index);
// set the remaining active/selected sheet
int nSheets = sheets.size();
if (nSheets < 1) {
// nothing more to do if there are no sheets left
return;
}
// the index of the closest remaining sheet to the one just deleted
int newSheetIndex = index;
if (newSheetIndex >= nSheets) {
newSheetIndex = nSheets-1;
}
if (wasActive) {
setActiveSheet(newSheetIndex);
}
if (wasSelected) {
boolean someOtherSheetIsStillSelected = false;
for (int i =0; i < nSheets; i++) {
if (getSheetAt(i).isSelected()) {
someOtherSheetIsStillSelected = true;
break;
}
}
if (!someOtherSheetIsStillSelected) {
setSelectedTab(newSheetIndex);
}
}
}
/**

View File

@ -299,8 +299,81 @@ public final class TestHSSFWorkbook extends TestCase {
}
}
public void testActiveSheetAfterDelete_bug40414() {
HSSFWorkbook wb=new HSSFWorkbook();
HSSFSheet sheet0 = wb.createSheet("Sheet0");
HSSFSheet sheet1 = wb.createSheet("Sheet1");
HSSFSheet sheet2 = wb.createSheet("Sheet2");
HSSFSheet sheet3 = wb.createSheet("Sheet3");
HSSFSheet sheet4 = wb.createSheet("Sheet4");
// confirm default activation/selection
confirmActiveSelected(sheet0, true);
confirmActiveSelected(sheet1, false);
confirmActiveSelected(sheet2, false);
confirmActiveSelected(sheet3, false);
confirmActiveSelected(sheet4, false);
wb.setActiveSheet(3);
wb.setSelectedTab(3);
confirmActiveSelected(sheet0, false);
confirmActiveSelected(sheet1, false);
confirmActiveSelected(sheet2, false);
confirmActiveSelected(sheet3, true);
confirmActiveSelected(sheet4, false);
wb.removeSheetAt(3);
// after removing the only active/selected sheet, another should be active/selected in its place
if (!sheet4.isSelected()) {
throw new AssertionFailedError("identified bug 40414 a");
}
if (!sheet4.isActive()) {
throw new AssertionFailedError("identified bug 40414 b");
}
confirmActiveSelected(sheet0, false);
confirmActiveSelected(sheet1, false);
confirmActiveSelected(sheet2, false);
confirmActiveSelected(sheet4, true);
sheet3 = sheet4; // re-align local vars in this test case
// Some more cases of removing sheets
// Starting with a multiple selection, and different active sheet
wb.setSelectedTabs(new int[] { 1, 3, });
wb.setActiveSheet(2);
confirmActiveSelected(sheet0, false, false);
confirmActiveSelected(sheet1, false, true);
confirmActiveSelected(sheet2, true, false);
confirmActiveSelected(sheet3, false, true);
// removing a sheet that is not active, and not the only selected sheet
wb.removeSheetAt(3);
confirmActiveSelected(sheet0, false, false);
confirmActiveSelected(sheet1, false, true);
confirmActiveSelected(sheet2, true, false);
// removing the only selected sheet
wb.removeSheetAt(1);
confirmActiveSelected(sheet0, false, false);
confirmActiveSelected(sheet2, true, true);
// The last remaining sheet should always be active+selected
wb.removeSheetAt(1);
confirmActiveSelected(sheet0, true, true);
}
private static void confirmActiveSelected(HSSFSheet sheet, boolean expected) {
assertEquals(expected, sheet.isActive());
assertEquals(expected, sheet.isSelected());
confirmActiveSelected(sheet, expected, expected);
}
private static void confirmActiveSelected(HSSFSheet sheet,
boolean expectedActive, boolean expectedSelected) {
assertEquals("active", expectedActive, sheet.isActive());
assertEquals("selected", expectedSelected, sheet.isSelected());
}
}