using System;
using System.Collections.Generic;
using FastReport.Table;
using FastReport.Utils;
namespace FastReport.AdvMatrix
{
///
/// The descriptor that is used to describe one element of the matrix header.
///
///
/// The class is used to define one header element of the matrix
/// (either the column element or row element). The key properties are
/// and .
/// The collection of descriptors used to represent the matrix header is stored
/// in the AdvMatrixObject.Data.Columns and AdvMatrixObject.Data.Rows properties.
///
public class HeaderDescriptor : IFRSerializable
{
///
/// Gets or sets the name of this descriptor.
///
///
/// This property is used by the TopN engine to find linked items such as TopNTotal, Others, OtherTotal.
/// All others descriptors have empty name.
///
public string Name { get; set; }
///
/// Gets the parent descriptor of this descriptor.
///
public HeaderDescriptor Parent { get; private set; }
///
/// Gets child items of this descriptor.
///
public List Items { get; }
///
/// Gets or sets an expression which value will be used to fill the matrix.
///
///
/// Expression may be any valid expression. Usually it's a data column:
/// [DataSource.Column].
///
public string Expression { get; set; }
///
/// Gets or sets a text which will be displayed in this item.
///
///
/// DisplayText may contain text mixed with expressions just like in the TextObject, e.g. "Some text: [expr]".
/// The default property value is empty for group descriptors.
/// In this case the group value returned by the property will be displayed in this item.
///
public string DisplayText { get; set; }
///
/// Gets or sets the filter expression.
///
public string Filter { get; set; }
///
/// Gets or sets the sort order of header values.
///
///
/// This property determines how the values displayed in this element are sorted. The default sort is ascending.
///
public SortOrder Sort { get; set; }
///
/// Gets or sets the sort button name which toggles the sort order of this item.
///
public string SortToggledBy { get; set; }
///
/// Gets or sets an expression which value will be used to sort the header values.
///
/// This expression is used to sort header by its total value. The expression must contain single aggregate, e.g. "Sum([Table1.Field1])".
/// The empty expression (by default) indicates that the header should be sorted by its value.
///
public string SortByTotal { get; set; }
///
/// Gets or sets a value indicating that this item can be sorted interactively.
///
public bool InteractiveSort { get; set; }
///
/// Gets or sets an expression which value will be used to sort the header values interactively.
///
/// This expression is used to sort header values when interactive sorting is on.
/// The expression must contain single aggregate, e.g. "Sum([Table1.Field1])".
/// The empty expression (by default) indicates automatic mode.
///
public string InteractiveSortBy { get; set; }
///
/// Gets or sets the visibility of this item.
///
public bool Visible { get; set; }
///
/// Gets or sets the expression that returns the visibility of this item.
///
public string VisibleExpression { get; set; }
///
/// Gets or sets the collapse button name which toggles the visibility of this item.
///
public string VisibleToggledBy { get; set; }
///
/// Gets or sets a value indicating that the page break must be printed before this element.
///
///
/// Page break is not printed before the very first element.
///
public bool PageBreak { get; set; }
///
/// Determines whether the item should merge itself with single subitem.
///
public bool MergeSingleItem { get; set; }
///
/// Determines whether this item and its subitems will be displayed stepped.
///
public bool Stepped { get; set; }
///
/// Gets TopN settings for this item.
///
public TopNInfo TopN { get; private set; }
///
/// Gets or sets column span of this item. 0 means span is set automatically.
///
public int ColSpan { get; set; }
///
/// Gets or sets row span of this item. 0 means span is set automatically.
///
public int RowSpan { get; set; }
// these items set by TemplateBuilder.UpdateDescriptors
internal AdvMatrixObject Matrix { get; set; }
internal bool IsColumn { get; set; }
internal TableColumn TemplateColumn { get; set; }
internal TableRow TemplateRow { get; set; }
internal TableCell TemplateCell { get; set; }
// Aggregate is used if "sort by total" is on
internal AggregateExpressionPair SortAggregate { get; set; }
// Aggregate is used if interactive sort is on
internal AggregateExpressionPair InteractiveSortAggregate { get; set; }
internal bool IsGroup { get { return !String.IsNullOrEmpty(Expression); } }
internal bool IsTopNItem { get { return !String.IsNullOrEmpty(Name); } }
internal HeaderDescriptor Root
{
get
{
HeaderDescriptor item = this;
while (item.Parent != null)
{
item = item.Parent;
}
return item;
}
}
internal int Span
{
get
{
if (Stepped)
return 1;
int count = TerminalItems.Count;
return count > 0 ? count : 1;
}
}
internal List AllItems
{
get
{
List list = new List();
GetAllItems(this, list);
return list;
}
}
internal List TerminalItems
{
get
{
List list = new List();
GetTerminalItems(this, list);
return list;
}
}
private void GetAllItems(HeaderDescriptor root, List list)
{
foreach (HeaderDescriptor d in root.Items)
{
list.Add(d);
GetAllItems(d, list);
}
}
private void GetTerminalItems(HeaderDescriptor root, List list)
{
if (root.Items.Count == 0 || root.Stepped)
list.Add(root);
foreach (HeaderDescriptor d in root.Items)
{
GetTerminalItems(d, list);
}
}
internal void SetParent(HeaderDescriptor parent)
{
Parent = parent;
}
internal void InitAggregates()
{
ExpressionParser parser = new ExpressionParser(Matrix);
if (!String.IsNullOrEmpty(SortByTotal))
{
SortAggregate = parser.Parse(SortByTotal);
}
if (InteractiveSort && !String.IsNullOrEmpty(InteractiveSortBy))
{
// use existing cell aggregate here
InteractiveSortAggregate = Matrix.Data.CellData.FindAggregate(parser.Parse(InteractiveSortBy));
}
}
internal object CalcValue()
{
if (String.IsNullOrEmpty(Expression))
return null;
return Matrix.Report.Calc(Expression);
}
///
/// Adds new child descriptor.
///
/// The new descriptor.
public HeaderDescriptor Add()
{
return Add(new HeaderDescriptor());
}
///
/// Adds a child descriptor.
///
/// The new descriptor.
/// The new descriptor.
public HeaderDescriptor Add(HeaderDescriptor descr)
{
Items.Add(descr);
descr.Parent = this;
return descr;
}
///
public void Serialize(FRWriter writer)
{
writer.ItemName = "Descriptor";
HeaderDescriptor c = writer.DiffObject as HeaderDescriptor;
if (Name != c.Name)
writer.WriteStr("Name", Name);
if (Expression != c.Expression)
writer.WriteStr("Expression", Expression);
if (DisplayText != c.DisplayText)
writer.WriteStr("DisplayText", DisplayText);
if (Filter != c.Filter)
writer.WriteStr("Filter", Filter);
if (Sort != c.Sort)
writer.WriteValue("Sort", Sort);
if (SortToggledBy != c.SortToggledBy)
writer.WriteStr("SortToggledBy", SortToggledBy);
if (SortByTotal != c.SortByTotal)
writer.WriteStr("SortByTotal", SortByTotal);
if (InteractiveSort != c.InteractiveSort)
writer.WriteBool("InteractiveSort", InteractiveSort);
if (InteractiveSortBy != c.InteractiveSortBy)
writer.WriteStr("InteractiveSortBy", InteractiveSortBy);
if (Visible != c.Visible)
writer.WriteBool("Visible", Visible);
if (VisibleExpression != c.VisibleExpression)
writer.WriteStr("VisibleExpression", VisibleExpression);
if (VisibleToggledBy != c.VisibleToggledBy)
writer.WriteStr("VisibleToggledBy", VisibleToggledBy);
TopN.Serialize(writer, "TopN", c.TopN);
if (Stepped != c.Stepped)
writer.WriteBool("Stepped", Stepped);
if (PageBreak != c.PageBreak)
writer.WriteBool("PageBreak", PageBreak);
if (MergeSingleItem != c.MergeSingleItem)
writer.WriteBool("MergeSingleItem", MergeSingleItem);
if (ColSpan != c.ColSpan)
writer.WriteInt("ColSpan", ColSpan);
if (RowSpan != c.RowSpan)
writer.WriteInt("RowSpan", RowSpan);
foreach (HeaderDescriptor d in Items)
{
writer.Write(d);
}
}
///
public void Deserialize(FRReader reader)
{
reader.ReadProperties(this);
Items.Clear();
while (reader.NextItem())
{
reader.Read(Add());
}
}
///
/// Initializes a new instance of the class.
///
public HeaderDescriptor()
{
Name = "";
Items = new List();
Expression = "";
DisplayText = "";
Filter = "";
Sort = SortOrder.Ascending;
SortToggledBy = "";
SortByTotal = "";
InteractiveSort = true;
InteractiveSortBy = "";
Visible = true;
VisibleExpression = "";
VisibleToggledBy = "";
TopN = new TopNInfo(this);
}
///
/// Initializes a new instance of the class with the group expression specified.
///
public HeaderDescriptor(string expression) : this()
{
Expression = expression;
}
}
}