FreeCAD

Форк
0
/
MaterialValue.cpp 
852 строки · 22.4 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2023 David Carter <dcarter@david.carter.ca>             *
3
 *                                                                         *
4
 *   This file is part of FreeCAD.                                         *
5
 *                                                                         *
6
 *   FreeCAD is free software: you can redistribute it and/or modify it    *
7
 *   under the terms of the GNU Lesser General Public License as           *
8
 *   published by the Free Software Foundation, either version 2.1 of the  *
9
 *   License, or (at your option) any later version.                       *
10
 *                                                                         *
11
 *   FreeCAD is distributed in the hope that it will be useful, but        *
12
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
14
 *   Lesser General Public License for more details.                       *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Lesser General Public      *
17
 *   License along with FreeCAD. If not, see                               *
18
 *   <https://www.gnu.org/licenses/>.                                      *
19
 *                                                                         *
20
 **************************************************************************/
21

22
#include "PreCompiled.h"
23
#ifndef _PreComp_
24
#include <QMetaType>
25
#include <QRegularExpression>
26
#endif
27

28
#include <App/Application.h>
29
#include <Base/QtTools.h>
30
#include <Base/Quantity.h>
31
#include <Gui/MetaTypes.h>
32

33
#include "Exceptions.h"
34
#include "MaterialValue.h"
35

36

37
using namespace Materials;
38

39
/* TRANSLATOR Material::MaterialValue */
40

41
TYPESYSTEM_SOURCE(Materials::MaterialValue, Base::BaseClass)
42

43
QMap<QString, MaterialValue::ValueType> MaterialValue::_typeMap {
44
    {QString::fromStdString("String"), String},
45
    {QString::fromStdString("Boolean"), Boolean},
46
    {QString::fromStdString("Integer"), Integer},
47
    {QString::fromStdString("Float"), Float},
48
    {QString::fromStdString("Quantity"), Quantity},
49
    {QString::fromStdString("Distribution"), Distribution},
50
    {QString::fromStdString("List"), List},
51
    {QString::fromStdString("2DArray"), Array2D},
52
    {QString::fromStdString("3DArray"), Array3D},
53
    {QString::fromStdString("Color"), Color},
54
    {QString::fromStdString("Image"), Image},
55
    {QString::fromStdString("File"), File},
56
    {QString::fromStdString("URL"), URL},
57
    {QString::fromStdString("MultiLineString"), MultiLineString},
58
    {QString::fromStdString("FileList"), FileList},
59
    {QString::fromStdString("ImageList"), ImageList},
60
    {QString::fromStdString("SVG"), SVG}};
61

62
MaterialValue::MaterialValue()
63
    : _valueType(None)
64
{
65
    this->setInitialValue(None);
66
}
67

68
MaterialValue::MaterialValue(const MaterialValue& other)
69
    : _valueType(other._valueType)
70
    , _value(other._value)
71
{}
72

73
MaterialValue::MaterialValue(ValueType type)
74
    : _valueType(type)
75
{
76
    this->setInitialValue(None);
77
}
78

79
MaterialValue::MaterialValue(ValueType type, ValueType inherited)
80
    : _valueType(type)
81
{
82
    this->setInitialValue(inherited);
83
}
84

85
MaterialValue& MaterialValue::operator=(const MaterialValue& other)
86
{
87
    if (this == &other) {
88
        return *this;
89
    }
90

91
    _valueType = other._valueType;
92
    _value = other._value;
93

94
    return *this;
95
}
96

97
bool MaterialValue::operator==(const MaterialValue& other) const
98
{
99
    if (this == &other) {
100
        return true;
101
    }
102

103
    return (_valueType == other._valueType) && (_value == other._value);
104
}
105

106
QString MaterialValue::escapeString(const QString& source)
107
{
108
    QString res = source;
109
    res.replace(QString::fromStdString("\\"), QString::fromStdString("\\\\"));
110
    res.replace(QString::fromStdString("\""), QString::fromStdString("\\\""));
111
    return res;
112
}
113

114
MaterialValue::ValueType MaterialValue::mapType(const QString& stringType)
115
{
116
    // If not found, return None
117
    return _typeMap.value(stringType, None);
118
}
119

120
void MaterialValue::setInitialValue(ValueType inherited)
121
{
122
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
123
    if (_valueType == String || _valueType == MultiLineString || _valueType == SVG) {
124
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
125
    }
126
    else if (_valueType == Boolean) {
127
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::Bool));
128
    }
