123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Collections;
- using FastReport.Utils;
- namespace FastReport.Matrix
- {
- /// <summary>
- /// Represents a collection of matrix header descriptors used in the <see cref="MatrixObject"/>.
- /// </summary>
- public class MatrixHeader : CollectionBase, IFRSerializable
- {
- private MatrixHeaderItem rootItem;
- private int nextIndex;
- private string name;
- /// <summary>
- /// Gets or sets the element at the specified index.
- /// </summary>
- /// <param name="index">Index of an element.</param>
- /// <returns>The element at the specified index.</returns>
- public MatrixHeaderDescriptor this[int index]
- {
- get { return List[index] as MatrixHeaderDescriptor; }
- set { List[index] = value; }
- }
- internal MatrixHeaderItem RootItem
- {
- get { return rootItem; }
- }
-
- internal string Name
- {
- get { return name; }
- set { name = value; }
- }
- /// <summary>
- /// Adds the specified descriptors to the end of this collection.
- /// </summary>
- /// <param name="range">Array of descriptors to add.</param>
- public void AddRange(MatrixHeaderDescriptor[] range)
- {
- foreach (MatrixHeaderDescriptor s in range)
- {
- Add(s);
- }
- }
- /// <summary>
- /// Adds a descriptor to the end of this collection.
- /// </summary>
- /// <param name="value">Descriptor to add.</param>
- /// <returns>Index of the added descriptor.</returns>
- public int Add(MatrixHeaderDescriptor value)
- {
- return List.Add(value);
- }
- /// <summary>
- /// Inserts a descriptor into this collection at the specified index.
- /// </summary>
- /// <param name="index">The zero-based index at which value should be inserted.</param>
- /// <param name="value">The descriptor to insert.</param>
- public void Insert(int index, MatrixHeaderDescriptor value)
- {
- List.Insert(index, value);
- }
- /// <summary>
- /// Removes the specified descriptor from the collection.
- /// </summary>
- /// <param name="value">Descriptor to remove.</param>
- public void Remove(MatrixHeaderDescriptor value)
- {
- int i = IndexOf(value);
- if (i != -1)
- List.RemoveAt(i);
- }
- /// <summary>
- /// Returns the zero-based index of the first occurrence of a descriptor.
- /// </summary>
- /// <param name="value">The descriptor to locate in the collection.</param>
- /// <returns>The zero-based index of the first occurrence of descriptor within
- /// the entire collection, if found; otherwise, -1.</returns>
- public int IndexOf(MatrixHeaderDescriptor value)
- {
- return List.IndexOf(value);
- }
- /// <summary>
- /// Determines whether a descriptor is in the collection.
- /// </summary>
- /// <param name="value">The descriptor to locate in the collection.</param>
- /// <returns><b>true</b> if descriptor is found in the collection; otherwise, <b>false</b>.</returns>
- public bool Contains(MatrixHeaderDescriptor value)
- {
- return List.Contains(value);
- }
- /// <summary>
- /// Copies the elements of this collection to a new array.
- /// </summary>
- /// <returns>An array containing copies of this collection elements. </returns>
- public MatrixHeaderDescriptor[] ToArray()
- {
- MatrixHeaderDescriptor[] result = new MatrixHeaderDescriptor[Count];
- for (int i = 0; i < Count; i++)
- {
- result[i] = this[i];
- }
- return result;
- }
- /// <summary>
- /// Gets the list of indices of terminal items of this header.
- /// </summary>
- /// <returns>The list of indices.</returns>
- public int[] GetTerminalIndices()
- {
- return GetTerminalIndices(rootItem);
- }
- /// <summary>
- /// Gets the list of indices of terminal items of the header with specified address.
- /// </summary>
- /// <param name="address">The address of a header.</param>
- /// <returns>The list of indices.</returns>
- public int[] GetTerminalIndices(object[] address)
- {
- MatrixHeaderItem rootItem = Find(address, false, 0);
- return GetTerminalIndices(rootItem);
- }
- private int[] GetTerminalIndices(MatrixHeaderItem rootItem)
- {
- List<MatrixHeaderItem> terminalItems = rootItem.GetTerminalItems();
- int[] result = new int[terminalItems.Count];
- for (int i = 0; i < result.Length; i++)
- result[i] = terminalItems[i].Index;
- return result;
- }
- /// <summary>
- /// Removes a header item with the address specified.
- /// </summary>
- /// <param name="address">The address of a header.</param>
- public void RemoveItem(object[] address)
- {
- MatrixHeaderItem item = Find(address, false, 0);
- if (item != null)
- item.Parent.Items.Remove(item);
- }
- /// <summary>
- /// Gets an index of header with the address specified.
- /// </summary>
- /// <param name="address">The address of a header.</param>
- /// <returns>The index of header.</returns>
- public int Find(object[] address)
- {
- MatrixHeaderItem item = Find(address, false, 0);
- if (item != null)
- return item.Index;
- return -1;
- }
- /// <summary>
- /// Gets an index of header with the address specified. If there is no such header item, it will be created.
- /// </summary>
- /// <param name="address">The address of a header.</param>
- /// <returns>The index of header.</returns>
- public int FindOrCreate(object[] address)
- {
- MatrixHeaderItem item = Find(address, true, 0);
- if (item != null)
- return item.Index;
- return -1;
- }
- internal MatrixHeaderItem Find(object[] address, bool create, int dataRowNo)
- {
- // Note that the top header itself does not contain a value.
- // It is used as a list of first-level headers only.
- MatrixHeaderItem rootItem = RootItem;
-
- for (int i = 0; i < address.Length; i++)
- {
- int index = rootItem.Find(address[i], this[i].Sort);
-
- if (index >= 0)
- rootItem = rootItem.Items[index];
- else if (create)
- {
- // create new item if necessary.
- MatrixHeaderItem newItem = new MatrixHeaderItem(rootItem);
- newItem.Value = address[i];
- newItem.TemplateColumn = this[i].TemplateColumn;
- newItem.TemplateRow = this[i].TemplateRow;
- newItem.TemplateCell = this[i].TemplateCell;
- newItem.DataRowNo = dataRowNo;
- newItem.PageBreak = this[i].PageBreak;
- // index is used as a cell address in a matrix
- if (i == address.Length - 1)
- {
- // create index for bottom-level header
- newItem.Index = nextIndex;
- nextIndex++;
- }
- rootItem.Items.Insert(~index, newItem);
- rootItem = newItem;
- }
- else
- return null;
- }
- return rootItem;
- }
- private void AddTotalItems(MatrixHeaderItem rootItem, int descriptorIndex, bool isTemplate)
- {
- if (descriptorIndex >= Count)
- return;
-
- foreach (MatrixHeaderItem item in rootItem.Items)
- {
- AddTotalItems(item, descriptorIndex + 1, isTemplate);
- }
-
- if (this[descriptorIndex].Totals &&
- (isTemplate || !this[descriptorIndex].SuppressTotals || rootItem.Items.Count > 1))
- {
- MatrixHeaderItem totalItem = new MatrixHeaderItem(rootItem);
- totalItem.IsTotal = true;
- totalItem.Value = rootItem.Value;
- totalItem.DataRowNo = rootItem.DataRowNo;
- totalItem.TemplateColumn = this[descriptorIndex].TemplateTotalColumn;
- totalItem.TemplateRow = this[descriptorIndex].TemplateTotalRow;
- totalItem.TemplateCell = this[descriptorIndex].TemplateTotalCell;
- totalItem.Index = nextIndex;
- nextIndex++;
-
- if (this[descriptorIndex].TotalsFirst && !isTemplate)
- rootItem.Items.Insert(0, totalItem);
- else
- rootItem.Items.Add(totalItem);
- }
- }
-
- internal void AddTotalItems(bool isTemplate)
- {
- AddTotalItems(RootItem, 0, isTemplate);
- }
- internal void Reset()
- {
- RootItem.Clear();
- nextIndex = 0;
- }
- /// <inheritdoc/>
- public void Serialize(FRWriter writer)
- {
- writer.ItemName = Name;
- foreach (MatrixHeaderDescriptor d in this)
- {
- writer.Write(d);
- }
- }
- /// <inheritdoc/>
- public void Deserialize(FRReader reader)
- {
- Clear();
- while (reader.NextItem())
- {
- MatrixHeaderDescriptor d = new MatrixHeaderDescriptor();
- reader.Read(d);
- Add(d);
- }
- }
- internal MatrixHeader()
- {
- rootItem = new MatrixHeaderItem(null);
- }
- }
- }
|