807 lines
13 KiB
C#
807 lines
13 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using CPF.Drawing;
|
|
using CPF.ReoGrid.CellTypes;
|
|
using CPF.ReoGrid.Common;
|
|
using CPF.ReoGrid.Core;
|
|
using CPF.ReoGrid.DataFormat;
|
|
using CPF.ReoGrid.Formula;
|
|
using CPF.ReoGrid.Utility;
|
|
|
|
namespace CPF.ReoGrid
|
|
{
|
|
[Serializable]
|
|
public class Cell
|
|
{
|
|
public Worksheet Worksheet
|
|
{
|
|
get
|
|
{
|
|
return this.worksheet;
|
|
}
|
|
}
|
|
|
|
internal Cell(Worksheet worksheet)
|
|
{
|
|
this.worksheet = worksheet;
|
|
this.FontDirty = true;
|
|
}
|
|
|
|
internal int InternalRow
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Row;
|
|
}
|
|
set
|
|
{
|
|
this.InternalPos.Row = value;
|
|
}
|
|
}
|
|
|
|
internal int InternalCol
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Col;
|
|
}
|
|
set
|
|
{
|
|
this.InternalPos.Col = value;
|
|
}
|
|
}
|
|
|
|
public int Row
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Row;
|
|
}
|
|
}
|
|
|
|
public int Column
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Col;
|
|
}
|
|
}
|
|
|
|
public CellPosition Position
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos;
|
|
}
|
|
}
|
|
|
|
public RangePosition PositionAsRange
|
|
{
|
|
get
|
|
{
|
|
return new RangePosition(this.InternalRow, this.InternalCol, (int)this.rowspan, (int)this.colspan);
|
|
}
|
|
}
|
|
|
|
public string Address
|
|
{
|
|
get
|
|
{
|
|
return RGUtility.ToAddress(this.InternalPos.Row, this.InternalPos.Col, 1, 1, true);
|
|
}
|
|
}
|
|
|
|
internal short Colspan
|
|
{
|
|
get
|
|
{
|
|
return this.colspan;
|
|
}
|
|
set
|
|
{
|
|
this.colspan = value;
|
|
}
|
|
}
|
|
|
|
internal short Rowspan
|
|
{
|
|
get
|
|
{
|
|
return this.rowspan;
|
|
}
|
|
set
|
|
{
|
|
this.rowspan = value;
|
|
}
|
|
}
|
|
|
|
public short GetColspan()
|
|
{
|
|
return this.colspan;
|
|
}
|
|
|
|
public short GetRowspan()
|
|
{
|
|
return this.rowspan;
|
|
}
|
|
|
|
internal Rect Bounds
|
|
{
|
|
get
|
|
{
|
|
return this.bounds;
|
|
}
|
|
set
|
|
{
|
|
this.bounds = value;
|
|
}
|
|
}
|
|
|
|
internal float Width
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.Width;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.Width = value;
|
|
}
|
|
}
|
|
|
|
internal float Height
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.Height;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.Height = value;
|
|
}
|
|
}
|
|
|
|
internal float Top
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.Y;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.Y = value;
|
|
}
|
|
}
|
|
|
|
internal float Left
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.X;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.X = value;
|
|
}
|
|
}
|
|
|
|
internal float Right
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.Right;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.Width = this.bounds.Width + (this.bounds.Right - value);
|
|
}
|
|
}
|
|
|
|
internal float Bottom
|
|
{
|
|
get
|
|
{
|
|
return this.bounds.Bottom;
|
|
}
|
|
set
|
|
{
|
|
this.bounds.Height = this.bounds.Height + (this.bounds.Bottom - value);
|
|
}
|
|
}
|
|
|
|
public CellDataFormatFlag DataFormat
|
|
{
|
|
get
|
|
{
|
|
return this.dataFormat;
|
|
}
|
|
set
|
|
{
|
|
this.dataFormat = value;
|
|
}
|
|
}
|
|
|
|
public object DataFormatArgs
|
|
{
|
|
get
|
|
{
|
|
return this.dataFormatArgs;
|
|
}
|
|
set
|
|
{
|
|
this.dataFormatArgs = value;
|
|
}
|
|
}
|
|
|
|
internal object InnerData { get; set; }
|
|
|
|
public object Data
|
|
{
|
|
get
|
|
{
|
|
return this.InnerData;
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.worksheet != null;
|
|
if (flag)
|
|
{
|
|
this.worksheet.SetSingleCellData(this, value);
|
|
}
|
|
else
|
|
{
|
|
this.InnerData = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public T GetData<T>()
|
|
{
|
|
return CellUtility.ConvertData<T>(this.InnerData);
|
|
}
|
|
|
|
internal string InnerFormula { get; set; }
|
|
|
|
public FormulaStatus FormulaStatus
|
|
{
|
|
get
|
|
{
|
|
return this.formulaStatus;
|
|
}
|
|
}
|
|
|
|
internal string InnerDisplay { get; set; }
|
|
|
|
public string DisplayText
|
|
{
|
|
get
|
|
{
|
|
return this.InnerDisplay;
|
|
}
|
|
}
|
|
|
|
public bool IsReadOnly { get; set; }
|
|
|
|
public void StartEdit()
|
|
{
|
|
this.ValidateAssociation();
|
|
this.worksheet.StartEdit(this);
|
|
}
|
|
|
|
public void EndEdit()
|
|
{
|
|
this.ValidateAssociation();
|
|
bool flag = this.worksheet.currentEditingCell == this;
|
|
if (flag)
|
|
{
|
|
this.worksheet.EndEdit(this);
|
|
}
|
|
}
|
|
|
|
public void ExpandRowHeight()
|
|
{
|
|
this.ValidateAssociation();
|
|
this.worksheet.ExpandRowHeightToFitCell(this);
|
|
}
|
|
|
|
public void ExpandColumnWidth()
|
|
{
|
|
this.ValidateAssociation();
|
|
this.worksheet.ExpandColumnWidthFitToCell(this);
|
|
}
|
|
|
|
private void ValidateAssociation()
|
|
{
|
|
bool flag = this.worksheet == null;
|
|
if (flag)
|
|
{
|
|
throw new ReferenceObjectNotAssociatedException("Cell not associated to any worksheet.");
|
|
}
|
|
}
|
|
|
|
internal STNode FormulaTree
|
|
{
|
|
get
|
|
{
|
|
return this.formulaTree;
|
|
}
|
|
set
|
|
{
|
|
this.formulaTree = value;
|
|
}
|
|
}
|
|
|
|
public string Formula
|
|
{
|
|
get
|
|
{
|
|
return this.InnerFormula;
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.InnerFormula != value;
|
|
if (flag)
|
|
{
|
|
bool flag2 = this.Worksheet == null;
|
|
if (flag2)
|
|
{
|
|
this.InnerFormula = value;
|
|
this.InnerData = null;
|
|
this.InnerDisplay = null;
|
|
Logger.Log("cell", "Cell not attached to any worksheet: {0}", new object[]
|
|
{
|
|
this.Position.ToAddress()
|
|
});
|
|
}
|
|
else
|
|
{
|
|
bool flag3 = string.IsNullOrEmpty(value);
|
|
if (flag3)
|
|
{
|
|
this.worksheet.DeleteCellFormula(this);
|
|
}
|
|
else
|
|
{
|
|
this.worksheet.SetCellFormula(this, value);
|
|
this.worksheet.RecalcCell(this, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool HasFormula
|
|
{
|
|
get
|
|
{
|
|
return !string.IsNullOrEmpty(this.InnerFormula);
|
|
}
|
|
}
|
|
|
|
internal WorksheetRangeStyle InnerStyle { get; set; }
|
|
|
|
internal StyleParentKind StyleParentKind { get; set; }
|
|
|
|
internal void CreateOwnStyle()
|
|
{
|
|
this.InnerStyle = new WorksheetRangeStyle(this.InnerStyle);
|
|
this.StyleParentKind = StyleParentKind.Own;
|
|
bool flag = ++Cell._count % 50 == 0;
|
|
if (flag)
|
|
{
|
|
Logger.Log("style", "new style created, count: " + Cell._count.ToString());
|
|
}
|
|
}
|
|
|
|
public ReferenceCellStyle Style
|
|
{
|
|
get
|
|
{
|
|
bool flag = this.referenceStyle == null;
|
|
if (flag)
|
|
{
|
|
this.referenceStyle = new ReferenceCellStyle(this);
|
|
}
|
|
return this.referenceStyle;
|
|
}
|
|
set
|
|
{
|
|
bool flag = value == null;
|
|
if (flag)
|
|
{
|
|
this.Worksheet.RemoveRangeStyles(new RangePosition(this.InternalPos, this.InternalPos), PlainStyleFlag.All);
|
|
}
|
|
else
|
|
{
|
|
Cell cell = value.Cell;
|
|
bool flag2 = cell == null;
|
|
if (!flag2)
|
|
{
|
|
WorksheetRangeStyle innerStyle = cell.InnerStyle;
|
|
StyleParentKind styleParentKind = cell.StyleParentKind;
|
|
StyleParentKind styleParentKind2 = styleParentKind;
|
|
if (styleParentKind2 > StyleParentKind.Range)
|
|
{
|
|
if (styleParentKind2 != StyleParentKind.Own)
|
|
{
|
|
}
|
|
this.InnerStyle = new WorksheetRangeStyle(cell.InnerStyle);
|
|
this.StyleParentKind = StyleParentKind.Own;
|
|
}
|
|
else
|
|
{
|
|
this.InnerStyle = cell.InnerStyle;
|
|
this.StyleParentKind = cell.StyleParentKind;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsVisible
|
|
{
|
|
get
|
|
{
|
|
bool flag = this.Worksheet == null;
|
|
return !flag && this.Worksheet.IsCellVisible(this);
|
|
}
|
|
}
|
|
|
|
internal float DistributedIndentSpacing
|
|
{
|
|
get
|
|
{
|
|
return this.distributedIndentSpacing;
|
|
}
|
|
set
|
|
{
|
|
this.distributedIndentSpacing = value;
|
|
}
|
|
}
|
|
|
|
internal float DistributedIndentSpacingPrint
|
|
{
|
|
get
|
|
{
|
|
return this.distributedIndentSpacingPrint;
|
|
}
|
|
set
|
|
{
|
|
this.distributedIndentSpacingPrint = value;
|
|
}
|
|
}
|
|
|
|
public CellBorderProperty Border
|
|
{
|
|
get
|
|
{
|
|
bool flag = this.borderProperty == null;
|
|
if (flag)
|
|
{
|
|
this.borderProperty = new CellBorderProperty(this);
|
|
}
|
|
return this.borderProperty;
|
|
}
|
|
}
|
|
|
|
internal void UpdateContentBounds()
|
|
{
|
|
bool flag = this.body != null;
|
|
if (flag)
|
|
{
|
|
float left = this.InnerStyle.Padding.Left;
|
|
float top = this.InnerStyle.Padding.Top;
|
|
float num = this.bounds.Width - 1f - this.InnerStyle.Padding.Left - this.InnerStyle.Padding.Right;
|
|
float num2 = this.bounds.Height - 1f - this.InnerStyle.Padding.Top - this.InnerStyle.Padding.Bottom;
|
|
Rect rect = new Rect(ref left, ref top, ref num, ref num2);
|
|
bool flag2 = this.body.Bounds != rect;
|
|
if (flag2)
|
|
{
|
|
this.body.Bounds = rect;
|
|
this.body.OnBoundsChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public object Tag { get; set; }
|
|
|
|
public ICellBody Body
|
|
{
|
|
get
|
|
{
|
|
return this.body;
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.body != value;
|
|
if (flag)
|
|
{
|
|
this.body = value;
|
|
bool flag2 = this.body != null;
|
|
if (flag2)
|
|
{
|
|
this.body.OnSetup(this);
|
|
bool flag3 = this.body is CellBody;
|
|
if (flag3)
|
|
{
|
|
((CellBody)this.body).InnerCell = this;
|
|
}
|
|
}
|
|
this.UpdateContentBounds();
|
|
bool flag4 = this.Worksheet != null;
|
|
if (flag4)
|
|
{
|
|
this.Worksheet.RequestInvalidate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Cell Clone()
|
|
{
|
|
Cell cell = new Cell(this.Worksheet);
|
|
CellUtility.CopyCell(cell, this);
|
|
return cell;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return "Cell[" + this.Address + "]";
|
|
}
|
|
|
|
internal CellPosition MergeStartPos
|
|
{
|
|
get
|
|
{
|
|
return this.mergeStartPos;
|
|
}
|
|
set
|
|
{
|
|
Debug.Assert(value.Row >= -1 && value.Col >= -1);
|
|
this.mergeStartPos = value;
|
|
}
|
|
}
|
|
|
|
internal CellPosition MergeEndPos
|
|
{
|
|
get
|
|
{
|
|
return this.mergeEndPos;
|
|
}
|
|
set
|
|
{
|
|
bool flag = (value.Row > -1 && value.Col <= -1) || (value.Row <= -1 && value.Col > -1);
|
|
if (flag)
|
|
{
|
|
Debug.Assert(false);
|
|
}
|
|
Debug.Assert(value.Row >= -1 && value.Col >= -1);
|
|
this.mergeEndPos = value;
|
|
}
|
|
}
|
|
|
|
internal bool IsStartMergedCell
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Equals(this.MergeStartPos);
|
|
}
|
|
}
|
|
|
|
internal bool IsEndMergedCell
|
|
{
|
|
get
|
|
{
|
|
return this.InternalPos.Row == this.mergeEndPos.Row && this.InternalPos.Col == this.mergeEndPos.Col;
|
|
}
|
|
}
|
|
|
|
public bool IsMergedCell
|
|
{
|
|
get
|
|
{
|
|
return this.IsStartMergedCell;
|
|
}
|
|
}
|
|
|
|
public bool IsValidCell
|
|
{
|
|
get
|
|
{
|
|
return this.rowspan >= 1 && this.colspan >= 1;
|
|
}
|
|
}
|
|
|
|
public bool InsideMergedRange
|
|
{
|
|
get
|
|
{
|
|
return this.IsStartMergedCell || (this.rowspan == 0 && this.colspan == 0);
|
|
}
|
|
}
|
|
|
|
internal bool FontDirty { get; set; }
|
|
|
|
internal Rect TextBounds
|
|
{
|
|
get
|
|
{
|
|
return this.textBounds;
|
|
}
|
|
set
|
|
{
|
|
this.textBounds = value;
|
|
}
|
|
}
|
|
|
|
internal float TextBoundsTop
|
|
{
|
|
get
|
|
{
|
|
return this.textBounds.Y;
|
|
}
|
|
set
|
|
{
|
|
this.textBounds.Y = value;
|
|
}
|
|
}
|
|
|
|
internal float TextBoundsLeft
|
|
{
|
|
get
|
|
{
|
|
return this.textBounds.X;
|
|
}
|
|
set
|
|
{
|
|
this.textBounds.X = value;
|
|
}
|
|
}
|
|
|
|
internal float TextBoundsWidth
|
|
{
|
|
get
|
|
{
|
|
return this.textBounds.Width;
|
|
}
|
|
set
|
|
{
|
|
this.textBounds.Width = value;
|
|
}
|
|
}
|
|
|
|
internal float TextBoundsHeight
|
|
{
|
|
get
|
|
{
|
|
return this.textBounds.Height;
|
|
}
|
|
set
|
|
{
|
|
this.textBounds.Height = value;
|
|
}
|
|
}
|
|
|
|
internal Rect PrintTextBounds { get; set; }
|
|
|
|
internal ReoGridRenderHorAlign RenderHorAlign { get; set; }
|
|
|
|
internal short RenderTextColumnSpan { get; set; }
|
|
|
|
public Color RenderColor { get; internal set; }
|
|
|
|
internal float RenderScaleFactor { get; set; }
|
|
|
|
public string Comment
|
|
{
|
|
get
|
|
{
|
|
return this.comment;
|
|
}
|
|
set
|
|
{
|
|
this.comment = value;
|
|
bool flag = this.worksheet != null;
|
|
if (flag)
|
|
{
|
|
this.worksheet.AddCellCommentIfNotExist(this);
|
|
this.worksheet.RequestInvalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool TraceFormulaPrecedents
|
|
{
|
|
get
|
|
{
|
|
return this.Worksheet.IsCellInTracePrecedents(this.InternalPos);
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.Worksheet != null;
|
|
if (flag)
|
|
{
|
|
if (value)
|
|
{
|
|
this.Worksheet.TraceCellPrecedents(this);
|
|
}
|
|
else
|
|
{
|
|
this.Worksheet.RemoveCellTracePrecedents(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool TraceFormulaDependents
|
|
{
|
|
get
|
|
{
|
|
bool flag = this.Worksheet == null;
|
|
return !flag && this.Worksheet.IsCellInTracePrecedents(this.InternalPos);
|
|
}
|
|
set
|
|
{
|
|
bool flag = this.Worksheet != null;
|
|
if (flag)
|
|
{
|
|
if (value)
|
|
{
|
|
this.Worksheet.TraceCellDependents(this);
|
|
}
|
|
else
|
|
{
|
|
this.Worksheet.RemoveCellTraceDependents(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal Font RenderFont { get; set; }
|
|
|
|
internal TextDecoration TextDecoration { get; set; }
|
|
|
|
[NonSerialized]
|
|
private Worksheet worksheet;
|
|
|
|
internal CellPosition InternalPos;
|
|
|
|
private short colspan;
|
|
|
|
private short rowspan;
|
|
|
|
[NonSerialized]
|
|
private Rect bounds;
|
|
|
|
private CellDataFormatFlag dataFormat;
|
|
|
|
private object dataFormatArgs;
|
|
|
|
internal FormulaStatus formulaStatus;
|
|
|
|
[NonSerialized]
|
|
internal STNode formulaTree;
|
|
|
|
private static int _count;
|
|
|
|
[NonSerialized]
|
|
private ReferenceCellStyle referenceStyle;
|
|
|
|
private float distributedIndentSpacing;
|
|
|
|
private float distributedIndentSpacingPrint;
|
|
|
|
private CellBorderProperty borderProperty = null;
|
|
|
|
internal ICellBody body;
|
|
|
|
private CellPosition mergeStartPos = CellPosition.Empty;
|
|
|
|
private CellPosition mergeEndPos = CellPosition.Empty;
|
|
|
|
private Rect textBounds;
|
|
|
|
private string comment;
|
|
}
|
|
}
|