129
    else if (_valueType == Integer) {
130
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::Int));
131
    }
132
    else if (_valueType == Float) {
133
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::Float));
134
    }
135
    else if (_valueType == URL) {
136
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
137
    }
138
    else if (_valueType == Color) {
139
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
140
    }
141
    else if (_valueType == File) {
142
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
143
    }
144
    else if (_valueType == Image) {
145
        _value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
146
    }
147
#else
148
    if (_valueType == String || _valueType == MultiLineString || _valueType == SVG) {
149
        _value = QVariant(QMetaType(QMetaType::QString));
150
    }
151
    else if (_valueType == Boolean) {
152
        _value = QVariant(QMetaType(QMetaType::Bool));
153
    }
154
    else if (_valueType == Integer) {
155
        _value = QVariant(QMetaType(QMetaType::Int));
156
    }
157
    else if (_valueType == Float) {
158
        _value = QVariant(QMetaType(QMetaType::Float));
159
    }
160
    else if (_valueType == URL) {
161
        _value = QVariant(QMetaType(QMetaType::QString));
162
    }
163
    else if (_valueType == Color) {
164
        _value = QVariant(QMetaType(QMetaType::QString));
165
    }
166
    else if (_valueType == File) {
167
        _value = QVariant(QMetaType(QMetaType::QString));
168
    }
169
    else if (_valueType == Image) {
170
        _value = QVariant(QMetaType(QMetaType::QString));
171
    }
172
#endif
173
    else if (_valueType == Quantity) {
174
        Base::Quantity qu;
175
        qu.setInvalid();
176
        _value = QVariant::fromValue(qu);
177
    }
178
    else if (_valueType == List || _valueType == FileList || _valueType == ImageList) {
179
        auto list = QList<QVariant>();
180
        _value = QVariant::fromValue(list);
181
    }
182
    else if (_valueType == Array2D) {
183
        if (_valueType != inherited) {
184
            throw InvalidMaterialType("Initializing a regular material value as a 2D Array");
185
        }
186

187
        _value = QVariant();  // Uninitialized default value
188
    }
189
    else if (_valueType == Array3D) {
190
        if (_valueType != inherited) {
191
            throw InvalidMaterialType("Initializing a regular material value as a 3D Array");
192
        }
193

194
        _value = QVariant();  // Uninitialized default value
195
    }
196
    else {
197
        // Default is to set the type to None and leave the variant uninitialized
198
        _valueType = None;
199
        _value = QVariant();
200
    }
201
}
202

203
void MaterialValue::setList(const QList<QVariant>& value)
204
{
205
    _value = QVariant::fromValue(value);
206
}
207

208
bool MaterialValue::isNull() const
209
{
210
    if (_value.isNull()) {
211
        return true;
212
    }
213

214
    if (_valueType == Quantity) {
215
        return !_value.value<Base::Quantity>().isValid();
216
    }
217

218
    if (_valueType == List || _valueType == FileList || _valueType == ImageList) {
219
        return _value.value<QList<QVariant>>().isEmpty();
220
    }
221

222
    return false;
223
}
224

225
QString MaterialValue::getYAMLStringImage() const
226
{
227
    QString yaml;
228
    yaml = QString::fromStdString(" |-2");
229
    QString base64 = getValue().toString();
230
    while (!base64.isEmpty()) {
231
        yaml += QString::fromStdString("\n      ") + base64.left(74);
232
        base64.remove(0, 74);
233
    }
234
    return yaml;
235
}
236

237
QString MaterialValue::getYAMLStringList() const
238
{
239
    QString yaml;
240
    for (auto& it : getList()) {
241
        yaml += QString::fromStdString("\n      - \"") + escapeString(it.toString())
242
            + QString::fromStdString("\"");
243
    }
244
    return yaml;
245
}
246

247
QString MaterialValue::getYAMLStringImageList() const
248
{
249
    QString yaml;
250
    for (auto& it : getList()) {
251
        yaml += QString::fromStdString("\n      - |-2");
252
        QString base64 = it.toString();
253
        while (!base64.isEmpty()) {
254
            yaml += QString::fromStdString("\n        ") + base64.left(72);
255
            base64.remove(0, 72);
256
        }
257
    }
258
    return yaml;
259
}
260

