44523 - fixed workbook sheet selection and focus

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@656893 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-05-15 23:30:08 +00:00
parent 42b0a779b5
commit 3524eaad44
7 changed files with 206 additions and 82 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! --> <!-- Don't forget to update status.xml too! -->
<release version="3.1-beta2" date="2008-05-??"> <release version="3.1-beta2" date="2008-05-??">
<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">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> <action dev="POI-DEVELOPERS" type="fix">44985 - Properly update TextSpecInfoAtom when the parent text is changed</action>
<action dev="POI-DEVELOPERS" type="fix">41187 - fixed HSSFSheet to properly read xls files without ROW records</action> <action dev="POI-DEVELOPERS" type="fix">41187 - fixed HSSFSheet to properly read xls files without ROW records</action>

View File

@ -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-beta2" date="2008-05-??"> <release version="3.1-beta2" date="2008-05-??">
<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">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> <action dev="POI-DEVELOPERS" type="fix">44985 - Properly update TextSpecInfoAtom when the parent text is changed</action>
<action dev="POI-DEVELOPERS" type="fix">41187 - fixed HSSFSheet to properly read xls files without ROW records</action> <action dev="POI-DEVELOPERS" type="fix">41187 - fixed HSSFSheet to properly read xls files without ROW records</action>

View File

