123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- using System;
- using System.Collections.Generic;
- using FastReport.Table;
- using FastReport.Utils;
- namespace FastReport.AdvMatrix
- {
- /// <summary>
- /// The descriptor that is used to describe one element of the matrix header.
- /// </summary>
- /// <remarks>
- /// The class is used to define one header element of the matrix
- /// (either the column element or row element). The key properties are
- /// <see cref="Expression"/> and <see cref="Sort"/>.
- /// <para/>The collection of descriptors used to represent the matrix header is stored
- /// in the <b>AdvMatrixObject.Data.Columns</b> and <b>AdvMatrixObject.Data.Rows</b> properties.
- /// </remarks>
- public class HeaderDescriptor : IFRSerializable
- {
- /// <summary>
- /// Gets or sets the name of this descriptor.
- /// </summary>
- /// <remarks>
- /// This property is used by the TopN engine to find linked items such as TopNTotal, Others, OtherTotal.
- /// All others descriptors have empty name.
- /// </remarks>
- public string Name { get; set; }
- /// <summary>
- /// Gets the parent descriptor of this descriptor.
- /// </summary>
- public HeaderDescriptor Parent { get; private set; }
- /// <summary>
- /// Gets child items of this descriptor.
- /// </summary>
- public List<HeaderDescriptor> Items { get; }
- /// <summary>
- /// Gets or sets an expression which value will be used to fill the matrix.
- /// </summary>
- /// <remarks>
- /// <b>Expression</b> may be any valid expression. Usually it's a data column:
- /// <c>[DataSource.Column]</c>.
- /// </remarks>
- public string Expression { get; set; }
- /// <summary>
- /// Gets or sets a text which will be displayed in this item.
- /// </summary>
- /// <remarks>
- /// <b>DisplayText</b> 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 <see cref="Expression"/> property will be displayed in this item.
- /// </remarks>
- public string DisplayText { get; set; }
- /// <summary>
- /// Gets or sets the filter expression.
- /// </summary>
- public string Filter { get; set; }
- /// <summary>
- /// Gets or sets the sort order of header values.
- /// </summary>
- /// <remarks>
- /// This property determines how the values displayed in this element are sorted. The default sort is ascending.
- /// </remarks>
- public SortOrder Sort { get; set; }
- /// <summary>
- /// Gets or sets the sort button name which toggles the sort order of this item.
- /// </summary>
- public string SortToggledBy { get; set; }
- /// <summary>
- /// Gets or sets an expression which value will be used to sort the header values.
- /// </summary>
- /// <remarks>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.
- /// </remarks>
- public string SortByTotal { get; set; }
- /// <summary>
- /// Gets or sets a value indicating that this item can be sorted interactively.
- /// </summary>
- public bool InteractiveSort { get; set; }
- /// <summary>
- /// Gets or sets an expression which value will be used to sort the header values interactively.
- /// </summary>
- /// <remarks>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.
- /// </remarks>
- public string InteractiveSortBy { get; set; }
- /// <summary>
- /// Gets or sets the visibility of this item.
- /// </summary>
- public bool Visible { get; set; }
- /// <summary>
- /// Gets or sets the expression that returns the visibility of this item.
- /// </summary>
- public string VisibleExpression { get; set; }
- /// <summary>
- /// Gets or sets the collapse button name which toggles the visibility of this item.
- /// </summary>
- public string VisibleToggledBy { get; set; }
- /// <summary>
- /// Gets or sets a value indicating that the page break must be printed before this element.
- /// </summary>
- /// <remarks>
- /// Page break is not printed before the very first element.
- /// </remarks>
- public bool PageBreak { get; set; }
- /// <summary>
- /// Determines whether the item should merge itself with single subitem.
- /// </summary>
- public bool MergeSingleItem { get; set; }
- /// <summary>
- /// Determines whether this item and its subitems will be displayed stepped.
- /// </summary>
- public bool Stepped { get; set; }
- /// <summary>
- /// Gets TopN settings for this item.
- /// </summary>
- public TopNInfo TopN { get; private set; }
- /// <summary>
- /// Gets or sets column span of this item. 0 means span is set automatically.
- /// </summary>
- public int ColSpan { get; set; }
- /// <summary>
- /// Gets or sets row span of this item. 0 means span is set automatically.
- /// </summary>
- 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<HeaderDescriptor> AllItems
- {
- get
- {
- List<HeaderDescriptor> list = new List<HeaderDescriptor>();
- GetAllItems(this, list);
- return list;
- }
- }
- internal List<HeaderDescriptor> TerminalItems
- {
- get
- {
- List<HeaderDescriptor> list = new List<HeaderDescriptor>();
- GetTerminalItems(this, list);
- return list;
- }
- }
- private void GetAllItems(HeaderDescriptor root, List<HeaderDescriptor> list)
- {
- foreach (HeaderDescriptor d in root.Items)
- {
- list.Add(d);
- GetAllItems(d, list);
- }
- }
- private void GetTerminalItems(HeaderDescriptor root, List<HeaderDescriptor> 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);
- }
- /// <summary>
- /// Adds new child descriptor.
- /// </summary>
- /// <returns>The new descriptor.</returns>
- public HeaderDescriptor Add()
- {
- return Add(new HeaderDescriptor());
- }
- /// <summary>
- /// Adds a child descriptor.
- /// </summary>
- /// <param name="descr">The new descriptor.</param>
- /// <returns>The new descriptor.</returns>
- public HeaderDescriptor Add(HeaderDescriptor descr)
- {
- Items.Add(descr);
- descr.Parent = this;
- return descr;
- }
- /// <inheritdoc/>
- 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);
- }
- }
- /// <inheritdoc/>
- public void Deserialize(FRReader reader)
- {
- reader.ReadProperties(this);
- Items.Clear();
- while (reader.NextItem())
- {
- reader.Read(Add());
- }
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="HeaderDescriptor"/> class.
- /// </summary>
- public HeaderDescriptor()
- {
- Name = "";
- Items = new List<HeaderDescriptor>();
- Expression = "";
- DisplayText = "";
- Filter = "";
- Sort = SortOrder.Ascending;
- SortToggledBy = "";
- SortByTotal = "";
- InteractiveSort = true;
- InteractiveSortBy = "";
- Visible = true;
- VisibleExpression = "";
- VisibleToggledBy = "";
- TopN = new TopNInfo(this);
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="HeaderDescriptor"/> class with the group expression specified.
- /// </summary>
- public HeaderDescriptor(string expression) : this()
- {
- Expression = expression;
- }
- }
- }
|