261
QString MaterialValue::getYAMLStringMultiLine() const
262
{
263
    QString yaml;
264
    yaml = QString::fromStdString(" |2");
265
    auto list =
266
        getValue().toString().split(QRegularExpression(QString::fromStdString("[\r\n]")), Qt::SkipEmptyParts);
267
    for (auto& it : list) {
268
        yaml += QString::fromStdString("\n      ") + it;
269
    }
270
    return yaml;
271
}
272

273
QString MaterialValue::getYAMLString() const
274
{
275
    QString yaml;
276
    if (!isNull()) {
277
        if (getType() == MaterialValue::Image) {
278
            return getYAMLStringImage();
279
        }
280
        if (getType() == MaterialValue::List || getType() == MaterialValue::FileList) {
281
            return getYAMLStringList();
282
        }
283
        if (getType() == MaterialValue::ImageList) {
284
            return getYAMLStringImageList();
285
        }
286
        if (getType() == MaterialValue::MultiLineString || getType() == MaterialValue::SVG) {
287
            return getYAMLStringMultiLine();
288
        }
289
        if (getType() == MaterialValue::Quantity) {
290
            auto quantity = getValue().value<Base::Quantity>();
291
            yaml += quantity.getUserString();
292
        }
293
        else if (getType() == MaterialValue::Float) {
294
            auto value = getValue();
295
            if (!value.isNull()) {
296
                yaml += QString::fromLatin1("%1").arg(value.toFloat(), 0, 'g', 6);
297
            }
298
        }
299
        else if (getType() == MaterialValue::List) {
300
            for (auto& it : getList()) {
301
                yaml += QString::fromLatin1("\n      - \"") + escapeString(it.toString())
302
                    + QString::fromLatin1("\"");
303
            }
304
            return yaml;
305
        }
306
        else {
307
            yaml += getValue().toString();
308
        }
309
    }
310
    yaml = QString::fromLatin1(" \"") + escapeString(yaml) + QString::fromLatin1("\"");
311
    return yaml;
312
}
313

314
//===
315

316
TYPESYSTEM_SOURCE(Materials::Material2DArray, Materials::MaterialValue)
317

318
Material2DArray::Material2DArray()
319
    : MaterialValue(Array2D, Array2D)
320
    , _columns(0)
321
{
322
    // Initialize separatelt to prevent recursion
323
    // setType(Array2D);
324
}
325

326
Material2DArray::Material2DArray(const Material2DArray& other)
327
    : MaterialValue(other)
328
    , _columns(other._columns)
329
{
330
    deepCopy(other);
331
}
332

333
Material2DArray& Material2DArray::operator=(const Material2DArray& other)
334
{
335
    if (this == &other) {
336
        return *this;
337
    }
338

339
    MaterialValue::operator=(other);
340
    _columns = other._columns;
341

342
    deepCopy(other);
343

344
    return *this;
345
}
346

347
void Material2DArray::deepCopy(const Material2DArray& other)
348
{
349
    // Deep copy
350
    for (auto& row : other._rows) {
351
        QList<QVariant> vv;
352
        for (auto& col : *row) {
353
            QVariant newVariant(col);
354
            vv.push_back(newVariant);
355
        }
356
        addRow(std::make_shared<QList<QVariant>>(vv));
357
    }
358
}
359

360
bool Material2DArray::isNull() const
361
{
362
    return rows() <= 0;
363
}
364

365
void Material2DArray::validateRow(int row) const
366
{
367
    if (row < 0 || row >= rows()) {
368
        throw InvalidIndex();
369
    }
370
}
371

372
void Material2DArray::validateColumn(int column) const
373
{
374
    if (column < 0 || column >= columns()) {
375
        throw InvalidIndex();
376
    }
377
}
378

379
std::shared_ptr<QList<QVariant>> Material2DArray::getRow(int row) const
380
{
381
    validateRow(row);
382

383
    try {
384
        return _rows.at(row);
385
    }
386
    catch (std::out_of_range const&) {
387
        throw InvalidIndex();
388
    }
389
}
390

391
std::shared_ptr<QList<QVariant>> Material2DArray::getRow(int row)
392
{
393
    validateRow(row);
394

395
    try {
396
        return _rows.at(row);
397
    }
398
    catch (std::out_of_range const&) {
399
        throw InvalidIndex();
400
    }
401
}
402

403
void Material2DArray::addRow(const std::shared_ptr<QList<QVariant>>& row)
404
{
405
    _rows.push_back(row);
406
}
407