@ -2131,6 +2131,9 @@ public final class Sheet implements Model {
return header; return header;
} }
public WindowTwoRecord getWindowTwo() {
return windowTwo;
}
/** /**
* Sets the HeaderRecord. * Sets the HeaderRecord.
* @param newHeader The new HeaderRecord for the sheet. * @param newHeader The new HeaderRecord for the sheet.

View File

@ -57,8 +57,8 @@ public class WindowOneRecord
BitFieldFactory.getInstance(0x20); // display tabs at the bottom BitFieldFactory.getInstance(0x20); // display tabs at the bottom
// all the rest are "reserved" // all the rest are "reserved"
private short field_6_selected_tab; private int field_6_active_sheet;
private short field_7_displayed_tab; private int field_7_first_visible_tab;
private short field_8_num_selected_tabs; private short field_8_num_selected_tabs;
private short field_9_tab_width_ratio; private short field_9_tab_width_ratio;
@ -91,8 +91,8 @@ public class WindowOneRecord
field_3_width = in.readShort(); field_3_width = in.readShort();
field_4_height = in.readShort(); field_4_height = in.readShort();
field_5_options = in.readShort(); field_5_options = in.readShort();
field_6_selected_tab = in.readShort(); field_6_active_sheet = in.readShort();
field_7_displayed_tab = in.readShort(); field_7_first_visible_tab = in.readShort();
field_8_num_selected_tabs = in.readShort(); field_8_num_selected_tabs = in.readShort();
field_9_tab_width_ratio = in.readShort(); field_9_tab_width_ratio = in.readShort();
} }
@ -202,24 +202,33 @@ public class WindowOneRecord
// end bitfields // end bitfields
public void setActiveSheetIndex(int index) {
field_6_active_sheet = index;
}
/** /**
* set the selected tab number * deprecated May 2008
* @param s tab number * @deprecated - Misleading name - use setActiveSheetIndex()
*/ */
public void setSelectedTab(short s) public void setSelectedTab(short s)
{ {
field_6_selected_tab = s; setActiveSheetIndex(s);
} }
/** /**
* set the displayed tab number * Sets the first visible sheet in the worksheet tab-bar. This method does <b>not</b>
* @param t tab number * hide, select or focus sheets. It just sets the scroll position in the tab-bar.
* @param t the sheet index of the tab that will become the first in the tab-bar
*/ */
public void setFirstVisibleTab(int t) {
field_7_first_visible_tab = t;
}
public void setDisplayedTab(short t) /**
{ * deprecated May 2008
field_7_displayed_tab = t; * @deprecated - Misleading name - use setFirstVisibleTab()
*/
public void setDisplayedTab(short t) {
setFirstVisibleTab(t);
} }
/** /**
@ -347,24 +356,36 @@ public class WindowOneRecord
// end options bitfields // end options bitfields
/**
* get the selected tab number
* @return Tab number
*/
/**
* @return the index of the currently displayed sheet
*/
public int getActiveSheetIndex() {
return field_6_active_sheet;
}
/**
* deprecated May 2008
* @deprecated - Misleading name - use getActiveSheetIndex()
*/
public short getSelectedTab() public short getSelectedTab()
{ {
return field_6_selected_tab; return (short) getActiveSheetIndex();
} }
/** /**
* get the displayed tab number * @return the first visible sheet in the worksheet tab-bar.
* @return Tab number * I.E. the scroll position of the tab-bar.
*/
public int getFirstVisibleTab() {
return field_7_first_visible_tab;
}
/**
* deprecated May 2008
* @deprecated - Misleading name - use getFirstVisibleTab()
*/ */
public short getDisplayedTab() public short getDisplayedTab()
{ {
return field_7_displayed_tab; return (short) getFirstVisibleTab();
} }
/** /**
@ -412,10 +433,10 @@ public class WindowOneRecord
.append(getDisplayVerticalScrollbar()).append("\n"); .append(getDisplayVerticalScrollbar()).append("\n");
buffer.append(" .tabs = ").append(getDisplayTabs()) buffer.append(" .tabs = ").append(getDisplayTabs())
.append("\n"); .append("\n");
buffer.append(" .selectedtab = ") buffer.append(" .activeSheet = ")
.append(Integer.toHexString(getSelectedTab())).append("\n"); .append(Integer.toHexString(getActiveSheetIndex())).append("\n");
buffer.append(" .displayedtab = ") buffer.append(" .firstVisibleTab = ")
.append(Integer.toHexString(getDisplayedTab())).append("\n"); .append(Integer.toHexString(getFirstVisibleTab())).append("\n");
buffer.append(" .numselectedtabs = ") buffer.append(" .numselectedtabs = ")
.append(Integer.toHexString(getNumSelectedTabs())).append("\n"); .append(Integer.toHexString(getNumSelectedTabs())).append("\n");
buffer.append(" .tabwidthratio = ") buffer.append(" .tabwidthratio = ")
@ -434,8 +455,8 @@ public class WindowOneRecord
LittleEndian.putShort(data, 8 + offset, getWidth()); LittleEndian.putShort(data, 8 + offset, getWidth());
LittleEndian.putShort(data, 10 + offset, getHeight()); LittleEndian.putShort(data, 10 + offset, getHeight());
LittleEndian.putShort(data, 12 + offset, getOptions()); LittleEndian.putShort(data, 12 + offset, getOptions());
LittleEndian.putShort(data, 14 + offset, getSelectedTab()); LittleEndian.putUShort(data, 14 + offset, getActiveSheetIndex());
LittleEndian.putShort(data, 16 + offset, getDisplayedTab()); LittleEndian.putUShort(data, 16 + offset, getFirstVisibleTab());
LittleEndian.putShort(data, 18 + offset, getNumSelectedTabs()); LittleEndian.putShort(data, 18 + offset, getNumSelectedTabs());
LittleEndian.putShort(data, 20 + offset, getTabWidthRatio()); LittleEndian.putShort(data, 20 + offset, getTabWidthRatio());
return getRecordSize(); return getRecordSize();

View File

@ -54,7 +54,7 @@ public class WindowTwoRecord
private BitField displayGuts = BitFieldFactory.getInstance(0x80); private BitField displayGuts = BitFieldFactory.getInstance(0x80);
private BitField freezePanesNoSplit = BitFieldFactory.getInstance(0x100); private BitField freezePanesNoSplit = BitFieldFactory.getInstance(0x100);
private BitField selected = BitFieldFactory.getInstance(0x200); private BitField selected = BitFieldFactory.getInstance(0x200);
private BitField paged = BitFieldFactory.getInstance(0x400); private BitField active = BitFieldFactory.getInstance(0x400);
private BitField savedInPageBreakPreview = BitFieldFactory.getInstance(0x800); private BitField savedInPageBreakPreview = BitFieldFactory.getInstance(0x800);
// 4-7 reserved // 4-7 reserved
@ -222,12 +222,16 @@ public class WindowTwoRecord
* is the sheet currently displayed in the window * is the sheet currently displayed in the window
* @param p displayed or not * @param p displayed or not
*/ */
public void setActive(boolean p) {
public void setPaged(boolean p) field_1_options = active.setShortBoolean(field_1_options, p);
{ }
field_1_options = paged.setShortBoolean(field_1_options, p); /**
* deprecated May 2008
* @deprecated use setActive()
*/
public void setPaged(boolean p) {
setActive(p);
} }
/** /**
* was the sheet saved in page break view * was the sheet saved in page break view
* @param p pagebreaksaved or not * @param p pagebreaksaved or not
@ -416,9 +420,15 @@ public class WindowTwoRecord
* @return displayed or not * @return displayed or not
*/ */
public boolean getPaged() public boolean isActive() {
{ return active.isSet(field_1_options);
return paged.isSet(field_1_options); }
/**
* deprecated May 2008
* @deprecated use isActive()
*/
public boolean getPaged() {
return isActive();
} }
/** /**
@ -520,7 +530,7 @@ public class WindowTwoRecord
.append(getFreezePanesNoSplit()).append("\n"); .append(getFreezePanesNoSplit()).append("\n");
buffer.append(" .selected = ").append(getSelected()) buffer.append(" .selected = ").append(getSelected())
.append("\n"); .append("\n");
buffer.append(" .paged = ").append(getPaged()) buffer.append(" .active = ").append(isActive())
.append("\n"); .append("\n");
buffer.append(" .svdinpgbrkpv= ") buffer.append(" .svdinpgbrkpv= ")
.append(getSavedInPageBreakPreview()).append("\n"); .append(getSavedInPageBreakPreview()).append("\n");

View File

@ -977,13 +977,34 @@ public final class HSSFSheet {
return new HSSFFooter( getSheet().getFooter() ); return new HSSFFooter( getSheet().getFooter() );
} }
/**
* Note - this is not the same as whether the sheet is focused (isActive)
* @return <code>true</code> if this sheet is currently selected
*/
public boolean isSelected() {
return getSheet().getWindowTwo().getSelected();
}
/** /**
* Sets whether sheet is selected. * Sets whether sheet is selected.
* @param sel Whether to select the sheet or deselect the sheet. * @param sel Whether to select the sheet or deselect the sheet.
*/ */
public void setSelected( boolean sel ) public void setSelected( boolean sel )
{ {
getSheet().setSelected( sel ); getSheet().getWindowTwo().setSelected(sel);
}
/**
* @return <code>true</code> if this sheet is currently focused
*/
public boolean isActive() {
return getSheet().getWindowTwo().isActive();
}
/**
* Sets whether sheet is selected.
* @param sel Whether to select the sheet or deselect the sheet.
*/
public void setActive(boolean sel )
{
getSheet().getWindowTwo().setActive(sel);
} }
/** /**

View File

@ -365,16 +365,66 @@ public class HSSFWorkbook extends POIDocument
workbook.setSheetOrder(sheetname, pos); workbook.setSheetOrder(sheetname, pos);
} }
private void validateSheetIndex(int index) {
int lastSheetIx = sheets.size() - 1;
if (index < 0 || index > lastSheetIx) {
throw new IllegalArgumentException("Sheet index ("
+ index +") is out of range (0.." + lastSheetIx + ")");
}
}
/** /**
* sets the tab whose data is actually seen when the sheet is opened. * Selects a single sheet. This may be different to
* This may be different from the "selected sheet" since excel seems to * the 'active' sheet (which is the sheet with focus).
* allow you to show the data of one sheet when another is seen "selected" */
* in the tabs (at the bottom). public void setSelectedTab(int index) {
* @see org.apache.poi.hssf.usermodel.HSSFSheet#setSelected(boolean)
* @param index validateSheetIndex(index);
int nSheets = sheets.size();
for (int i=0; i<nSheets; i++) {
getSheetAt(i).setSelected(i == index);
}
workbook.getWindowOne().setNumSelectedTabs((short)1);
}
/**
* deprecated May 2008
* @deprecated use setSelectedTab(int)
*/ */
public void setSelectedTab(short index) { public void setSelectedTab(short index) {
workbook.getWindowOne().setSelectedTab(index); setSelectedTab((int)index);
}
public void setSelectedTabs(int[] indexes) {
for (int i = 0; i < indexes.length; i++) {
validateSheetIndex(indexes[i]);
}
int nSheets = sheets.size();
for (int i=0; i<nSheets; i++) {
boolean bSelect = false;
for (int j = 0; j < indexes.length; j++) {
if (indexes[j] == i) {
bSelect = true;
break;
}
}
getSheetAt(i).setSelected(bSelect);
}
workbook.getWindowOne().setNumSelectedTabs((short)indexes.length);
}
/**
* Convenience method to set the active sheet. The active sheet is is the sheet
* which is currently displayed when the workbook is viewed in Excel.
* 'Selected' sheet(s) is a distinct concept.
*/
public void setActiveSheet(int index) {
validateSheetIndex(index);
int nSheets = sheets.size();
for (int i=0; i<nSheets; i++) {
getSheetAt(i).setActive(i == index);
}
workbook.getWindowOne().setActiveSheetIndex(index);
} }
/** /**
@ -384,25 +434,46 @@ public class HSSFWorkbook extends POIDocument
* in the tabs (at the bottom). * in the tabs (at the bottom).
* @see org.apache.poi.hssf.usermodel.HSSFSheet#setSelected(boolean) * @see org.apache.poi.hssf.usermodel.HSSFSheet#setSelected(boolean)
*/ */
public short getSelectedTab() { public int getActiveSheetIndex() {
return workbook.getWindowOne().getSelectedTab(); return workbook.getWindowOne().getActiveSheetIndex();
} }
/**
* deprecated May 2008
* @deprecated - Misleading name - use getActiveSheetIndex()
*/
public short getSelectedTab() {
return (short) getActiveSheetIndex();
}
/** /**
* sets the first tab that is displayed in the list of tabs * sets the first tab that is displayed in the list of tabs
* in excel. * in excel.
* @param index * @param index
*/ */
public void setFirstVisibleTab(int index) {
workbook.getWindowOne().setFirstVisibleTab(index);
}
/**
* deprecated May 2008
* @deprecated - Misleading name - use setFirstVisibleTab()
*/
public void setDisplayedTab(short index) { public void setDisplayedTab(short index) {
workbook.getWindowOne().setDisplayedTab(index); setFirstVisibleTab(index);
} }
/** /**
* sets the first tab that is displayed in the list of tabs * sets the first tab that is displayed in the list of tabs in excel.
* in excel. */
public int getFirstVisibleTab() {
return workbook.getWindowOne().getFirstVisibleTab();
}
/**
* deprecated May 2008
* @deprecated - Misleading name - use getFirstVisibleTab()
*/ */
public short getDisplayedTab() { public short getDisplayedTab() {
return workbook.getWindowOne().getDisplayedTab(); return (short) getFirstVisibleTab();
} }
/** /**
@ -563,17 +634,13 @@ public class HSSFWorkbook extends POIDocument
public HSSFSheet createSheet() public HSSFSheet createSheet()
{ {
// if (getNumberOfSheets() == 3)
// throw new RuntimeException("You cannot have more than three sheets in HSSF 1.0");
HSSFSheet sheet = new HSSFSheet(this); HSSFSheet sheet = new HSSFSheet(this);
sheets.add(sheet); sheets.add(sheet);
workbook.setSheetName(sheets.size() - 1, workbook.setSheetName(sheets.size() - 1, "Sheet" + (sheets.size() - 1));
"Sheet" + (sheets.size() - 1)); boolean isOnlySheet = sheets.size() == 1;
WindowTwoRecord windowTwo = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid); sheet.setSelected(isOnlySheet);
windowTwo.setSelected(sheets.size() == 1); sheet.setActive(isOnlySheet);
windowTwo.setPaged(sheets.size() == 1);
return sheet; return sheet;
} }
@ -584,23 +651,24 @@ public class HSSFWorkbook extends POIDocument
*/ */
public HSSFSheet cloneSheet(int sheetNum) { public HSSFSheet cloneSheet(int sheetNum) {
HSSFSheet srcSheet = (HSSFSheet)sheets.get(sheetNum); validateSheetIndex(sheetNum);
HSSFSheet srcSheet = (HSSFSheet) sheets.get(sheetNum);
String srcName = workbook.getSheetName(sheetNum); String srcName = workbook.getSheetName(sheetNum);
if (srcSheet != null) {
HSSFSheet clonedSheet = srcSheet.cloneSheet(this); HSSFSheet clonedSheet = srcSheet.cloneSheet(this);
WindowTwoRecord windowTwo = (WindowTwoRecord) clonedSheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid); clonedSheet.setSelected(false);
windowTwo.setSelected(sheets.size() == 1); clonedSheet.setActive(false);
windowTwo.setPaged(sheets.size() == 1);
sheets.add(clonedSheet); sheets.add(clonedSheet);
int i=1; int i = 1;
while (true) { while (true) {
//Try and find the next sheet name that is unique // Try and find the next sheet name that is unique
String name = srcName; String name = srcName;
String index = Integer.toString(i++); String index = Integer.toString(i++);
if (name.length()+index.length()+2<31) if (name.length() + index.length() + 2 < 31) {
name = name + "("+index+")"; name = name + "(" + index + ")";
else name = name.substring(0, 31-index.length()-2)+"("+index+")"; } else {
name = name.substring(0, 31 - index.length() - 2) + "(" + index + ")";
}
//If the sheet name is unique, then set it otherwise move on to the next number. //If the sheet name is unique, then set it otherwise move on to the next number.
if (workbook.getSheetIndex(name) == -1) { if (workbook.getSheetIndex(name) == -1) {
@ -610,16 +678,16 @@ public class HSSFWorkbook extends POIDocument
} }
return clonedSheet; return clonedSheet;
} }
return null;
}
/** /**
* create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and returns * create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and
* the high level representation. Use this to create new sheets. * returns the high level representation. Use this to create new sheets.
* *
* @param sheetname sheetname to set for the sheet. * @param sheetname
* sheetname to set for the sheet.
* @return HSSFSheet representing the new sheet. * @return HSSFSheet representing the new sheet.
* @throws IllegalArgumentException if there is already a sheet present with a case-insensitive * @throws IllegalArgumentException
* if there is already a sheet present with a case-insensitive
* match for the specified name. * match for the specified name.
*/ */
@ -632,9 +700,9 @@ public class HSSFWorkbook extends POIDocument
sheets.add(sheet); sheets.add(sheet);
workbook.setSheetName(sheets.size() - 1, sheetname); workbook.setSheetName(sheets.size() - 1, sheetname);
WindowTwoRecord windowTwo = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid); boolean isOnlySheet = sheets.size() == 1;
windowTwo.setSelected(sheets.size() == 1); sheet.setSelected(isOnlySheet);
windowTwo.setPaged(sheets.size() == 1); sheet.setActive(isOnlySheet);
return sheet; return sheet;
} }
@ -834,8 +902,7 @@ public class HSSFWorkbook extends POIDocument
HSSFPrintSetup printSetup = sheet.getPrintSetup(); HSSFPrintSetup printSetup = sheet.getPrintSetup();
printSetup.setValidSettings(false); printSetup.setValidSettings(false);
WindowTwoRecord w2 = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid); sheet.setActive(true);
w2.setPaged(true);
} }
private NameRecord findExistingRowColHeaderNameRecord( int sheetIndex ) private NameRecord findExistingRowColHeaderNameRecord( int sheetIndex )