123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.ComponentModel;
- using System.Drawing;
- using FastReport.Data;
- using FastReport.Utils;
- namespace FastReport.Table
- {
- /// <summary>
- /// Represents a table row.
- /// </summary>
- /// <remarks>
- /// Use the <see cref="Height"/> property to set the height of a row. If <see cref="AutoSize"/>
- /// property is <b>true</b>, the row will calculate its height automatically.
- /// <para/>You can also set the <see cref="MinHeight"/> and <see cref="MaxHeight"/> properties
- /// to restrict the row's height.
- /// </remarks>
- public partial class TableRow : ComponentBase, IParent
- {
- #region Fields
- private List<TableCellData> 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
- /// <summary>
- /// Gets or sets a height of the row, in pixels.
- /// </summary>
- /// <remarks>
- /// The row height cannot exceed the range defined by the <see cref="MinHeight"/>
- /// and <see cref="MaxHeight"/> properties.
- /// <note>To convert between pixels and report units, use the constants defined
- /// in the <see cref="Units"/> class.</note>
- /// </remarks>
- [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;
- }
- }
- /// <summary>
- /// Gets or sets the minimal height for this row, in pixels.
- /// </summary>
- [DefaultValue(0f)]
- [Category("Layout")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float MinHeight
- {
- get { return minHeight; }
- set { minHeight = value; }
- }
- /// <summary>
- /// Gets or sets the maximal height for this row, in pixels.
- /// </summary>
- [DefaultValue(1000f)]
- [Category("Layout")]
- [TypeConverter("FastReport.TypeConverters.UnitsConverter, FastReport")]
- public float MaxHeight
- {
- get { return maxHeight; }
- set { maxHeight = value; }
- }
- /// <summary>
- /// Gets or sets a value determines if the row should calculate its height automatically.
- /// </summary>
- /// <remarks>
- /// The row height cannot exceed the range defined by the <see cref="MinHeight"/>
- /// and <see cref="MaxHeight"/> properties.
- /// </remarks>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool AutoSize
- {
- get { return autoSize; }
- set { autoSize = value; }
- }
- /// <summary>
- /// Gets or sets a value that determines if the component can break its contents across pages.
- /// </summary>
- [DefaultValue(false)]
- [Category("Behavior")]
- public bool CanBreak
- {
- get { return canBreak; }
- set { canBreak = value; }
- }
- /// <summary>
- /// Gets the index of this row.
- /// </summary>
- [Browsable(false)]
- public int Index
- {
- get { return index; }
- }
- /// <inheritdoc/>
- [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; }
- }
- /// <summary>
- /// Gets or sets the cell with specified index.
- /// </summary>
- /// <param name="col">Column index.</param>
- /// <returns>The <b>TableCell</b> object.</returns>
- [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);
- }
- }
- /// <summary>
- /// Gets or sets the page break flag for this row.
- /// </summary>
- [Browsable(false)]
- public bool PageBreak
- {
- get { return pageBreak; }
- set { pageBreak = value; }
- }
- /// <summary>
- /// Gets or sets the number of rows to keep on the same page.
- /// </summary>
- [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
- /// <inheritdoc/>
- public bool CanContain(Base child)
- {
- return child is TableCell;
- }
- /// <inheritdoc/>
- 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]);
- }
- }
- /// <inheritdoc/>
- public void AddChild(Base child)
- {
- // support deserializing the cells
- if (child is TableCell)
- {
- this[cells.Count] = child as TableCell;
- child.SetParent(this);
- }
- }
- /// <inheritdoc/>
- public void RemoveChild(Base child)
- {
- }
- private TableCellData FindCellData(TableCell cell)
- {
- foreach (TableCellData cellData in cells)
- {
- if (cellData.Cell == cell)
- return cellData;
- }
- return null;
- }
- /// <inheritdoc/>
- public int GetChildOrder(Base child)
- {
- TableCellData cellData = FindCellData(child as TableCell);
- return cellData == null ? 0 : cells.IndexOf(cellData);
- }
- /// <inheritdoc/>
- 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);
- }
- }
- /// <inheritdoc/>
- 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<Rectangle> 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
- /// <inheritdoc/>
- 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;
- }
- /// <inheritdoc/>
- 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);
- }
- }
- }
- /// <inheritdoc/>
- 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
- /// <summary>
- /// Initializes a new instance of the <see cref="TableRow"/> class.
- /// </summary>
- public TableRow()
- {
- cells = new List<TableCellData>();
- maxHeight = 1000;
- Height = DefaultHeight;
- SetFlags(Flags.CanCopy | Flags.CanDelete | Flags.CanWriteBounds, false);
- BaseName = "Row";
- }
- }
- }
|