using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using FastReport.Data;
using FastReport.Utils;
namespace FastReport.Table
{
///
/// Represents a table row.
///
///
/// Use the property to set the height of a row. If
/// property is true, the row will calculate its height automatically.
/// You can also set the and properties
/// to restrict the row's height.
///
public partial class TableRow : ComponentBase, IParent
{
#region Fields
private List cells;
private float minHeight;
private float maxHeight;
private bool autoSize;
private bool canBreak;
private bool pageBreak;
private int keepRows;
private int index;
private float saveHeight;
private bool saveVisible;
private bool serializingToPreview;
#endregion
#region Properties
///
/// Gets or sets a height of the row, in pixels.
///
///
/// The row height cannot exceed the range defined by the
/// and properties.
/// To convert between pixels and report units, use the constants defined
/// in the class.
///
[TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
public override float Height
{
get { return base.Height; }
set
{
value = Converter.DecreasePrecision(value, 2);
if (value > MaxHeight && !canBreak)
value = MaxHeight;
if (value < MinHeight)
value = MinHeight;
base.Height = value;
}
}
///
/// Gets or sets the minimal height for this row, in pixels.
///
[DefaultValue(0f)]
[Category("Layout")]
[TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
public float MinHeight
{
get { return minHeight; }
set { minHeight = value; }
}
///
/// Gets or sets the maximal height for this row, in pixels.
///
[DefaultValue(1000f)]
[Category("Layout")]
[TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
public float MaxHeight
{
get { return maxHeight; }
set { maxHeight = value; }
}
///
/// Gets or sets a value determines if the row should calculate its height automatically.
///
///
/// The row height cannot exceed the range defined by the
/// and properties.
///
[DefaultValue(false)]
[Category("Behavior")]
public bool AutoSize
{
get { return autoSize; }
set { autoSize = value; }
}
///
/// Gets or sets a value that determines if the component can break its contents across pages.
///
[DefaultValue(false)]
[Category("Behavior")]
public bool CanBreak
{
get { return canBreak; }
set { canBreak = value; }
}
///
/// Gets the index of this row.
///
[Browsable(false)]
public int Index
{
get { return index; }
}
///
[Browsable(false)]
public override float Top
{
get
{
TableBase table = Parent as TableBase;
if (table == null)
return 0;
float result = 0;
for (int i = 0; i < Index; i++)
{
result += table.Rows[i].Height;
}
return result;
}
set { base.Top = value; }
}
///
/// Gets or sets the cell with specified index.
///
/// Column index.
/// The TableCell object.
[Browsable(false)]
public TableCell this[int col]
{
get
{
TableCellData cellData = CellData(col);
TableCell cell = cellData.Cell;
cell.SetParent(this);
cell.SetValue(cellData.Value);
return cell;
}
set
{
TableCellData cellData = CellData(col);
cellData.AttachCell(value);
}
}
///
/// Gets or sets the page break flag for this row.
///
[Browsable(false)]
public bool PageBreak
{
get { return pageBreak; }
set { pageBreak = value; }
}
///
/// Gets or sets the number of rows to keep on the same page.
///
[Browsable(false)]
public int KeepRows
{
get { return keepRows; }
set { keepRows = value; }
}
internal static float DefaultHeight
{
get { return (int)Math.Round(18 / (0.25f * Units.Centimeters)) * (0.25f * Units.Centimeters); }
}
#endregion
#region IParent Members
///
public bool CanContain(Base child)
{
return child is TableCell;
}
///
public void GetChildObjects(ObjectCollection list)
{
TableBase table = Parent as TableBase;
if (table == null)
return;
for (int i = 0; i < table.Columns.Count; i++)
{
if (!serializingToPreview || table.Columns[i].Visible)
list.Add(this[i]);
}
}
///
public void AddChild(Base child)
{
// support deserializing the cells
if (child is TableCell)
{
this[cells.Count] = child as TableCell;
child.SetParent(this);
}
}
///
public void RemoveChild(Base child)
{
}
private TableCellData FindCellData(TableCell cell)
{
foreach (TableCellData cellData in cells)
{
if (cellData.Cell == cell)
return cellData;
}
return null;
}
///
public int GetChildOrder(Base child)
{
TableCellData cellData = FindCellData(child as TableCell);
return cellData == null ? 0 : cells.IndexOf(cellData);
}
///
public void SetChildOrder(Base child, int order)
{
TableCellData cellData = FindCellData(child as TableCell);
if (cellData == null)
return;
int oldOrder = child.ZOrder;
if (oldOrder != -1 && order != -1 && oldOrder != order)
{
if (order > cells.Count)
order = cells.Count;
if (oldOrder <= order)
order--;
cells.Remove(cellData);
cells.Insert(order, cellData);
}
}
///
public void UpdateLayout(float dx, float dy)
{
TableBase table = Parent as TableBase;
if (table == null)
return;
// update this row cells
for (int i = 0; i < table.Columns.Count; i++)
{
this.CellData(i).UpdateLayout(dx, dy);
}
// update spanned cells that contains this row
List spanList = table.GetSpanList();
foreach (Rectangle span in spanList)
{
if (Index > span.Top && Index < span.Bottom)
table[span.Left, span.Top].CellData.UpdateLayout(dx, dy);
}
}
#endregion
#region Public Methods
///
public override void Assign(Base source)
{
TableRow src = source as TableRow;
MinHeight = src.MinHeight;
MaxHeight = src.MaxHeight;
AutoSize = src.AutoSize;
KeepRows = src.KeepRows;
CanBreak = src.CanBreak;
base.Assign(source);
}
internal TableCellData CellData(int col)
{
while (col >= cells.Count)
{
cells.Add(new TableCellData());
}
TableCellData cellData = cells[col];
cellData.Table = Parent as TableBase;
cellData.Address = new Point(col, Index);
return cellData;
}
internal void CorrectCellsOnColumnChange(int index, int correct)
{
if (correct == 1)
cells.Insert(index, new TableCellData());
else if (index < cells.Count)
cells.RemoveAt(index);
}
internal void SetIndex(int value)
{
index = value;
}
///
public override void Serialize(FRWriter writer)
{
TableRow c = writer.DiffObject as TableRow;
serializingToPreview = writer.SerializeTo == SerializeTo.Preview;
base.Serialize(writer);
if (FloatDiff(MinHeight, c.MinHeight))
writer.WriteFloat("MinHeight", MinHeight);
if (FloatDiff(MaxHeight, c.MaxHeight))
writer.WriteFloat("MaxHeight", MaxHeight);
if (FloatDiff(Height, c.Height))
writer.WriteFloat("Height", Height);
if (AutoSize != c.AutoSize)
writer.WriteBool("AutoSize", AutoSize);
if (CanBreak != c.CanBreak)
writer.WriteBool("CanBreak", CanBreak);
if (Parent is TableResult)
{
// write children by itself
SetFlags(Flags.CanWriteChildren, true);
writer.SaveChildren = true;
TableResult table = Parent as TableResult;
foreach (TableColumn column in table.ColumnsToSerialize)
{
TableCell cell = this[column.Index];
writer.Write(cell);
}
}
}
///
public override void Clear()
{
base.Clear();
foreach (TableCellData cell in cells)
{
cell.Dispose();
}
cells.Clear();
}
internal void SaveState()
{
saveHeight = Height;
saveVisible = Visible;
}
internal void RestoreState()
{
Height = saveHeight;
Visible = saveVisible;
}
#endregion
///
/// Initializes a new instance of the class.
///
public TableRow()
{
cells = new List();
maxHeight = 1000;
Height = DefaultHeight;
SetFlags(Flags.CanCopy | Flags.CanDelete | Flags.CanWriteBounds, false);
BaseName = "Row";
}
}
}