408
void Material2DArray::insertRow(int index, const std::shared_ptr<QList<QVariant>>& row)
409
{
410
    _rows.insert(_rows.begin() + index, row);
411
}
412

413
void Material2DArray::deleteRow(int row)
414
{
415
    if (row >= static_cast<int>(_rows.size()) || row < 0) {
416
        throw InvalidIndex();
417
    }
418
    _rows.erase(_rows.begin() + row);
419
}
420

421
void Material2DArray::setValue(int row, int column, const QVariant& value)
422
{
423
    validateRow(row);
424
    validateColumn(column);
425

426
    auto val = getRow(row);
427
    try {
428
        val->replace(column, value);
429
    }
430
    catch (const std::out_of_range&) {
431
        throw InvalidIndex();
432
    }
433
}
434

435
QVariant Material2DArray::getValue(int row, int column) const
436
{
437
    validateColumn(column);
438

439
    auto val = getRow(row);
440
    try {
441
        return val->at(column);
442
    }
443
    catch (std::out_of_range const&) {
444
        throw InvalidIndex();
445
    }
446
}
447

448
void Material2DArray::dumpRow(const std::shared_ptr<QList<QVariant>>& row)
449
{
450
    Base::Console().Log("row: ");
451
    for (auto& column : *row) {
452
        Base::Console().Log("'%s' ", column.toString().toStdString().c_str());
453
    }
454
    Base::Console().Log("\n");
455
}
456

457
void Material2DArray::dump() const
458
{
459
    for (auto& row : _rows) {
460
        dumpRow(row);
461
    }
462
}
463

464
QString Material2DArray::getYAMLString() const
465
{
466
    if (isNull()) {
467
        return QString();
468
    }
469

470
    // Set the correct indentation. 9 chars in this case
471
    QString pad;
472
    pad.fill(QChar::fromLatin1(' '), 9);
473

474
    // Save the array contents
475
    QString yaml = QString::fromStdString("\n      - [");
476
    bool firstRow = true;
477
    for (auto& row : _rows) {
478
        if (!firstRow) {
479
            // Each row is on its own line, padded for correct indentation
480
            yaml += QString::fromStdString(",\n") + pad;
481
        }
482
        else {
483
            firstRow = false;
484
        }
485
        yaml += QString::fromStdString("[");
486

487
        bool first = true;
488
        for (auto& column : *row) {
489
            if (!first) {
490
                // TODO: Fix for arrays with too many columns to fit on a single line
491
                yaml += QString::fromStdString(", ");
492
            }
493
            else {
494
                first = false;
495
            }
496
            yaml += QString::fromStdString("\"");
497
            auto quantity = column.value<Base::Quantity>();
498
            yaml += quantity.getUserString();
499
            yaml += QString::fromStdString("\"");
500
        }
501

502
        yaml += QString::fromStdString("]");
503
    }
504
    yaml += QString::fromStdString("]");
505
    return yaml;
506
}
507

508
//===
509

510
TYPESYSTEM_SOURCE(Materials::Material3DArray, Materials::MaterialValue)
511

512
Material3DArray::Material3DArray()
513
    : MaterialValue(Array3D, Array3D)
514
    , _currentDepth(0)
515
    , _columns(0)
516
{
517
    // Initialize separatelt to prevent recursion
518
    // setType(Array3D);
519
}
520

521
bool Material3DArray::isNull() const
522
{
523
    return depth() <= 0;
524
}
525

526
void Material3DArray::validateDepth(int level) const
527
{
528
    if (level < 0 || level >= depth()) {
529
        throw InvalidIndex();
530
    }
531
}
532

533
void Material3DArray::validateColumn(int column) const
534
{
535
    if (column < 0 || column >= columns()) {
536
        throw InvalidIndex();
537
    }
538
}
539

540
void Material3DArray::validateRow(int level, int row) const
541
{
542
    validateDepth(level);
543

544
    if (row < 0 || row >= rows(level)) {
545
        throw InvalidIndex();
546
    }
547
}
548

549
const std::shared_ptr<QList<std::shared_ptr<QList<Base::Quantity>>>>&
550
Material3DArray::getTable(const Base::Quantity& depth) const
551
{
552
    for (auto& it : _rowMap) {
553
        if (std::get<0>(it) == depth) {
554
            return std::get<1>(it);
555
        }
556
    }
557

558
    throw InvalidIndex();
559
}
560

