FastReport

Форк
0
294 строки · 9.9 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Collections;
5
using FastReport.Utils;
6

7
namespace FastReport.Matrix
8
{
9
    /// <summary>
10
    /// Represents a collection of matrix header descriptors used in the <see cref="MatrixObject"/>.
11
    /// </summary>
12
    public class MatrixHeader : CollectionBase, IFRSerializable
13
    {
14
        private MatrixHeaderItem rootItem;
15
        private int nextIndex;
16
        private string name;
17

18
        /// <summary>
19
        /// Gets or sets the element at the specified index.
20
        /// </summary>
21
        /// <param name="index">Index of an element.</param>
22
        /// <returns>The element at the specified index.</returns>
23
        public MatrixHeaderDescriptor this[int index]
24
        {
25
            get { return List[index] as MatrixHeaderDescriptor; }
26
            set { List[index] = value; }
27
        }
28

29
        internal MatrixHeaderItem RootItem
30
        {
31
            get { return rootItem; }
32
        }
33

34
        internal string Name
35
        {
36
            get { return name; }
37
            set { name = value; }
38
        }
39

40
        /// <summary>
41
        /// Adds the specified descriptors to the end of this collection.
42
        /// </summary>
43
        /// <param name="range">Array of descriptors to add.</param>
44
        public void AddRange(MatrixHeaderDescriptor[] range)
45
        {
46
            foreach (MatrixHeaderDescriptor s in range)
47
            {
48
                Add(s);
49
            }
50
        }
51

52
        /// <summary>
53
        /// Adds a descriptor to the end of this collection.
54
        /// </summary>
55
        /// <param name="value">Descriptor to add.</param>
56
        /// <returns>Index of the added descriptor.</returns>
57
        public int Add(MatrixHeaderDescriptor value)
58
        {
59
            return List.Add(value);
60
        }
61

62
        /// <summary>
63
        /// Inserts a descriptor into this collection at the specified index.
64
        /// </summary>
65
        /// <param name="index">The zero-based index at which value should be inserted.</param>
66
        /// <param name="value">The descriptor to insert.</param>
67
        public void Insert(int index, MatrixHeaderDescriptor value)
68
        {
69
            List.Insert(index, value);
70
        }
71

72
        /// <summary>
73
        /// Removes the specified descriptor from the collection.
74
        /// </summary>
75
        /// <param name="value">Descriptor to remove.</param>
76
        public void Remove(MatrixHeaderDescriptor value)
77
        {
78
            int i = IndexOf(value);
79
            if (i != -1)
80
                List.RemoveAt(i);
81
        }
82

83
        /// <summary>
84
        /// Returns the zero-based index of the first occurrence of a descriptor.
85
        /// </summary>
86
        /// <param name="value">The descriptor to locate in the collection.</param>
87
        /// <returns>The zero-based index of the first occurrence of descriptor within 
88
        /// the entire collection, if found; otherwise, -1.</returns>
89
        public int IndexOf(MatrixHeaderDescriptor value)
90
        {
91
            return List.IndexOf(value);
92
        }
93

94
        /// <summary>
95
        /// Determines whether a descriptor is in the collection.
96
        /// </summary>
97
        /// <param name="value">The descriptor to locate in the collection.</param>
98
        /// <returns><b>true</b> if descriptor is found in the collection; otherwise, <b>false</b>.</returns>
99
        public bool Contains(MatrixHeaderDescriptor value)
100
        {
101
            return List.Contains(value);
102
        }
103

104
        /// <summary>
105
        /// Copies the elements of this collection to a new array. 
106
        /// </summary>
107
        /// <returns>An array containing copies of this collection elements. </returns>
108
        public MatrixHeaderDescriptor[] ToArray()
109
        {
110
            MatrixHeaderDescriptor[] result = new MatrixHeaderDescriptor[Count];
111
            for (int i = 0; i < Count; i++)
112
            {
113
                result[i] = this[i];
114
            }
115
            return result;
116
        }
117

118
        /// <summary>
119
        /// Gets the list of indices of terminal items of this header.
120
        /// </summary>
121
        /// <returns>The list of indices.</returns>
122
        public int[] GetTerminalIndices()
123
        {
124
            return GetTerminalIndices(rootItem);
125
        }
126

127
        /// <summary>
128
        /// Gets the list of indices of terminal items of the header with specified address.
129
        /// </summary>
130
        /// <param name="address">The address of a header.</param>
131
        /// <returns>The list of indices.</returns>
132
        public int[] GetTerminalIndices(object[] address)
133
        {
134
            MatrixHeaderItem rootItem = Find(address, false, 0);
135
            return GetTerminalIndices(rootItem);
136
        }
137

138
        private int[] GetTerminalIndices(MatrixHeaderItem rootItem)
139
        {
140
            List<MatrixHeaderItem> terminalItems = rootItem.GetTerminalItems();
141
            int[] result = new int[terminalItems.Count];
142
            for (int i = 0; i < result.Length; i++)
143
                result[i] = terminalItems[i].Index;
144
            return result;
145
        }
146

147
        /// <summary>
148
        /// Removes a header item with the address specified. 
149
        /// </summary>
150
        /// <param name="address">The address of a header.</param>
151
        public void RemoveItem(object[] address)
152
        {
153
            MatrixHeaderItem item = Find(address, false, 0);
154
            if (item != null)
155
                item.Parent.Items.Remove(item);
156
        }
157

158
        /// <summary>
159
        /// Gets an index of header with the address specified. 
160
        /// </summary>
161
        /// <param name="address">The address of a header.</param>
162
        /// <returns>The index of header.</returns>
163
        public int Find(object[] address)
164
        {
165
            MatrixHeaderItem item = Find(address, false, 0);
166
            if (item != null)
167
                return item.Index;
168
            return -1;
169
        }
170

171
        /// <summary>
172
        /// Gets an index of header with the address specified. If there is no such header item, it will be created.
173
        /// </summary>
174
        /// <param name="address">The address of a header.</param>
175
        /// <returns>The index of header.</returns>
176
        public int FindOrCreate(object[] address)
177
        {
178
            MatrixHeaderItem item = Find(address, true, 0);
179
            if (item != null)
180
                return item.Index;
181
            return -1;
182
        }
183

184
        internal MatrixHeaderItem Find(object[] address, bool create, int dataRowNo)
185
        {
186
            // Note that the top header itself does not contain a value. 
187
            // It is used as a list of first-level headers only.
188
            MatrixHeaderItem rootItem = RootItem;
189

190
            for (int i = 0; i < address.Length; i++)
191
            {
192
                int index = rootItem.Find(address[i], this[i].Sort);
193

194
                if (index >= 0)
195
                    rootItem = rootItem.Items[index];
196
                else if (create)
197
                {
198
                    // create new item if necessary.
199
                    MatrixHeaderItem newItem = new MatrixHeaderItem(rootItem);
200
                    newItem.Value = address[i];
201
                    newItem.TemplateColumn = this[i].TemplateColumn;
202
                    newItem.TemplateRow = this[i].TemplateRow;
203
                    newItem.TemplateCell = this[i].TemplateCell;
204
                    newItem.DataRowNo = dataRowNo;
205
                    newItem.PageBreak = this[i].PageBreak;
206

207
                    // index is used as a cell address in a matrix
208
                    if (i == address.Length - 1)
209
                    {
210
                        // create index for bottom-level header
211
                        newItem.Index = nextIndex;
212
                        nextIndex++;
213
                    }
214

215
                    rootItem.Items.Insert(~index, newItem);
216
                    rootItem = newItem;
217
                }
218
                else
219
                    return null;
220
            }
221

222
            return rootItem;
223
        }
224

225

226
        private void AddTotalItems(MatrixHeaderItem rootItem, int descriptorIndex, bool isTemplate)
227
        {
228
            if (descriptorIndex >= Count)
229
                return;
230

231
            foreach (MatrixHeaderItem item in rootItem.Items)
232
            {
233
                AddTotalItems(item, descriptorIndex + 1, isTemplate);
234
            }
235

236
            if (this[descriptorIndex].Totals &&
237
              (isTemplate || !this[descriptorIndex].SuppressTotals || rootItem.Items.Count > 1))
238
            {
239
                MatrixHeaderItem totalItem = new MatrixHeaderItem(rootItem);
240
                totalItem.IsTotal = true;
241
                totalItem.Value = rootItem.Value;
242
                totalItem.DataRowNo = rootItem.DataRowNo;
243
                totalItem.TemplateColumn = this[descriptorIndex].TemplateTotalColumn;
244
                totalItem.TemplateRow = this[descriptorIndex].TemplateTotalRow;
245
                totalItem.TemplateCell = this[descriptorIndex].TemplateTotalCell;
246
                totalItem.Index = nextIndex;
247
                nextIndex++;
248

249
                if (this[descriptorIndex].TotalsFirst && !isTemplate)
250
                    rootItem.Items.Insert(0, totalItem);
251
                else
252
                    rootItem.Items.Add(totalItem);
253
            }
254
        }
255

256
        internal void AddTotalItems(bool isTemplate)
257
        {
258
            AddTotalItems(RootItem, 0, isTemplate);
259
        }
260

261
        internal void Reset()
262
        {
263
            RootItem.Clear();
264
            nextIndex = 0;
265
        }
266

267
        /// <inheritdoc/>
268
        public void Serialize(FRWriter writer)
269
        {
270
            writer.ItemName = Name;
271
            foreach (MatrixHeaderDescriptor d in this)
272
            {
273
                writer.Write(d);
274
            }
275
        }
276

277
        /// <inheritdoc/>
278
        public void Deserialize(FRReader reader)
279
        {
280
            Clear();
281
            while (reader.NextItem())
282
            {
283
                MatrixHeaderDescriptor d = new MatrixHeaderDescriptor();
284
                reader.Read(d);
285
                Add(d);
286
            }
287
        }
288

289
        internal MatrixHeader()
290
        {
291
            rootItem = new MatrixHeaderItem(null);
292
        }
293
    }
294
}
295

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.