• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MorganKryze / ConsoleAppVisuals / 8418737641

25 Mar 2024 10:35AM UTC coverage: 93.788%. Remained the same
8418737641

push

github

MorganKryze
🚑 (TableSelector) fix render issue with first display not rendering properly

917 of 1042 branches covered (88.0%)

Branch coverage included in aggregate %.

2012 of 2081 relevant lines covered (96.68%)

252.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.62
/src/ConsoleAppVisuals/elements/passive_elements/TableView.cs
1
/*
2
    GNU GPL License 2024 MorganKryze(Yann Vidamment)
3
    For full license information, please visit: https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/LICENSE
4
*/
5
namespace ConsoleAppVisuals.PassiveElements;
6

7
/// <summary>
8
/// A <see cref="TableView"/> is a passive element that displays a table on the console.
9
/// </summary>
10
/// <remarks>
11
/// For more information, refer to the following resources:
12
/// <list type="bullet">
13
/// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
14
/// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
15
/// </list>
16
/// </remarks>
17
public class TableView : PassiveElement
18
{
19
    #region Fields: title, headers, lines, display array, rounded corners
20
    private string? _title;
21
    private List<string>? _rawHeaders;
22
    private List<List<string>>? _rawLines;
23
    private string[]? _displayArray;
24
    private Placement _placement;
25
    private readonly Borders _borders;
26
    #endregion
27

28
    #region Properties: get headers, get lines
29
    /// <summary>
30
    /// This property returns the headers of the table.
31
    /// </summary>
32
    public List<string>? GetRawHeaders => _rawHeaders;
4✔
33

34
    /// <summary>
35
    /// This property returns the lines of the table.
36
    /// </summary>
37
    public List<List<string>>? GetRawLines => _rawLines;
3✔
38

39
    /// <summary>
40
    /// This property returns the title of the table.
41
    /// </summary>
42
    public override Placement Placement => _placement;
2✔
43

44
    /// <summary>
45
    /// This property returns the height of the table.
46
    /// </summary>
47
    public override int Height => _displayArray?.Length ?? 0;
9✔
48

49
    /// <summary>
50
    /// This property returns the width of the table.
51
    /// </summary>
52
    public override int Width => _displayArray?.Max(x => x.Length) ?? 0;
1!
53

54
    /// <summary>
55
    /// This property returns the number of lines in the table.
56
    /// </summary>
57
    public int Count => _rawLines?.Count ?? 0;
8✔
58

59
    /// <summary>
60
    /// This property returns the borders of the table.
61
    /// </summary>
62
    public Borders Borders => _borders;
2,116✔
63

64
    /// <summary>
65
    /// The border type of the selector.
66
    /// </summary>
67
    public BordersType BordersType => _borders.Type;
1✔
68
    #endregion
69

70
    #region Constructor
71
    /// <summary>
72
    /// A <see cref="TableView"/> is a passive element that displays a table on the console.
73
    /// </summary>
74
    /// <param name="title">The title of the table.</param>s
75
    /// <param name="headers">The headers of the table.</param>
76
    /// <param name="lines">The lines of the table.</param>
77
    /// <param name="placement">The placement of the table.</param>
78
    /// <param name="bordersType">The type of borders to use for the table.</param>
79
    /// <exception cref="ArgumentException">Is thrown when the number of columns in the table is not consistent with itself or with the headers.</exception>
80
    /// <exception cref="NullReferenceException">Is thrown when no body lines were provided.</exception>
81
    /// <remarks>
82
    /// For more information, refer to the following resources:
83
    /// <list type="bullet">
84
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
85
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
86
    /// </list>
87
    /// </remarks>
88
    public TableView(
59✔
89
        string? title = null,
59✔
90
        List<string>? headers = null,
59✔
91
        List<List<string>>? lines = null,
59✔
92
        Placement placement = Placement.TopCenter,
59✔
93
        BordersType bordersType = BordersType.SingleStraight
59✔
94
    )
59✔
95
    {
96
        _title = title;
59✔
97
        _rawHeaders = headers;
59✔
98
        _rawLines = lines;
59✔
99
        _borders = new Borders(bordersType);
59✔
100
        _placement = placement;
59✔
101
        if (CompatibilityCheck())
59✔
102
        {
103
            BuildTable();
51✔
104
        }
105
    }
57✔
106
    #endregion
107

108
    #region Check Methods
109
    private bool CompatibilityCheck()
110
    {
111
        if (_rawHeaders is null)
62✔
112
        {
113
            return CheckRawLines();
7✔
114
        }
115
        else if (_rawLines is null)
55✔
116
        {
117
            return true;
1✔
118
        }
119
        else
120
        {
121
            return CheckRawHeadersAndLines();
54✔
122
        }
123
    }
124

125
    private bool CheckRawLines()
126
    {
127
        if (_rawLines is null || _rawLines.Count == 0)
7✔
128
        {
129
            return false;
2✔
130
        }
131

132
        for (int i = 0; i < _rawLines.Count; i++)
28✔
133
        {
134
            if (_rawLines[i].Count != _rawLines[0].Count)
10✔
135
            {
136
                throw new ArgumentException(
1✔
137
                    "The number of columns in the table is not consistent."
1✔
138
                );
1✔
139
            }
140
        }
141
        return true;
4✔
142
    }
143

144
    private bool CheckRawHeadersAndLines()
145
    {
146
        if (_rawLines is null || _rawLines.Count == 0)
54✔
147
        {
148
            return false;
4✔
149
        }
150

151
        if (_rawLines.Count > 0)
50✔
152
        {
153
            for (int i = 0; i < _rawLines.Count; i++)
284✔
154
            {
155
                if (_rawLines[i].Count != _rawHeaders?.Count)
94!
156
                {
157
                    throw new ArgumentException(
2✔
158
                        "The number of columns in the table is not consistent(Headers or Lines)."
2✔
159
                    );
2✔
160
                }
161
            }
162
        }
163
        return true;
48✔
164
    }
165
    #endregion
166

167
    #region Build Methods
168
    private void BuildTable()
169
    {
170
        if (_rawHeaders is null)
71✔
171
        {
172
            if (_rawLines is not null)
10✔
173
            {
174
                BuildLines();
8✔
175
            }
176
        }
177
        else
178
        {
179
            if (_rawLines is null)
61✔
180
            {
181
                BuildHeaders();
2✔
182
            }
183
            else
184
            {
185
                BuildHeadersAndLines();
59✔
186
            }
187
        }
188
    }
61✔
189

190
    private void BuildHeadersAndLines()
191
    {
192
        if (_rawHeaders is not null && _rawLines is not null)
59✔
193
        {
194
            var stringList = new List<string>();
59✔
195
            var localMax = new int[_rawHeaders.Count];
59✔
196
            for (int i = 0; i < _rawHeaders.Count; i++)
472✔
197
            {
198
                if (_rawHeaders[i]?.Length > localMax[i])
177!
199
                {
200
                    localMax[i] = _rawHeaders[i]?.Length ?? 0;
177!
201
                }
202
            }
203

204
            for (int i = 0; i < _rawLines.Count; i++)
318✔
205
            {
206
                for (int j = 0; j < _rawLines[i].Count; j++)
800✔
207
                {
208
                    if (_rawLines[i][j]?.ToString()?.Length > localMax[j])
300!
209
                    {
210
                        localMax[j] = _rawLines[i][j]?.ToString()?.Length ?? 0;
×
211
                    }
212
                }
213
            }
214

215
            StringBuilder headerBuilder = new($"{Borders.Vertical} ");
59✔
216
            for (int i = 0; i < _rawHeaders.Count; i++)
472✔
217
            {
218
                headerBuilder.Append(_rawHeaders[i]?.PadRight(localMax[i]) ?? "");
177!
219
                if (i != _rawHeaders.Count - 1)
177✔
220
                {
221
                    headerBuilder.Append($" {Borders.Vertical} ");
118✔
222
                }
223
                else
224
                {
225
                    headerBuilder.Append($" {Borders.Vertical}");
59✔
226
                }
227
            }
228
            stringList.Add(headerBuilder.ToString());
59✔
229

230
            StringBuilder upperBorderBuilder = new(Borders.TopLeft.ToString());
59✔
231
            for (int i = 0; i < _rawHeaders.Count; i++)
472✔
232
            {
233
                upperBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
177✔
234
                upperBorderBuilder.Append(
177✔
235
                    (i != _rawHeaders.Count - 1)
177✔
236
                        ? Borders.Top.ToString()
177✔
237
                        : Borders.TopRight.ToString()
177✔
238
                );
177✔
239
            }
240
            stringList.Insert(0, upperBorderBuilder.ToString());
59✔
241

242
            StringBuilder intermediateBorderBuilder = new($"{Borders.Left}");
59✔
243
            for (int i = 0; i < _rawHeaders.Count; i++)
472✔
244
            {
245
                intermediateBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
177✔
246
                intermediateBorderBuilder.Append(
177✔
247
                    (i != _rawHeaders.Count - 1) ? Borders.Cross : Borders.Right
177✔
248
                );
177✔
249
            }
250
            stringList.Add(intermediateBorderBuilder.ToString());
59✔
251

252
            for (int i = 0; i < _rawLines.Count; i++)
318✔
253
            {
254
                StringBuilder lineBuilder = new($"{Borders.Vertical} ");
100✔
255
                for (int j = 0; j < _rawLines[i].Count; j++)
800✔
256
                {
257
                    lineBuilder.Append(_rawLines[i][j]?.ToString()?.PadRight(localMax[j]) ?? "");
300!
258
                    if (j != _rawLines[i].Count - 1)
300✔
259
                    {
260
                        lineBuilder.Append($" {Borders.Vertical} ");
200✔
261
                    }
262
                    else
263
                    {
264
                        lineBuilder.Append($" {Borders.Vertical}");
100✔
265
                    }
266
                }
267
                stringList.Add(lineBuilder.ToString());
100✔
268
            }
269

270
            StringBuilder lowerBorderBuilder = new(Borders.BottomLeft.ToString());
59✔
271
            for (int i = 0; i < _rawHeaders.Count; i++)
472✔
272
            {
273
                lowerBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
177✔
274
                lowerBorderBuilder.Append(
177✔
275
                    (i != _rawHeaders.Count - 1)
177✔
276
                        ? Borders.Bottom.ToString()
177✔
277
                        : Borders.BottomRight.ToString()
177✔
278
                );
177✔
279
            }
280
            stringList.Add(lowerBorderBuilder.ToString());
59✔
281

282
            _displayArray = stringList.ToArray();
59✔
283
            BuildTitle();
59✔
284
        }
285
    }
59✔
286

287
    private void BuildHeaders()
288
    {
289
        if (_rawHeaders is not null)
2✔
290
        {
291
            var stringList = new List<string>();
2✔
292
            var localMax = new int[_rawHeaders.Count];
2✔
293
            for (int i = 0; i < _rawHeaders.Count; i++)
16✔
294
            {
295
                if (_rawHeaders[i]?.Length > localMax[i])
6!
296
                {
297
                    localMax[i] = _rawHeaders[i]?.Length ?? 0;
6!
298
                }
299
            }
300
            StringBuilder headerBuilder = new($"{Borders.Vertical} ");
2✔
301
            for (int i = 0; i < _rawHeaders.Count; i++)
16✔
302
            {
303
                headerBuilder.Append(_rawHeaders[i]?.PadRight(localMax[i]) ?? "");
6!
304
                if (i != _rawHeaders.Count - 1)
6✔
305
                {
306
                    headerBuilder.Append($" {Borders.Vertical} ");
4✔
307
                }
308
                else
309
                {
310
                    headerBuilder.Append($" {Borders.Vertical}");
2✔
311
                }
312
            }
313
            stringList.Add(headerBuilder.ToString());
2✔
314
            StringBuilder upperBorderBuilder = new(Borders.TopLeft.ToString());
2✔
315
            for (int i = 0; i < _rawHeaders.Count; i++)
16✔
316
            {
317
                upperBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
6✔
318
                upperBorderBuilder.Append(
6✔
319
                    (i != _rawHeaders.Count - 1)
6✔
320
                        ? Borders.Top.ToString()
6✔
321
                        : Borders.TopRight.ToString()
6✔
322
                );
6✔
323
            }
324
            stringList.Insert(0, upperBorderBuilder.ToString());
2✔
325
            StringBuilder lowerBorderBuilder = new(Borders.BottomLeft.ToString());
2✔
326
            for (int i = 0; i < _rawHeaders.Count; i++)
16✔
327
            {
328
                lowerBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
6✔
329
                lowerBorderBuilder.Append(
6✔
330
                    (i != _rawHeaders.Count - 1)
6✔
331
                        ? Borders.Bottom.ToString()
6✔
332
                        : Borders.BottomRight.ToString()
6✔
333
                );
6✔
334
            }
335
            stringList.Add(lowerBorderBuilder.ToString());
2✔
336
            _displayArray = stringList.ToArray();
2✔
337
            BuildTitle();
2✔
338
        }
339
    }
2✔
340

341
    private void BuildLines()
342
    {
343
        if (_rawLines is not null)
8✔
344
        {
345
            var stringList = new List<string>();
8✔
346
            var localMax = new int[_rawLines[0].Count];
8✔
347
            for (int i = 0; i < _rawLines.Count; i++)
44✔
348
            {
349
                for (int j = 0; j < _rawLines[i].Count; j++)
112✔
350
                {
351
                    if (_rawLines[i][j]?.ToString()?.Length > localMax[j])
42!
352
                    {
353
                        localMax[j] = _rawLines[i][j]?.ToString()?.Length ?? 0;
24!
354
                    }
355
                }
356
            }
357
            for (int i = 0; i < _rawLines.Count; i++)
44✔
358
            {
359
                StringBuilder line = new($"{Borders.Vertical} ");
14✔
360
                for (int j = 0; j < _rawLines[i].Count; j++)
112✔
361
                {
362
                    line.Append(_rawLines[i][j]?.ToString()?.PadRight(localMax[j]) ?? "");
42!
363
                    if (j != _rawLines[i].Count - 1)
42✔
364
                    {
365
                        line.Append($" {Borders.Vertical} ");
28✔
366
                    }
367
                    else
368
                    {
369
                        line.Append($" {Borders.Vertical}");
14✔
370
                    }
371
                }
372
                stringList.Add(line.ToString());
14✔
373
            }
374
            StringBuilder upperBorderBuilder = new(Borders.TopLeft.ToString());
8✔
375
            for (int i = 0; i < _rawLines.Count; i++)
44✔
376
            {
377
                upperBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
14✔
378
                upperBorderBuilder.Append(
14✔
379
                    (i != _rawLines.Count - 1)
14✔
380
                        ? Borders.Top.ToString()
14✔
381
                        : Borders.TopRight.ToString()
14✔
382
                );
14✔
383
            }
384
            stringList.Insert(0, upperBorderBuilder.ToString());
8✔
385
            StringBuilder lowerBorderBuilder = new(Borders.BottomLeft.ToString());
8✔
386
            for (int i = 0; i < _rawLines.Count; i++)
44✔
387
            {
388
                lowerBorderBuilder.Append(new string(Borders.Horizontal, localMax[i] + 2));
14✔
389
                lowerBorderBuilder.Append(
14✔
390
                    (i != _rawLines.Count - 1)
14✔
391
                        ? Borders.Bottom.ToString()
14✔
392
                        : Borders.BottomRight.ToString()
14✔
393
                );
14✔
394
            }
395
            stringList.Add(lowerBorderBuilder.ToString());
8✔
396
            _displayArray = stringList.ToArray();
8✔
397
            BuildTitle();
8✔
398
        }
399
    }
8✔
400

401
    private void BuildTitle()
402
    {
403
        if (_title is not null)
69✔
404
        {
405
            var len = _displayArray![0].Length;
11✔
406
            var title = _title.ResizeString(len - 4);
11✔
407
            title = $"{Borders.Vertical} {title} {Borders.Vertical}";
11✔
408
            var upperBorderBuilder = new StringBuilder(Borders.TopLeft.ToString());
11✔
409
            upperBorderBuilder.Append(new string(Borders.Horizontal, len - 2));
11✔
410
            upperBorderBuilder.Append(Borders.TopRight.ToString());
11✔
411
            var display = _displayArray.ToList();
11✔
412
            display[0] = display[0]
11✔
413
                .Remove(0, 1)
11✔
414
                .Insert(0, Borders.Left.ToString())
11✔
415
                .Remove(display[1].Length - 1, 1)
11✔
416
                .Insert(display[1].Length - 1, Borders.Right.ToString());
11✔
417
            display.Insert(0, title);
11✔
418
            display.Insert(0, upperBorderBuilder.ToString());
11✔
419
            _displayArray = display.ToArray();
11✔
420
        }
421
    }
69✔
422
    #endregion
423

424
    #region Methods: Get, Add, Update, Remove, Clear
425
    /// <summary>
426
    /// Updates the placement of the table.
427
    /// </summary>
428
    /// <param name="placement">The new placement of the table.</param>
429
    /// <remarks>
430
    /// For more information, refer to the following resources:
431
    /// <list type="bullet">
432
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
433
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
434
    /// </list>
435
    /// </remarks>
436
    public void UpdatePlacement(Placement placement)
437
    {
438
        _placement = placement;
1✔
439
        BuildTable();
1✔
440
    }
1✔
441

442
    /// <summary>
443
    /// This method updates the borders of the table.
444
    /// </summary>
445
    /// <param name="bordersType">The type of border to use for the table.</param>
446
    /// <remarks>
447
    /// For more information, refer to the following resources:
448
    /// <list type="bullet">
449
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
450
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
451
    /// </list>
452
    /// </remarks>
453
    public void UpdateBordersType(BordersType bordersType)
454
    {
455
        _borders.UpdateBordersType(bordersType);
1✔
456
        BuildTable();
1✔
457
    }
1✔
458

459
    /// <summary>
460
    /// This method adds a title to the table.
461
    /// </summary>
462
    /// <param name="title">The title to add.</param>
463
    /// <remarks>
464
    /// For more information, refer to the following resources:
465
    /// <list type="bullet">
466
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
467
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
468
    /// </list>
469
    /// </remarks>
470
    public void AddTitle(string title)
471
    {
472
        _title = title;
2✔
473
        BuildTable();
2✔
474
    }
2✔
475

476
    /// <summary>
477
    /// This method updates the title of the table.
478
    /// </summary>
479
    /// <param name="title">The title to update.</param>
480
    /// <remarks>
481
    /// For more information, refer to the following resources:
482
    /// <list type="bullet">
483
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
484
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
485
    /// </list>
486
    /// </remarks>
487
    public void UpdateTitle(string title)
488
    {
489
        AddTitle(title);
1✔
490
    }
1✔
491

492
    /// <summary>
493
    /// This method clears the title of the table.
494
    /// </summary>
495
    /// <remarks>
496
    /// For more information, refer to the following resources:
497
    /// <list type="bullet">
498
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
499
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
500
    /// </list>
501
    /// </remarks>
502
    public void ClearTitle()
503
    {
504
        _title = null;
3✔
505
        BuildTable();
3✔
506
    }
3✔
507

508
    /// <summary>
509
    /// This method adds headers to the table.
510
    /// </summary>
511
    /// <param name="headers">The headers to add.</param>
512
    /// <remarks>
513
    /// For more information, refer to the following resources:
514
    /// <list type="bullet">
515
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
516
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
517
    /// </list>
518
    /// </remarks>
519
    public void AddHeaders(List<string> headers)
520
    {
521
        _rawHeaders = headers;
3✔
522
        if (CompatibilityCheck())
3✔
523
        {
524
            BuildTable();
2✔
525
        }
526
    }
2✔
527

528
    /// <summary>
529
    /// This method updates the headers of the table.
530
    /// </summary>
531
    /// <param name="headers">The headers to update.</param>
532
    /// <remarks>
533
    /// For more information, refer to the following resources:
534
    /// <list type="bullet">
535
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
536
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
537
    /// </list>
538
    /// </remarks>
539
    public void UpdateHeaders(List<string> headers)
540
    {
541
        AddHeaders(headers);
1✔
542
    }
1✔
543

544
    /// <summary>
545
    /// This method clears the headers of the table.
546
    /// </summary>
547
    /// <remarks>
548
    /// For more information, refer to the following resources:
549
    /// <list type="bullet">
550
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
551
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
552
    /// </list>
553
    /// </remarks>
554
    public void ClearHeaders()
555
    {
556
        _rawHeaders = null;
4✔
557
        BuildTable();
4✔
558
    }
4✔
559

560
    /// <summary>
561
    /// This method adds a line to the table.
562
    /// </summary>
563
    /// <param name="line">The line to add.</param>
564
    /// <exception cref="ArgumentException">Is thrown when the number of columns in the table is not consistent with itself or with the headers.</exception>
565
    /// <remarks>
566
    /// For more information, refer to the following resources:
567
    /// <list type="bullet">
568
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
569
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
570
    /// </list>
571
    /// </remarks>
572
    public void AddLine(List<string> line)
573
    {
574
        if (_rawLines?.Count > 0 && line.Count != _rawLines[0].Count)
4✔
575
        {
576
            throw new ArgumentException(
1✔
577
                "The number of columns in the table is not consistent with other lines."
1✔
578
            );
1✔
579
        }
580
        if (_rawHeaders is not null && line.Count != _rawHeaders.Count)
3✔
581
        {
582
            throw new ArgumentException(
1✔
583
                "The number of columns in the table is not consistent with the headers."
1✔
584
            );
1✔
585
        }
586
        _rawLines ??= new List<List<string>>();
2!
587
        _rawLines.Add(line);
2✔
588
        BuildTable();
2✔
589
    }
2✔
590

591
    /// <summary>
592
    /// This method updates a line in the table.
593
    /// </summary>
594
    /// <param name="index">The index of the line to update.</param>
595
    /// <param name="line">The new line.</param>
596
    /// <exception cref="ArgumentOutOfRangeException">Is thrown when the index is out of range.</exception>
597
    /// <exception cref="ArgumentException">Is thrown when the number of columns in the table is not consistent with itself or with the headers.</exception>
598
    /// <remarks>
599
    /// For more information, refer to the following resources:
600
    /// <list type="bullet">
601
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
602
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
603
    /// </list>
604
    /// </remarks>
605
    public void UpdateLine(int index, List<string> line)
606
    {
607
        if (_rawLines?.Count > 0)
3!
608
        {
609
            if (index < 0 || index >= _rawLines.Count)
3✔
610
            {
611
                throw new ArgumentOutOfRangeException(nameof(index), "The index is out of range.");
1✔
612
            }
613

614
            if (line.Count != _rawHeaders?.Count)
2!
615
            {
616
                throw new ArgumentException(
1✔
617
                    "The number of columns in the table is not consistent."
1✔
618
                );
1✔
619
            }
620
        }
621
        _rawLines![index] = line;
1✔
622
        BuildTable();
1✔
623
    }
1✔
624

625
    /// <summary>
626
    /// This method removes a line from the table.
627
    /// </summary>
628
    /// <param name="index">The index of the line to remove.</param>
629
    /// <exception cref="ArgumentOutOfRangeException">Is thrown when the index is out of range.</exception>
630
    /// <remarks>
631
    /// For more information, refer to the following resources:
632
    /// <list type="bullet">
633
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
634
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
635
    /// </list>
636
    /// </remarks>
637
    public void RemoveLine(int index)
638
    {
639
        if (_rawLines?.Count > 0 && (index < 0 || index >= _rawLines.Count))
2!
640
        {
641
            throw new ArgumentOutOfRangeException(nameof(index), "The index is out of range.");
1✔
642
        }
643

644
        _rawLines?.RemoveAt(index);
1!
645
        BuildTable();
1✔
646
    }
1✔
647

648
    /// <summary>
649
    /// This method clears the lines of the table.
650
    /// </summary>
651
    /// <remarks>
652
    /// For more information, refer to the following resources:
653
    /// <list type="bullet">
654
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
655
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
656
    /// </list>
657
    /// </remarks>
658
    public void ClearLines()
659
    {
660
        _rawLines = null;
3✔
661
        BuildTable();
3✔
662
    }
3✔
663

664
    /// <summary>
665
    /// This property returns the specified line in the table.
666
    /// </summary>
667
    /// <param name="index">The index of the line to return.</param>
668
    /// <returns>The line at the specified index.</returns>
669
    /// <exception cref="ArgumentOutOfRangeException">Is thrown when the index is out of range.</exception>
670
    /// <remarks>
671
    /// For more information, refer to the following resources:
672
    /// <list type="bullet">
673
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
674
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
675
    /// </list>
676
    /// </remarks>
677
    public List<string> GetLine(int index)
678
    {
679
        if (index < 0 || index >= _rawLines?.Count)
3!
680
        {
681
            throw new ArgumentOutOfRangeException(nameof(index), "The index is out of range.");
1✔
682
        }
683
        return _rawLines![index];
2✔
684
    }
685

686
    /// <summary>
687
    /// This method is used to get all the elements from a column given its index.
688
    /// </summary>
689
    /// <param name="index">The index of the column.</param>
690
    /// <returns>The elements of the column.</returns>
691
    /// <exception cref="ArgumentOutOfRangeException">Is thrown when the index is out of range.</exception>
692
    /// <remarks>
693
    /// For more information, refer to the following resources:
694
    /// <list type="bullet">
695
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
696
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
697
    /// </list>
698
    /// </remarks>
699
    public List<string>? GetColumnData(int index)
700
    {
701
        if (_rawLines is null)
4✔
702
        {
703
            return null;
1✔
704
        }
705

706
        if (index < 0 || index >= _rawLines[0].Count)
3✔
707
        {
708
            throw new ArgumentOutOfRangeException(nameof(index), "Invalid column index.");
1✔
709
        }
710

711
        List<string>? list = new();
2✔
712
        for (int i = 0; i < _rawLines.Count; i++)
12✔
713
        {
714
            list.Add(_rawLines[i][index]);
4✔
715
        }
716
        return list;
2✔
717
    }
718

719
    /// <summary>
720
    /// This method is used to get all the elements from a column given its header.
721
    /// </summary>
722
    /// <param name="header">The header of the column.</param>
723
    /// <returns>The elements of the column.</returns>
724
    /// <exception cref="InvalidOperationException">Is thrown when the table is empty.</exception>
725
    /// <exception cref="ArgumentOutOfRangeException">Is thrown when the header is invalid.</exception>
726
    /// <remarks>
727
    /// For more information, refer to the following resources:
728
    /// <list type="bullet">
729
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
730
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
731
    /// </list>
732
    /// </remarks>
733
    public List<string>? GetColumnData(string header)
734
    {
735
        if (_rawHeaders is null)
4✔
736
        {
737
            throw new InvalidOperationException("The headers are null.");
1✔
738
        }
739
        else if (_rawLines is null)
3✔
740
        {
741
            return null;
1✔
742
        }
743
        if (!_rawHeaders.Contains(header))
2✔
744
        {
745
            throw new ArgumentOutOfRangeException(nameof(header), "Invalid column header.");
1✔
746
        }
747

748
        return GetColumnData(_rawHeaders.IndexOf(header));
1✔
749
    }
750

751
    /// <summary>
752
    /// This method clears the table.
753
    /// </summary>
754
    /// <remarks>
755
    /// For more information, refer to the following resources:
756
    /// <list type="bullet">
757
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
758
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
759
    /// </list>
760
    /// </remarks>
761
    public void Reset()
762
    {
763
        _title = null;
1✔
764
        _rawHeaders?.Clear();
1!
765
        _rawLines?.Clear();
1!
766
        _displayArray = null;
1✔
767
    }
1✔
768
    #endregion
769

770
    #region Render
771
    /// <summary>
772
    /// This method displays the table without interaction.
773
    /// </summary>
774
    [Visual]
775
    protected override void RenderElementActions()
776
    {
777
        string[] array = new string[_displayArray!.Length];
778
        for (int j = 0; j < _displayArray.Length; j++)
779
        {
780
            array[j] = _displayArray[j];
781
            Core.WritePositionedString(array[j], _placement, false, Line + j);
782
        }
783
    }
784
    #endregion
785
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc