diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas
index 94b842b62..4683403ca 100755
--- a/components/fpspreadsheet/fpsopendocument.pas
+++ b/components/fpspreadsheet/fpsopendocument.pas
@@ -2961,6 +2961,7 @@ var
sheet: TsWorksheet;
vsm, hsm, hsp, vsp: Integer;
showGrid, showHeaders: Boolean;
+ actCol, actRow: Cardinal;
i: Integer;
begin
showGrid := true;
@@ -3027,14 +3028,14 @@ begin
begin
cfgName := GetAttrValue(node, 'config:name');
cfgValue := GetNodeValue(node);
- if cfgName = 'VerticalSplitMode' then
- vsm := StrToInt(cfgValue)
- else if cfgName = 'HorizontalSplitMode' then
- hsm := StrToInt(cfgValue)
- else if cfgName = 'VerticalSplitPosition' then
- vsp := StrToInt(cfgValue)
- else if cfgName = 'HorizontalSplitPosition' then
- hsp := StrToInt(cfgValue);
+ case cfgName of
+ 'CursorPositionX': actCol := StrToInt(cfgValue);
+ 'CursorPositionY': actRow := StrToInt(cfgValue);
+ 'VerticalSplitMode': vsm := StrToInt(cfgValue);
+ 'HorizontalSplitMode': hsm := StrToInt(cfgValue);
+ 'VerticalSplitPosition': vsp := StrToInt(cfgValue);
+ 'HorizontalSplitPosition': hsp := StrToInt(cfgValue);
+ end;
end;
node := node.NextSibling;
end;
@@ -3046,6 +3047,8 @@ begin
end else
sheet.Options := sheet.Options - [soHasFrozenPanes];
end;
+ // Active cell
+ sheet.SelectCell(actRow, actCol);
end;
end;
cfgTableItemNode := cfgTableItemNode.NextSibling;
@@ -5023,9 +5026,10 @@ procedure TsSpreadOpenDocWriter.WriteTableSettings(AStream: TStream);
var
i: Integer;
sheet: TsWorkSheet;
- hsm: Integer; // HorizontalSplitMode
- vsm: Integer; // VerticalSplitMode
- asr: Integer; // ActiveSplitRange
+ hsm: Integer; // HorizontalSplitMode
+ vsm: Integer; // VerticalSplitMode
+ asr: Integer; // ActiveSplitRange
+ actX, actY: Integer; // Active cell col/row index
begin
for i:=0 to Workbook.GetWorksheetCount-1 do
begin
@@ -5051,10 +5055,20 @@ begin
end;
{showGrid := (soShowGridLines in sheet.Options);}
+ if (sheet.ActiveCellRow <> cardinal(-1)) and (sheet.ActiveCellCol <> cardinal(-1)) then
+ begin
+ actX := sheet.ActiveCellCol;
+ actY := sheet.ActiveCellRow;
+ end else
+ begin
+ actX := sheet.LeftPaneWidth;
+ actY := sheet.TopPaneHeight;
+ end;
+
AppendToStream(AStream,
- ''+IntToStr(sheet.LeftPaneWidth)+'');
+ ''+IntToStr(actX)+'');
AppendToStream(AStream,
- ''+IntToStr(sheet.TopPaneHeight)+'');
+ ''+IntToStr(actY)+'');
AppendToStream(AStream,
''+IntToStr(hsm)+'');
AppendToStream(AStream,
diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas
index 4308bc16b..d22834789 100755
--- a/components/fpspreadsheet/xlsbiff2.pas
+++ b/components/fpspreadsheet/xlsbiff2.pas
@@ -504,6 +504,7 @@ begin
INT_EXCEL_ID_PRINTHEADERS: ReadPrintHeaders(AStream);
INT_EXCEL_ID_RIGHTMARGIN : ReadMargin(AStream, 1);
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
+ INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
INT_EXCEL_ID_TOPMARGIN : ReadMargin(AStream, 2);
INT_EXCEL_ID_DEFROWHEIGHT: ReadDefRowHeight(AStream);
diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas
index 853980582..e6be37d0f 100755
--- a/components/fpspreadsheet/xlsbiff5.pas
+++ b/components/fpspreadsheet/xlsbiff5.pas
@@ -431,6 +431,7 @@ begin
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
INT_EXCEL_ID_RSTRING : ReadRString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
+ INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
INT_EXCEL_ID_SHEETPR : ReadSHEETPR(AStream);
INT_EXCEL_ID_STANDARDWIDTH : ReadStandardWidth(AStream, FWorksheet);
diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas
index b8f794a3c..62ec4775e 100755
--- a/components/fpspreadsheet/xlsbiff8.pas
+++ b/components/fpspreadsheet/xlsbiff8.pas
@@ -819,6 +819,7 @@ begin
// This record replaces the record INTEGER written in BIFF2.
INT_EXCEL_ID_RK : ReadRKValue(AStream);
+ INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
INT_EXCEL_ID_SHEETPR : ReadSHEETPR(AStream);
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas
index 45a2bfd55..5a6778b85 100644
--- a/components/fpspreadsheet/xlscommon.pas
+++ b/components/fpspreadsheet/xlscommon.pas
@@ -431,6 +431,7 @@ type
function ReadRPNTokenArray(AStream: TStream; ACell: PCell;
ASharedFormulaBase: PCell = nil): Boolean;
function ReadRPNTokenArraySize(AStream: TStream): word; virtual;
+ procedure ReadSELECTION(AStream: TStream);
procedure ReadSharedFormula(AStream: TStream);
procedure ReadSHEETPR(AStream: TStream);
@@ -543,7 +544,7 @@ type
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); virtual;
// Writes out a SELECTION record
- procedure WriteSelection(AStream: TStream; ASheet: TsWorksheet; APane: Byte);
+ procedure WriteSELECTION(AStream: TStream; ASheet: TsWorksheet; APane: Byte);
procedure WriteSelections(AStream: TStream; ASheet: TsWorksheet);
(*
// Writes out a shared formula
@@ -2163,6 +2164,35 @@ begin
Result := WordLEToN(AStream.ReadWord);
end;
+{@@ ----------------------------------------------------------------------------
+ Reads a SELECTION record containing the currently selected cell
+ Valid for BIFF2-BIFF8.
+-------------------------------------------------------------------------------}
+procedure TsSpreadBIFFReader.ReadSELECTION(AStream: TStream);
+var
+ actPane: byte;
+ actRow, actCol: Word;
+ rngIndex: Word;
+ i, numRanges: Word;
+begin
+ // Active pane
+ actPane := AStream.ReadByte;
+
+ // Row index of the active cell
+ actRow := WordLEToN(AStream.ReadWord);
+
+ // Column index of the active cell
+ actCol := WordLEToN(AStream.ReadWord);
+
+ // Index into the following range list which contains the active cell
+ rngIndex := WordLEToN(AStream.ReadWord);
+
+ // Count of selected ranges
+ // Selected ranges --> ignore
+
+ FWorksheet.SelectCell(actRow, actCol);
+end;
+
{@@ ----------------------------------------------------------------------------
Reads a SHAREDFMLA record, i.e. reads cell range coordinates and a rpn
formula. The formula is applied to all cells in the range. The formula is
@@ -3695,29 +3725,34 @@ end;
APane is 0..3 (see below)
Valid for BIFF2-BIFF8
-------------------------------------------------------------------------------}
-procedure TsSpreadBIFFWriter.WriteSelection(AStream: TStream;
+procedure TsSpreadBIFFWriter.WriteSELECTION(AStream: TStream;
ASheet: TsWorksheet; APane: Byte);
var
activeCellRow, activeCellCol: Word;
begin
- case APane of
- 0: begin // right-bottom
- activeCellRow := ASheet.TopPaneHeight;
- activeCellCol := ASheet.LeftPaneWidth;
- end;
- 1: begin // right-top
- activeCellRow := 0;
- activeCellCol := ASheet.LeftPaneWidth;
- end;
- 2: begin // left-bottom
- activeCellRow := ASheet.TopPaneHeight;
- activeCellCol := 0;
- end;
- 3: begin // left-top
- activeCellRow := 0;
- activeCellCol := 0;
- end;
- end;
+ if FWorkbook.ActiveWorksheet <> nil then
+ begin
+ activeCellRow := FWorksheet.ActiveCellRow;
+ activeCellCol := FWorksheet.ActiveCellCol;
+ end else
+ case APane of
+ 0: begin // right-bottom
+ activeCellRow := ASheet.TopPaneHeight;
+ activeCellCol := ASheet.LeftPaneWidth;
+ end;
+ 1: begin // right-top
+ activeCellRow := 0;
+ activeCellCol := ASheet.LeftPaneWidth;
+ end;
+ 2: begin // left-bottom
+ activeCellRow := ASheet.TopPaneHeight;
+ activeCellCol := 0;
+ end;
+ 3: begin // left-top
+ activeCellRow := 0;
+ activeCellCol := 0;
+ end;
+ end;
{ BIFF record header }
WriteBIFFHeader(AStream, INT_EXCEL_ID_SELECTION, 15);
@@ -3963,6 +3998,8 @@ end;
Valid for BIFF5-BIFF8.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFFWriter.WriteWindow1(AStream: TStream);
+var
+ actSheet: Integer;
begin
{ BIFF Record header }
WriteBIFFHeader(AStream, INT_EXCEL_ID_WINDOW1, 18);
@@ -3986,7 +4023,10 @@ begin
MASK_WINDOW1_OPTION_WORKSHEET_TAB_VISIBLE));
{ Index to active (displayed) worksheet }
- AStream.WriteWord(WordToLE($00));
+ if FWorkbook.ActiveWorksheet = nil then
+ actSheet := 0 else
+ actSheet := FWorkbook.GetWorksheetIndex(FWorkbook.ActiveWorksheet);
+ AStream.WriteWord(WordToLE(actSheet));
{ Index of first visible tab in the worksheet tab bar }
AStream.WriteWord(WordToLE($00));
diff --git a/components/fpspreadsheet/xlsxooxml.pas b/components/fpspreadsheet/xlsxooxml.pas
index 2cec876af..63e60836e 100755
--- a/components/fpspreadsheet/xlsxooxml.pas
+++ b/components/fpspreadsheet/xlsxooxml.pas
@@ -1751,6 +1751,7 @@ var
childNode: TDOMNode;
nodeName: String;
s: String;
+ actRow, actCol: Cardinal;
begin
if ANode = nil then
exit;
@@ -1778,6 +1779,14 @@ begin
s := GetAttrValue(childNode, 'ySplit');
if s <> '' then AWorksheet.TopPaneHeight := StrToInt(s);
end;
+ end else
+ if nodeName = 'selection' then begin
+ s := GetAttrValue(childnode, 'activeCell');
+ if s <> '' then
+ begin
+ ParseCellString(s, actRow, actCol);
+ AWorksheet.SelectCell(actRow, actCol);
+ end;
end;
childNode := childNode.NextSibling;
end;
@@ -3025,6 +3034,8 @@ var
topRightCell: String;
bottomLeftCell: String;
bottomRightCell: String;
+ actCell: String;
+ tabSel: String;
begin
// Show gridlines ?
showGridLines := StrUtils.IfThen(soShowGridLines in AWorksheet.Options, ' ', 'showGridLines="0" ');
@@ -3032,63 +3043,86 @@ begin
// Show headers?
showHeaders := StrUtils.IfThen(soShowHeaders in AWorksheet.Options, ' ', 'showRowColHeaders="0" ');
+ // Active cell
+ if (AWorksheet.ActiveCellRow <> cardinal(-1)) and (AWorksheet.ActiveCellCol <> cardinal(-1)) then
+ actCell := GetCellString(AWorksheet.ActiveCellRow, AWorksheet.ActiveCellCol) else
+ actCell := '';
+
+ // Selected tab?
+ tabSel := StrUtils.IfThen(AWorksheet = FWorkbook.ActiveWorksheet, 'tabSelected="1" ', '');
+
// No frozen panes
if not (soHasFrozenPanes in AWorksheet.Options) or
((AWorksheet.LeftPaneWidth = 0) and (AWorksheet.TopPaneHeight = 0))
then
+ begin
+ if actCell = '' then actCell := 'A1';
AppendToStream(AStream, Format(
'' +
- '' +
+ '' +
+ '' +
+ '' +
'', [
- showGridLines, showHeaders
+ showGridLines, showHeaders, tabSel,
+ actCell, actCell
]))
- else
+ end else
begin // Frozen panes
topRightCell := GetCellString(0, AWorksheet.LeftPaneWidth, [rfRelRow, rfRelCol]);
bottomLeftCell := GetCellString(AWorksheet.TopPaneHeight, 0, [rfRelRow, rfRelCol]);
bottomRightCell := GetCellString(AWorksheet.TopPaneHeight, AWorksheet.LeftPaneWidth, [rfRelRow, rfRelCol]);
if (AWorksheet.LeftPaneWidth > 0) and (AWorksheet.TopPaneHeight > 0) then
+ begin
+ if actCell = '' then
+ actCell := bottomRightcell;
AppendToStream(AStream, Format(
'' +
- ''+
+ ''+
'' +
'' +
'' +
'' +
'' +
'', [
- showGridLines, showHeaders,
+ showGridLines, showHeaders, tabSel,
AWorksheet.LeftPaneWidth, AWorksheet.TopPaneHeight, bottomRightCell,
topRightCell, topRightCell,
bottomLeftCell, bottomLeftCell,
- bottomRightCell, bottomrightCell
+ actCell, actCell
]))
- else
+ end else
if (AWorksheet.LeftPaneWidth > 0) then
+ begin
+ if actCell = '' then
+ actCell := topRightCell;
AppendToStream(AStream, Format(
'' +
- ''+
+ ''+
'' +
'' +
'' +
'', [
- showGridLines, showHeaders,
+ showGridLines, showHeaders, tabSel,
AWorksheet.LeftPaneWidth, topRightCell,
- topRightCell, topRightCell
+ actCell, actCell
]))
- else
+ end else
if (AWorksheet.TopPaneHeight > 0) then
+ begin
+ if actCell = '' then
+ actCell := bottomLeftCell;
AppendToStream(AStream, Format(
''+
- ''+
+ ''+
''+
'' +
''+
'', [
- showGridLines, showHeaders,
+ showGridLines, showHeaders, tabSel,
AWorksheet.TopPaneHeight, bottomLeftCell,
- bottomLeftCell, bottomLeftCell
+ actCell, actCell
]));
+ end;
end;
end;