561
const std::shared_ptr<QList<std::shared_ptr<QList<Base::Quantity>>>>&
562
Material3DArray::getTable(int depthIndex) const
563
{
564
    try {
565
        return std::get<1>(_rowMap.at(depthIndex));
566
    }
567
    catch (std::out_of_range const&) {
568
        throw InvalidIndex();
569
    }
570
}
571

572
std::shared_ptr<QList<Base::Quantity>> Material3DArray::getRow(int depth, int row) const
573
{
574
    validateRow(depth, row);
575

576
    try {
577
        return getTable(depth)->at(row);
578
    }
579
    catch (std::out_of_range const&) {
580
        throw InvalidIndex();
581
    }
582
}
583

584
std::shared_ptr<QList<Base::Quantity>> Material3DArray::getRow(int row) const
585
{
586
    // Check if we can convert otherwise throw error
587
    return getRow(_currentDepth, row);
588
}
589

590
std::shared_ptr<QList<Base::Quantity>> Material3DArray::getRow(int depth, int row)
591
{
592
    validateRow(depth, row);
593

594
    try {
595
        return getTable(depth)->at(row);
596
    }
597
    catch (std::out_of_range const&) {
598
        throw InvalidIndex();
599
    }
600
}
601

602
std::shared_ptr<QList<Base::Quantity>> Material3DArray::getRow(int row)
603
{
604
    return getRow(_currentDepth, row);
605
}
606

607
void Material3DArray::addRow(int depth, const std::shared_ptr<QList<Base::Quantity>>& row)
608
{
609
    try {
610
        getTable(depth)->push_back(row);
611
    }
612
    catch (std::out_of_range const&) {
613
        throw InvalidIndex();
614
    }
615
}
616

617
void Material3DArray::addRow(const std::shared_ptr<QList<Base::Quantity>>& row)
618
{
619
    addRow(_currentDepth, row);
620
}
621

622
int Material3DArray::addDepth(int depth, const Base::Quantity& value)
623
{
624
    if (depth == this->depth()) {
625
        // Append to the end
626
        return addDepth(value);
627
    }
628
    if (depth > this->depth()) {
629
        throw InvalidIndex();
630
    }
631
    auto rowVector = std::make_shared<QList<std::shared_ptr<QList<Base::Quantity>>>>();
632
    auto entry = std::make_pair(value, rowVector);
633
    _rowMap.insert(_rowMap.begin() + depth, entry);
634

635
    return depth;
636
}
637

638
int Material3DArray::addDepth(const Base::Quantity& value)
639
{
640
    auto rowVector = std::make_shared<QList<std::shared_ptr<QList<Base::Quantity>>>>();
641
    auto entry = std::make_pair(value, rowVector);
642
    _rowMap.push_back(entry);
643

644
    return depth() - 1;
645
}
646

647
void Material3DArray::deleteDepth(int depth)
648
{
649
    deleteRows(depth);  // This may throw an InvalidIndex
650
    _rowMap.erase(_rowMap.begin() + depth);
651
}
652

653
void Material3DArray::insertRow(int depth,
654
                                int row,
655
                                const std::shared_ptr<QList<Base::Quantity>>& rowData)
656
{
657
    try {
658
        auto table = getTable(depth);
659
        table->insert(table->begin() + row, rowData);
660
    }
661
    catch (std::out_of_range const&) {
662
        throw InvalidIndex();
663
    }
664
}
665

666
void Material3DArray::insertRow(int row, const std::shared_ptr<QList<Base::Quantity>>& rowData)
667
{
668
    insertRow(_currentDepth, row, rowData);
669
}
670

671
void Material3DArray::deleteRow(int depth, int row)
672
{
673
    auto table = getTable(depth);
674
    if (row >= static_cast<int>(table->size()) || row < 0) {
675
        throw InvalidIndex();
676
    }
677
    table->erase(table->begin() + row);
678
}
679

680
void Material3DArray::deleteRow(int row)
681
{
682
    deleteRow(_currentDepth, row);
683
}
684

685
void Material3DArray::deleteRows(int depth)
686
{
687
    auto table = getTable(depth);
688
    table->clear();
689
}
690

691
void Material3DArray::deleteRows()
692
{
693
    deleteRows(_currentDepth);
694
}
695

696
int Material3DArray::rows(int depth) const
697
{
698
    if (depth < 0 || (depth == 0 && this->depth() == 0)) {
699
        return 0;
700
    }
701
    validateDepth(depth);
702

703
    return getTable(depth)->size();
704
}
705

