/* ====================================================================
Licensed to the Apache Software Foundation (ASF) Under one or more
contributor license agreements. See the NOTICE file distributed with
this work for Additional information regarding copyright ownership.
The ASF licenses this file to You Under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed Under the License is distributed on an "AS Is" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations Under the License.
==================================================================== */
namespace HH.WMS.Utils.NPOI.HSSF.Record.Aggregates
{
using System;
using System.Text;
using System.Collections;
using HH.WMS.Utils.NPOI.DDF;
using HH.WMS.Utils.NPOI.Util;
using HH.WMS.Utils.NPOI.HSSF.Record;
using HH.WMS.Utils.NPOI.SS.Formula;
using HH.WMS.Utils.NPOI.HSSF.Model;
using HH.WMS.Utils.NPOI.SS.Formula.PTG;
/**
*
* Aggregate value records toGether. Things are easier to handle that way.
*
* @author andy
* @author Glen Stampoultzis (glens at apache.org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
public class ValueRecordsAggregate
{
const int MAX_ROW_INDEX = 0XFFFF;
const int INDEX_NOT_SET = -1;
public const short sid = -1001; // 1000 clashes with RowRecordsAggregate
int firstcell = INDEX_NOT_SET;
int lastcell = INDEX_NOT_SET;
CellValueRecordInterface[][] records;
/** Creates a new instance of ValueRecordsAggregate */
public ValueRecordsAggregate():
this(INDEX_NOT_SET, INDEX_NOT_SET, new CellValueRecordInterface[30][]) // We start with 30 Rows.
{
}
private ValueRecordsAggregate(int firstCellIx, int lastCellIx, CellValueRecordInterface[][] pRecords)
{
firstcell = firstCellIx;
lastcell = lastCellIx;
records = pRecords;
}
public void InsertCell(CellValueRecordInterface cell)
{
int column = cell.Column;
int row = cell.Row;
if (row >= records.Length)
{
CellValueRecordInterface[][] oldRecords = records;
int newSize = oldRecords.Length * 2;
if (newSize < row + 1) newSize = row + 1;
records = new CellValueRecordInterface[newSize][];
Array.Copy(oldRecords, 0, records, 0, oldRecords.Length);
}
object objRowCells = records[row];
if (objRowCells == null)
{
int newSize = column + 1;
if (newSize < 10) newSize = 10;
objRowCells = new CellValueRecordInterface[newSize];
records[row] = (CellValueRecordInterface[])objRowCells;
}
CellValueRecordInterface[] rowCells = (CellValueRecordInterface[])objRowCells;
if (column >= rowCells.Length)
{
CellValueRecordInterface[] oldRowCells = rowCells;
int newSize = oldRowCells.Length * 2;
if (newSize < column + 1) newSize = column + 1;
// if(newSize>257) newSize=257; // activate?
rowCells = new CellValueRecordInterface[newSize];
Array.Copy(oldRowCells, 0, rowCells, 0, oldRowCells.Length);
records[row] = rowCells;
}
rowCells[column] = cell;
if ((column < firstcell) || (firstcell == -1))
{
firstcell = column;
}
if ((column > lastcell) || (lastcell == -1))
{
lastcell = column;
}
}
public void RemoveCell(CellValueRecordInterface cell)
{
if (cell == null)
{
throw new ArgumentException("cell must not be null");
}
int row = cell.Row;
if (row >= records.Length)
{
throw new Exception("cell row is out of range");
}
CellValueRecordInterface[] rowCells = records[row];
if (rowCells == null)
{
throw new Exception("cell row is already empty");
}
int column = cell.Column;
if (column >= rowCells.Length)
{
throw new Exception("cell column is out of range");
}
rowCells[column] = null;
}
public void RemoveAllCellsValuesForRow(int rowIndex)
{
if (rowIndex < 0 || rowIndex > MAX_ROW_INDEX)
{
throw new ArgumentException("Specified rowIndex " + rowIndex
+ " is outside the allowable range (0.." + MAX_ROW_INDEX + ")");
}
if (rowIndex >= records.Length)
{
// this can happen when the client code has created a row,
// and then removes/replaces it before adding any cells. (see bug 46312)
return;
}
records[rowIndex] = null;
}
public CellValueRecordInterface[] GetValueRecords()
{
ArrayList temp = new ArrayList();
for (int i = 0; i < records.Length; i++)
{
CellValueRecordInterface[] rowCells = records[i];
if (rowCells == null)
{
continue;
}
for (int j = 0; j < rowCells.Length; j++)
{
CellValueRecordInterface cell = rowCells[j];
if (cell != null)
{
temp.Add(cell);
}
}
}
return (CellValueRecordInterface[])temp.ToArray(typeof(CellValueRecordInterface));
}
public int PhysicalNumberOfCells
{
get
{
int count = 0;
for (int r = 0; r < records.Length; r++)
{
CellValueRecordInterface[] rowCells = records[r];
if (rowCells != null)
for (short c = 0; c < rowCells.Length; c++)
{
if (rowCells[c] != null) count++;
}
}
return count;
}
}
public int FirstCellNum
{
get
{
return firstcell;
}
}
public int LastCellNum
{
get
{
return lastcell;
}
}
public void AddMultipleBlanks(MulBlankRecord mbr)
{
for (int j = 0; j < mbr.NumColumns; j++)
{
BlankRecord br = new BlankRecord();
br.Column = j + mbr.FirstColumn;
br.Row = mbr.Row;
br.XFIndex = (mbr.GetXFAt(j));
InsertCell(br);
}
}
private MulBlankRecord CreateMBR(CellValueRecordInterface[] cellValues, int startIx, int nBlank)
{
short[] xfs = new short[nBlank];
for (int i = 0; i < xfs.Length; i++)
{
xfs[i] = ((BlankRecord)cellValues[startIx + i]).XFIndex;
}
int rowIx = cellValues[startIx].Row;
return new MulBlankRecord(rowIx, startIx, xfs);
}
public void Construct(CellValueRecordInterface rec, RecordStream rs, SharedValueManager sfh)
{
if (rec is FormulaRecord)
{
FormulaRecord formulaRec = (FormulaRecord)rec;
// read optional cached text value
StringRecord cachedText=null;
Type nextClass = rs.PeekNextClass();
if (nextClass == typeof(StringRecord))
{
cachedText = (StringRecord)rs.GetNext();
}
else
{
cachedText = null;
}
InsertCell(new FormulaRecordAggregate(formulaRec, cachedText, sfh));
}
else
{
InsertCell(rec);
}
}
/**
* Sometimes the shared formula flag "seems" to be erroneously Set, in which case there is no
* call to
* As it turns out, this is not a problem, because in these circumstances, the existing value
* for