Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/GNEAttributeProperties.cpp
193674 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GNEAttributeProperties.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Jan 2020
17
///
18
// Abstract Base class for tag properties used in GNEAttributeCarrier
19
/****************************************************************************/
20
21
#include <netedit/elements/GNEAttributeCarrier.h>
22
23
#include "GNETagProperties.h"
24
#include "GNEAttributeProperties.h"
25
26
// ===========================================================================
27
// method definitions
28
// ===========================================================================
29
30
GNEAttributeProperties::GNEAttributeProperties(GNETagProperties* tagProperties, const SumoXMLAttr attribute, const Property attributeProperty,
31
const Edit editProperty, const std::string& definition) :
32
myTagPropertyParent(tagProperties),
33
myAttribute(attribute),
34
myAttrStr(toString(attribute)),
35
myAttributeProperty(attributeProperty),
36
myEditProperty(editProperty),
37
myDefinition(definition) {
38
// check build conditions (only in debug mode)
39
checkBuildConstraints();
40
// add attribute in tag properties vector
41
tagProperties->myAttributeProperties.push_back(this);
42
}
43
44
45
GNEAttributeProperties::GNEAttributeProperties(GNETagProperties* tagProperties, const SumoXMLAttr attribute, const Property attributeProperty,
46
const Edit editProperty, const std::string& definition, const std::string& defaultValue) :
47
myTagPropertyParent(tagProperties),
48
myAttribute(attribute),
49
myAttrStr(toString(attribute)),
50
myAttributeProperty(attributeProperty),
51
myEditProperty(editProperty),
52
myDefinition(definition),
53
myDefaultStringValue(defaultValue) {
54
// check build conditions (only in debug mode)
55
checkBuildConstraints();
56
// parse default values
57
parseDefaultValues(defaultValue, true);
58
// add attribute in tag properties vector
59
tagProperties->myAttributeProperties.push_back(this);
60
}
61
62
63
GNEAttributeProperties::GNEAttributeProperties(GNETagProperties* tagProperties, const SumoXMLAttr attribute, const Property attributeProperty,
64
const Edit editProperty, const std::string& definition, const std::string& defaultValueMask, const std::string& defaultValue) :
65
myTagPropertyParent(tagProperties),
66
myAttribute(attribute),
67
myAttrStr(toString(attribute)),
68
myAttributeProperty(attributeProperty),
69
myEditProperty(editProperty),
70
myDefinition(definition),
71
myDefaultStringValue(defaultValueMask) {
72
// check build conditions (only in debug mode)
73
checkBuildConstraints();
74
// parse default values
75
parseDefaultValues(defaultValue, false);
76
// add attribute in tag properties vector
77
tagProperties->myAttributeProperties.push_back(this);
78
}
79
80
81
GNEAttributeProperties::GNEAttributeProperties(GNETagProperties* tagProperties, const SumoXMLAttr attribute, const std::string& definition) :
82
myTagPropertyParent(tagProperties),
83
myAttribute(attribute),
84
myAttrStr(toString(attribute)),
85
myDefinition(definition) {
86
// check build conditions (only in debug mode)
87
checkBuildConstraints();
88
// add attribute in tag properties vector
89
tagProperties->myAttributeProperties.push_back(this);
90
}
91
92
93
GNEAttributeProperties::~GNEAttributeProperties() {}
94
95
96
void
97
GNEAttributeProperties::checkAttributeIntegrity() const {
98
// check integrity only in debug mode
99
#ifdef DEBUG
100
// check that there are properties
101
if (myAttributeProperty & Property::NO_PROPERTY) {
102
throw FormatException("Attr properties cannot be empty");
103
}
104
// check that positive attributes correspond only to a int, floats or SUMOTimes
105
if (isPositive() && !isNumerical()) {
106
throw FormatException("Only int, floats or SUMOTimes can be positive");
107
}
108
// check that secuential attributes correspond to a list
109
if (isSecuential() && !isList()) {
110
throw FormatException("Secuential property only is compatible with list properties");
111
}
112
// check that synonym attribute isn't nothing
113
if (hasAttrSynonym() && (myAttrSynonym == SUMO_ATTR_NOTHING)) {
114
throw FormatException("synonym attribute cannot be nothing");
115
}
116
// check that synonym attribute isn't nothing
117
if ((isFileOpen() || isFileSave()) && myFilenameExtensions.empty()) {
118
throw FormatException("Files requieres at least one extension");
119
}
120
// check that attribute sortables appears always in dialog
121
if (isSortable() && !isDialogEditor()) {
122
throw FormatException("Sortable attributes must be a dialog editor attribute");
123
}
124
// check that ranges are valid
125
if (hasAttrRange()) {
126
if (myMinimumRange == myMaximumRange) {
127
throw FormatException("empty range");
128
} else if ((myMinimumRange == 0) && (myMaximumRange == 0)) {
129
throw FormatException("non-defined range");
130
} else if ((myMaximumRange - myMinimumRange) <= 0) {
131
throw FormatException("invalid range");
132
}
133
}
134
// check that unique attributes aren't copyables
135
if (isUnique() && isCopyable()) {
136
throw FormatException("Unique attributes aren't copyables");
137
}
138
#endif // DEBUG
139
}
140
141
142
void
143
GNEAttributeProperties::setDiscreteValues(const std::vector<std::string>& discreteValues) {
144
if (isDiscrete()) {
145
myDiscreteValues = discreteValues;
146
} else {
147
throw FormatException("AttributeProperty doesn't support discrete values");
148
}
149
}
150
151
152
void
153
GNEAttributeProperties::setFilenameExtensions(const std::vector<std::string>& extensions) {
154
if (isFileOpen() || isFileSave()) {
155
myFilenameExtensions = extensions;
156
} else {
157
throw FormatException("AttributeProperty doesn't support extensions values");
158
}
159
}
160
161
162
void
163
GNEAttributeProperties::setDefaultActivated(const bool value) {
164
if (isActivatable()) {
165
myDefaultActivated = value;
166
} else {
167
throw FormatException("AttributeProperty doesn't support default activated");
168
}
169
}
170
171
172
void
173
GNEAttributeProperties::setSynonym(const SumoXMLAttr synonym) {
174
if (hasAttrSynonym()) {
175
myAttrSynonym = synonym;
176
} else {
177
throw FormatException("AttributeProperty doesn't support synonyms");
178
}
179
}
180
181
182
void
183
GNEAttributeProperties::setRange(const double minimum, const double maximum) {
184
if (hasAttrRange()) {
185
myMinimumRange = minimum;
186
myMaximumRange = maximum;
187
// check that given range is valid
188
if (myMinimumRange == myMaximumRange) {
189
throw FormatException("empty range");
190
} else if ((myMinimumRange == 0) && (myMaximumRange == 0)) {
191
throw FormatException("non-defined range");
192
} else if ((myMaximumRange - myMinimumRange) <= 0) {
193
throw FormatException("invalid range");
194
}
195
} else {
196
throw FormatException("AttributeProperty doesn't support ranges");
197
}
198
}
199
200
201
void
202
GNEAttributeProperties::setTagPropertyParent(GNETagProperties* tagPropertyParent) {
203
myTagPropertyParent = tagPropertyParent;
204
}
205
206
207
void
208
GNEAttributeProperties::setAlternativeName(const std::string& newAttrName) {
209
myAttrStr = newAttrName;
210
}
211
212
213
SumoXMLAttr
214
GNEAttributeProperties::getAttr() const {
215
return myAttribute;
216
}
217
218
219
const std::string&
220
GNEAttributeProperties::getAttrStr() const {
221
return myAttrStr;
222
}
223
224
225
const GNETagProperties*
226
GNEAttributeProperties::getTagPropertyParent() const {
227
return myTagPropertyParent;
228
}
229
230
231
int
232
GNEAttributeProperties::getPositionListed() const {
233
for (auto it = myTagPropertyParent->getAttributeProperties().begin(); it != myTagPropertyParent->getAttributeProperties().end(); it++) {
234
if ((*it)->getAttr() == myAttribute) {
235
return (int)(it - myTagPropertyParent->getAttributeProperties().begin());
236
}
237
}
238
throw ProcessError("Attribute wasn't found in myTagPropertyParent");
239
}
240
241
242
const std::string&
243
GNEAttributeProperties::getDefinition() const {
244
return myDefinition;
245
}
246
247
248
const std::string&
249
GNEAttributeProperties::getDefaultStringValue() const {
250
return myDefaultStringValue;
251
}
252
253
254
int
255
GNEAttributeProperties::getDefaultIntValue() const {
256
return myDefaultIntValue;
257
}
258
259
260
double
261
GNEAttributeProperties::getDefaultDoubleValue() const {
262
return myDefaultDoubleValue;
263
}
264
265
266
SUMOTime
267
GNEAttributeProperties::getDefaultTimeValue() const {
268
return myDefaultTimeValue;
269
}
270
271
272
bool
273
GNEAttributeProperties::getDefaultBoolValue() const {
274
return myDefaultBoolValue;
275
}
276
277
278
const RGBColor&
279
GNEAttributeProperties::getDefaultColorValue() const {
280
return myDefaultColorValue;
281
}
282
283
284
const Position&
285
GNEAttributeProperties::getDefaultPositionValue() const {
286
return myDefaultPositionValue;
287
}
288
289
290
bool
291
GNEAttributeProperties::getDefaultActivated() const {
292
return myDefaultActivated;
293
}
294
295
296
std::string
297
GNEAttributeProperties::getCategory() const {
298
if (isExtendedEditor()) {
299
return TL("Extended");
300
} else if (isGeoEditor()) {
301
return TL("GEO");
302
} else if (isFlowEditor()) {
303
return TL("Flow");
304
} else if (isNeteditEditor()) {
305
return TL("Netedit");
306
} else {
307
return TL("Internal");
308
}
309
}
310
311
312
std::string
313
GNEAttributeProperties::getDescription() const {
314
std::string pre;
315
std::string type;
316
std::string plural;
317
std::string last;
318
// pre type
319
if (isList()) {
320
pre += TL("list of ");
321
if (isVClass()) {
322
plural = "es";
323
} else {
324
plural = "s";
325
}
326
}
327
if (isPositive()) {
328
pre += TL("non-negative ");
329
}
330
if (isDiscrete()) {
331
pre += TL("discrete ");
332
}
333
if (isUnique()) {
334
pre += TL("unique ");
335
}
336
// type
337
if (isInt()) {
338
type = TL("integer");
339
}
340
if (isFloat()) {
341
type = TL("float");
342
}
343
if (isSUMOTime()) {
344
type = TL("SUMOTime");
345
}
346
if (isBool()) {
347
type = TL("boolean");
348
}
349
if (isString()) {
350
type = TL("string");
351
}
352
if (isPosition()) {
353
type = TL("position");
354
}
355
if (isColor()) {
356
type = TL("color");
357
}
358
if (isVClass()) {
359
type = TL("vClass");
360
}
361
if (isFileOpen()) {
362
type = TL("filename");
363
last = TL("(Existent)");
364
}
365
if (isFileSave()) {
366
type = TL("filename");
367
}
368
if (isProbability()) {
369
type = TL("probability");
370
last = TL("[0, 1]");
371
}
372
if (isAngle()) {
373
type = TL("angle");
374
last = TL("[0, 360]");
375
}
376
return pre + type + plural + last;
377
}
378
379
380
const std::vector<std::string>&
381
GNEAttributeProperties::getDiscreteValues() const {
382
return myDiscreteValues;
383
}
384
385
386
const std::vector<std::string>&
387
GNEAttributeProperties::getFilenameExtensions() const {
388
return myFilenameExtensions;
389
}
390
391
392
SumoXMLAttr
393
GNEAttributeProperties::getAttrSynonym() const {
394
if (hasAttrSynonym()) {
395
return myAttrSynonym;
396
} else {
397
throw ProcessError("Attr doesn't support synonym");
398
}
399
}
400
401
402
double
403
GNEAttributeProperties::getMinimumRange() const {
404
if (hasAttrRange()) {
405
return myMinimumRange;
406
} else {
407
throw ProcessError("Attr doesn't support range");
408
}
409
}
410
411
412
double
413
GNEAttributeProperties::getMaximumRange() const {
414
if (hasAttrRange()) {
415
return myMaximumRange;
416
} else {
417
throw ProcessError("Attr doesn't support range");
418
}
419
}
420
421
422
bool
423
GNEAttributeProperties::hasDefaultValue() const {
424
return myAttributeProperty & Property::DEFAULTVALUE;
425
}
426
427
428
bool
429
GNEAttributeProperties::hasAttrSynonym() const {
430
return myAttributeProperty & Property::SYNONYM;
431
}
432
433
bool
434
GNEAttributeProperties::hasAttrRange() const {
435
return myAttributeProperty & Property::RANGE;
436
}
437
438
439
bool
440
GNEAttributeProperties::isInt() const {
441
return myAttributeProperty & Property::INT;
442
}
443
444
445
bool
446
GNEAttributeProperties::isFloat() const {
447
return myAttributeProperty & Property::FLOAT;
448
}
449
450
451
bool
452
GNEAttributeProperties::isSUMOTime() const {
453
return myAttributeProperty & Property::SUMOTIME;
454
}
455
456
457
bool
458
GNEAttributeProperties::isBool() const {
459
return myAttributeProperty & Property::BOOL;
460
}
461
462
463
bool
464
GNEAttributeProperties::isString() const {
465
return myAttributeProperty & Property::STRING;
466
}
467
468
469
bool
470
GNEAttributeProperties::isPosition() const {
471
return myAttributeProperty & Property::POSITION;
472
}
473
474
475
bool
476
GNEAttributeProperties::isProbability() const {
477
return myAttributeProperty & Property::PROBABILITY;
478
}
479
480
481
bool
482
GNEAttributeProperties::isAngle() const {
483
return myAttributeProperty & Property::ANGLE;
484
}
485
486
487
bool
488
GNEAttributeProperties::isNumerical() const {
489
return isInt() || isFloat() || isSUMOTime();
490
}
491
492
493
bool
494
GNEAttributeProperties::isPositive() const {
495
return myAttributeProperty & Property::POSITIVE;
496
}
497
498
499
bool
500
GNEAttributeProperties::isColor() const {
501
return myAttributeProperty & Property::COLOR;
502
}
503
504
505
bool
506
GNEAttributeProperties::isVType() const {
507
return myAttributeProperty & Property::VTYPE;
508
}
509
510
511
bool
512
GNEAttributeProperties::isFileOpen() const {
513
return myAttributeProperty & Property::FILEOPEN;
514
}
515
516
517
bool
518
GNEAttributeProperties::isFileSave() const {
519
return myAttributeProperty & Property::FILESAVE;
520
}
521
522
523
bool
524
GNEAttributeProperties::isVClass() const {
525
return myAttributeProperty & Property::VCLASS;
526
}
527
528
529
bool
530
GNEAttributeProperties::isSVCPermission() const {
531
return isList() && isVClass();
532
}
533
534
535
bool
536
GNEAttributeProperties::isList() const {
537
return myAttributeProperty & Property::LIST;
538
}
539
540
541
bool
542
GNEAttributeProperties::isSecuential() const {
543
return myAttributeProperty & Property::SECUENCIAL;
544
}
545
546
547
bool
548
GNEAttributeProperties::isUnique() const {
549
return myAttributeProperty & Property::UNIQUE;
550
}
551
552
553
bool
554
GNEAttributeProperties::isDiscrete() const {
555
return myAttributeProperty & Property::DISCRETE;
556
}
557
558
559
bool
560
GNEAttributeProperties::requireUpdateGeometry() const {
561
return myAttributeProperty & Property::UPDATEGEOMETRY;
562
}
563
564
565
bool
566
GNEAttributeProperties::isActivatable() const {
567
return myAttributeProperty & Property::ACTIVATABLE;
568
}
569
570
571
bool
572
GNEAttributeProperties::isFlow() const {
573
return myAttributeProperty & Property::FLOW;
574
}
575
576
577
bool
578
GNEAttributeProperties::isCopyable() const {
579
return myAttributeProperty & Property::COPYABLE;
580
}
581
582
583
bool
584
GNEAttributeProperties::isAlwaysEnabled() const {
585
return myAttributeProperty & Property::ALWAYSENABLED;
586
}
587
588
bool
589
GNEAttributeProperties::isSortable() const {
590
return myAttributeProperty & Property::SORTABLE;
591
}
592
593
594
bool
595
GNEAttributeProperties::isBasicEditor() const {
596
return !isExtendedEditor() && !isGeoEditor() && !isFlowEditor() && !isNeteditEditor();
597
}
598
599
600
bool
601
GNEAttributeProperties::isExtendedEditor() const {
602
return myEditProperty & Edit::EXTENDEDEDITOR;
603
}
604
605
606
bool
607
GNEAttributeProperties::isGeoEditor() const {
608
return myEditProperty & Edit::GEOEDITOR;
609
}
610
611
612
bool
613
GNEAttributeProperties::isFlowEditor() const {
614
return myEditProperty & Edit::FLOWEDITOR;
615
}
616
617
618
bool
619
GNEAttributeProperties::isNeteditEditor() const {
620
return myEditProperty & Edit::NETEDITEDITOR;
621
}
622
623
624
bool
625
GNEAttributeProperties::isCreateMode() const {
626
return myEditProperty & Edit::CREATEMODE;
627
}
628
629
630
bool
631
GNEAttributeProperties::isEditMode() const {
632
return myEditProperty & Edit::EDITMODE;
633
}
634
635
636
bool
637
GNEAttributeProperties::isDialogEditor() const {
638
return myEditProperty & Edit::DIALOGEDITOR;
639
}
640
641
642
void
643
GNEAttributeProperties::checkBuildConstraints() const {
644
// check integrity only in debug mode
645
#ifdef DEBUG
646
// empty definition aren't valid
647
if (myDefinition.empty()) {
648
throw FormatException("Missing definition for AttributeProperty '" + toString(myAttribute) + "'");
649
}
650
// if default value isn't empty, but attribute doesn't support default values, throw exception.
651
if (!myDefaultStringValue.empty() && !(myAttributeProperty & Property::DEFAULTVALUE)) {
652
throw FormatException("AttributeProperty for '" + toString(myAttribute) + "' doesn't support default values");
653
}
654
// Attributes cannot be flowdefinition and enabilitablet at the same time
655
if ((myAttributeProperty & Property::FLOW) && (myAttributeProperty & Property::ACTIVATABLE)) {
656
throw FormatException("Attribute '" + toString(myAttribute) + "' cannot be flow definition and activatable at the same time");
657
}
658
// Check that attribute wasn't already inserted
659
for (const auto& attrProperty : myTagPropertyParent->myAttributeProperties) {
660
if (attrProperty->getAttr() == myAttribute) {
661
throw ProcessError(TLF("Attribute '%' already inserted", toString(myAttribute)));
662
}
663
}
664
#endif // DEBUG
665
}
666
667
668
void
669
GNEAttributeProperties::parseDefaultValues(const std::string& defaultValue, const bool overWritteDefaultString) {
670
// in every case parse default value back (to avoid problems during comparations)
671
if (isInt()) {
672
myDefaultIntValue = GNEAttributeCarrier::parse<int>(defaultValue);
673
if (overWritteDefaultString) {
674
myDefaultStringValue = toString(myDefaultIntValue);
675
}
676
} else if (isFloat()) {
677
myDefaultDoubleValue = GNEAttributeCarrier::parse<double>(defaultValue);
678
if (overWritteDefaultString) {
679
myDefaultStringValue = toString(myDefaultDoubleValue);
680
}
681
} else if (isSUMOTime()) {
682
myDefaultTimeValue = GNEAttributeCarrier::parse<SUMOTime>(defaultValue);
683
if (overWritteDefaultString) {
684
myDefaultStringValue = time2string(myDefaultTimeValue);
685
}
686
} else if (isBool()) {
687
myDefaultBoolValue = GNEAttributeCarrier::parse<bool>(defaultValue);
688
if (overWritteDefaultString) {
689
myDefaultStringValue = myDefaultBoolValue ? GNEAttributeCarrier::TRUE_STR : GNEAttributeCarrier::FALSE_STR;
690
}
691
} else if (isColor()) {
692
myDefaultColorValue = GNEAttributeCarrier::parse<RGBColor>(defaultValue);
693
if (overWritteDefaultString) {
694
myDefaultStringValue = toString(myDefaultColorValue);
695
}
696
} else if (isPosition()) {
697
myDefaultPositionValue = GNEAttributeCarrier::parse<Position>(defaultValue);
698
if (overWritteDefaultString) {
699
myDefaultStringValue = toString(myDefaultPositionValue);
700
}
701
}
702
}
703
704
/****************************************************************************/
705
706