706
void Material3DArray::setValue(int depth, int row, int column, const Base::Quantity& value)
707
{
708
    validateRow(depth, row);
709
    validateColumn(column);
710

711
    auto val = getRow(depth, row);
712
    try {
713
        val->replace(column, value);
714
    }
715
    catch (std::out_of_range const&) {
716
        throw InvalidIndex();
717
    }
718
}
719

720
void Material3DArray::setValue(int row, int column, const Base::Quantity& value)
721
{
722
    setValue(_currentDepth, row, column, value);
723
}
724

725
void Material3DArray::setDepthValue(int depth, const Base::Quantity& value)
726
{
727
    try {
728
        auto oldRows = getTable(depth);
729
        _rowMap.replace(depth, std::pair(value, oldRows));
730
    }
731
    catch (std::out_of_range const&) {
732
        throw InvalidIndex();
733
    }
734
}
735

736
void Material3DArray::setDepthValue(const Base::Quantity& value)
737
{
738
    setDepthValue(_currentDepth, value);
739
}
740

741

742
Base::Quantity Material3DArray::getValue(int depth, int row, int column) const
743
{
744
    // getRow validates depth and row. Do that first
745
    auto val = getRow(depth, row);
746
    validateColumn(column);
747

748
    try {
749
        return val->at(column);
750
    }
751
    catch (std::out_of_range const&) {
752
        throw InvalidIndex();
753
    }
754
}
755

756
Base::Quantity Material3DArray::getValue(int row, int column) const
757
{
758
    return getValue(_currentDepth, row, column);
759
}
760

761
Base::Quantity Material3DArray::getDepthValue(int depth) const
762
{
763
    validateDepth(depth);
764

765
    try {
766
        return std::get<0>(_rowMap.at(depth));
767
    }
768
    catch (std::out_of_range const&) {
769
        throw InvalidIndex();
770
    }
771
}
772

773
int Material3DArray::currentDepth() const
774
{
775
    return _currentDepth;
776
}
777

778
void Material3DArray::setCurrentDepth(int depth)
779
{
780
    validateDepth(depth);
781

782
    if (depth < 0 || _rowMap.empty()) {
783
        _currentDepth = 0;
784
    }
785
    else if (depth >= static_cast<int>(_rowMap.size())) {
786
        _currentDepth = _rowMap.size() - 1;
787
    }
788
    else {
789
        _currentDepth = depth;
790
    }
791
}
792

793
QString Material3DArray::getYAMLString() const
794
{
795
    if (isNull()) {
796
        return QString();
797
    }
798

799
    // Set the correct indentation. 7 chars + name length
800
    QString pad;
801
    pad.fill(QChar::fromLatin1(' '), 9);
802

803
    // Save the array contents
804
    QString yaml = QString::fromStdString("\n      - [");
805
    for (int depth = 0; depth < this->depth(); depth++) {
806
        if (depth > 0) {
807
            // Each row is on its own line, padded for correct indentation
808
            yaml += QString::fromStdString(",\n") + pad;
809
        }
810

811
        yaml += QString::fromStdString("\"");
812
        auto value = getDepthValue(depth).getUserString();
813
        yaml += value;
814
        yaml += QString::fromStdString("\": [");
815

816
        QString pad2;
817
        pad2.fill(QChar::fromLatin1(' '), 14 + value.length());
818

819
        bool firstRow = true;
820
        auto rows = getTable(depth);
821
        for (auto& row : *rows) {
822
            if (!firstRow) {
823
                // Each row is on its own line, padded for correct indentation
824
                yaml += QString::fromStdString(",\n") + pad2;
825
            }
826
            else {
827
                firstRow = false;
828
            }
829
            yaml += QString::fromStdString("[");
830

831
            bool first = true;
832
            for (auto& column : *row) {
833
                if (!first) {
834
                    // TODO: Fix for arrays with too many columns to fit on a single line
835
                    yaml += QString::fromStdString(", ");
836
                }
837
                else {
838
                    first = false;
839
                }
840
                yaml += QString::fromStdString("\"");
841
                // Base::Quantity quantity = column.value<Base::Quantity>();
842
                yaml += column.getUserString();
843
                yaml += QString::fromStdString("\"");
844
            }
845

846
            yaml += QString::fromStdString("]");
847
        }
848
        yaml += QString::fromStdString("]");
849
    }
850
    yaml += QString::fromStdString("]");
851
    return yaml;
852
}
853

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

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

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

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