Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/GNEAttributeProperties.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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 ranges are valid
121
if (hasAttrRange()) {
122
if (myMinimumRange == myMaximumRange) {
123
throw FormatException("empty range");
124
} else if ((myMinimumRange == 0) && (myMaximumRange == 0)) {
125
throw FormatException("non-defined range");
126
} else if ((myMaximumRange - myMinimumRange) <= 0) {
127
throw FormatException("invalid range");
128
}
129
}
130
// check that unique attributes aren't copyables
131
if (isUnique() && isCopyable()) {
132
throw FormatException("Unique attributes aren't copyables");
133
}
134
#endif // DEBUG
135
}
136
137
138
void
139
GNEAttributeProperties::setDiscreteValues(const std::vector<std::string>& discreteValues) {
140
if (isDiscrete()) {
141
myDiscreteValues = discreteValues;
142
} else {
143
throw FormatException("AttributeProperty doesn't support discrete values");
144
}
145
}
146
147
148
void
149
GNEAttributeProperties::setFilenameExtensions(const std::vector<std::string>& extensions) {
150
if (isFileOpen() || isFileSave()) {
151
myFilenameExtensions = extensions;
152
} else {
153
throw FormatException("AttributeProperty doesn't support extensions values");
154
}
155
}
156
157
158
void
159
GNEAttributeProperties::setDefaultActivated(const bool value) {
160
if (isActivatable()) {
161
myDefaultActivated = value;
162
} else {
163
throw FormatException("AttributeProperty doesn't support default activated");
164
}
165
}
166
167
168
void
169
GNEAttributeProperties::setSynonym(const SumoXMLAttr synonym) {
170
if (hasAttrSynonym()) {
171
myAttrSynonym = synonym;
172
} else {
173
throw FormatException("AttributeProperty doesn't support synonyms");
174
}
175
}
176
177
178
void
179
GNEAttributeProperties::setRange(const double minimum, const double maximum) {
180
if (hasAttrRange()) {
181
myMinimumRange = minimum;
182
myMaximumRange = maximum;
183
// check that given range is valid
184
if (myMinimumRange == myMaximumRange) {
185
throw FormatException("empty range");
186
} else if ((myMinimumRange == 0) && (myMaximumRange == 0)) {
187
throw FormatException("non-defined range");
188
} else if ((myMaximumRange - myMinimumRange) <= 0) {
189
throw FormatException("invalid range");
190
}
191
} else {
192
throw FormatException("AttributeProperty doesn't support ranges");
193
}
194
}
195
196
197
void
198
GNEAttributeProperties::setTagPropertyParent(GNETagProperties* tagPropertyParent) {
199
myTagPropertyParent = tagPropertyParent;
200
}
201
202
203
void
204
GNEAttributeProperties::setAlternativeName(const std::string& newAttrName) {
205
myAttrStr = newAttrName;
206
}
207
208
209
SumoXMLAttr
210
GNEAttributeProperties::getAttr() const {
211
return myAttribute;
212
}
213
214
215
const std::string&
216
GNEAttributeProperties::getAttrStr() const {
217
return myAttrStr;
218
}
219
220
221
const GNETagProperties*
222
GNEAttributeProperties::getTagPropertyParent() const {
223
return myTagPropertyParent;
224
}
225
226
227
int
228
GNEAttributeProperties::getPositionListed() const {
229
for (auto it = myTagPropertyParent->getAttributeProperties().begin(); it != myTagPropertyParent->getAttributeProperties().end(); it++) {
230
if ((*it)->getAttr() == myAttribute) {
231
return (int)(it - myTagPropertyParent->getAttributeProperties().begin());
232
}
233
}
234
throw ProcessError("Attribute wasn't found in myTagPropertyParent");
235
}
236
237
238
const std::string&
239
GNEAttributeProperties::getDefinition() const {
240
return myDefinition;
241
}
242
243
244
const std::string&
245
GNEAttributeProperties::getDefaultStringValue() const {
246
return myDefaultStringValue;
247
}
248
249
250
int
251
GNEAttributeProperties::getDefaultIntValue() const {
252
return myDefaultIntValue;
253
}
254
255
256
double
257
GNEAttributeProperties::getDefaultDoubleValue() const {
258
return myDefaultDoubleValue;
259
}
260
261
262
SUMOTime
263
GNEAttributeProperties::getDefaultTimeValue() const {
264
return myDefaultTimeValue;
265
}
266
267
268
bool
269
GNEAttributeProperties::getDefaultBoolValue() const {
270
return myDefaultBoolValue;
271
}
272
273
274
const RGBColor&
275
GNEAttributeProperties::getDefaultColorValue() const {
276
return myDefaultColorValue;
277
}
278
279
280
const Position&
281
GNEAttributeProperties::getDefaultPositionValue() const {
282
return myDefaultPositionValue;
283
}
284
285
286
bool
287
GNEAttributeProperties::getDefaultActivated() const {
288
return myDefaultActivated;
289
}
290
291
292
std::string
293
GNEAttributeProperties::getCategory() const {
294
if (isExtendedEditor()) {
295
return TL("Extended");
296
} else if (isGeoEditor()) {
297
return TL("GEO");
298
} else if (isFlowEditor()) {
299
return TL("Flow");
300
} else if (isNeteditEditor()) {
301
return TL("Netedit");
302
} else {
303
return TL("Internal");
304
}
305
}
306
307
308
std::string
309
GNEAttributeProperties::getDescription() const {
310
std::string pre;
311
std::string type;
312
std::string plural;
313
std::string last;
314
// pre type
315
if (isList()) {
316
pre += TL("list of ");
317
if (isVClass()) {
318
plural = "es";
319
} else {
320
plural = "s";
321
}
322
}
323
if (isPositive()) {
324
pre += TL("non-negative ");
325
}
326
if (isDiscrete()) {
327
pre += TL("discrete ");
328
}
329
if (isUnique()) {
330
pre += TL("unique ");
331
}
332
// type
333
if (isInt()) {
334
type = TL("integer");
335
}
336
if (isFloat()) {
337
type = TL("float");
338
}
339
if (isSUMOTime()) {
340
type = TL("SUMOTime");
341
}
342
if (isBool()) {
343
type = TL("boolean");
344
}
345
if (isString()) {
346
type = TL("string");
347
}
348
if (isPosition()) {
349
type = TL("position");
350
}
351
if (isColor()) {
352
type = TL("color");
353
}
354
if (isVClass()) {
355
type = TL("vClass");
356
}
357
if (isFileOpen()) {
358
type = TL("filename");
359
last = TL("(Existent)");
360
}
361
if (isFileSave()) {
362
type = TL("filename");
363
}
364
if (isProbability()) {
365
type = TL("probability");
366
last = TL("[0, 1]");
367
}
368
if (isAngle()) {
369
type = TL("angle");
370
last = TL("[0, 360]");
371
}
372
return pre + type + plural + last;
373
}
374
375
376
const std::vector<std::string>&
377
GNEAttributeProperties::getDiscreteValues() const {
378
return myDiscreteValues;
379
}
380
381
382
const std::vector<std::string>&
383
GNEAttributeProperties::getFilenameExtensions() const {
384
return myFilenameExtensions;
385
}
386
387
388
SumoXMLAttr
389
GNEAttributeProperties::getAttrSynonym() const {
390
if (hasAttrSynonym()) {
391
return myAttrSynonym;
392
} else {
393
throw ProcessError("Attr doesn't support synonym");
394
}
395
}
396
397
398
double
399
GNEAttributeProperties::getMinimumRange() const {
400
if (hasAttrRange()) {
401
return myMinimumRange;
402
} else {
403
throw ProcessError("Attr doesn't support range");
404
}
405
}
406
407
408
double
409
GNEAttributeProperties::getMaximumRange() const {
410
if (hasAttrRange()) {
411
return myMaximumRange;
412
} else {
413
throw ProcessError("Attr doesn't support range");
414
}
415
}
416
417
418
bool
419
GNEAttributeProperties::hasDefaultValue() const {
420
return myAttributeProperty & Property::DEFAULTVALUE;
421
}
422
423
424
bool
425
GNEAttributeProperties::hasAttrSynonym() const {
426
return myAttributeProperty & Property::SYNONYM;
427
}
428
429
bool
430
GNEAttributeProperties::hasAttrRange() const {
431
return myAttributeProperty & Property::RANGE;
432
}
433
434
435
bool
436
GNEAttributeProperties::isInt() const {
437
return myAttributeProperty & Property::INT;
438
}
439
440
441
bool
442
GNEAttributeProperties::isFloat() const {
443
return myAttributeProperty & Property::FLOAT;
444
}
445
446
447
bool
448
GNEAttributeProperties::isSUMOTime() const {
449
return myAttributeProperty & Property::SUMOTIME;
450
}
451
452
453
bool
454
GNEAttributeProperties::isBool() const {
455
return myAttributeProperty & Property::BOOL;
456
}
457
458
459
bool
460
GNEAttributeProperties::isString() const {
461
return myAttributeProperty & Property::STRING;
462
}
463
464
465
bool
466
GNEAttributeProperties::isPosition() const {
467
return myAttributeProperty & Property::POSITION;
468
}
469
470
471
bool
472
GNEAttributeProperties::isProbability() const {
473
return myAttributeProperty & Property::PROBABILITY;
474
}
475
476
477
bool
478
GNEAttributeProperties::isAngle() const {
479
return myAttributeProperty & Property::ANGLE;
480
}
481
482
483
bool
484
GNEAttributeProperties::isNumerical() const {
485
return isInt() || isFloat() || isSUMOTime();
486
}
487
488
489
bool
490
GNEAttributeProperties::isPositive() const {
491
return myAttributeProperty & Property::POSITIVE;
492
}
493
494
495
bool
496
GNEAttributeProperties::isColor() const {
497
return myAttributeProperty & Property::COLOR;
498
}
499
500
501
bool
502
GNEAttributeProperties::isVType() const {
503
return myAttributeProperty & Property::VTYPE;
504
}
505
506
507
bool
508
GNEAttributeProperties::isFileOpen() const {
509
return myAttributeProperty & Property::FILEOPEN;
510
}
511
512
513
bool
514
GNEAttributeProperties::isFileSave() const {
515
return myAttributeProperty & Property::FILESAVE;
516
}
517
518
519
bool
520
GNEAttributeProperties::isVClass() const {
521
return myAttributeProperty & Property::VCLASS;
522
}
523
524
525
bool
526
GNEAttributeProperties::isSVCPermission() const {
527
return isList() && isVClass();
528
}
529
530
531
bool
532
GNEAttributeProperties::isList() const {
533
return myAttributeProperty & Property::LIST;
534
}
535
536
537
bool
538
GNEAttributeProperties::isSecuential() const {
539
return myAttributeProperty & Property::SECUENCIAL;
540
}
541
542
543
bool
544
GNEAttributeProperties::isUnique() const {
545
return myAttributeProperty & Property::UNIQUE;
546
}
547
548
549
bool
550
GNEAttributeProperties::isDiscrete() const {
551
return myAttributeProperty & Property::DISCRETE;
552
}
553
554
555
bool
556
GNEAttributeProperties::requireUpdateGeometry() const {
557
return myAttributeProperty & Property::UPDATEGEOMETRY;
558
}
559
560
561
bool
562
GNEAttributeProperties::isActivatable() const {
563
return myAttributeProperty & Property::ACTIVATABLE;
564
}
565
566
567
bool
568
GNEAttributeProperties::isFlow() const {
569
return myAttributeProperty & Property::FLOW;
570
}
571
572
573
bool
574
GNEAttributeProperties::isCopyable() const {
575
return myAttributeProperty & Property::COPYABLE;
576
}
577
578
579
bool
580
GNEAttributeProperties::isAlwaysEnabled() const {
581
return myAttributeProperty & Property::ALWAYSENABLED;
582
}
583
584
585
bool
586
GNEAttributeProperties::isBasicEditor() const {
587
return !isExtendedEditor() && !isGeoEditor() && !isFlowEditor() && !isNeteditEditor();
588
}
589
590
591
bool
592
GNEAttributeProperties::isExtendedEditor() const {
593
return myEditProperty & Edit::EXTENDEDEDITOR;
594
}
595
596
597
bool
598
GNEAttributeProperties::isGeoEditor() const {
599
return myEditProperty & Edit::GEOEDITOR;
600
}
601
602
603
bool
604
GNEAttributeProperties::isFlowEditor() const {
605
return myEditProperty & Edit::FLOWEDITOR;
606
}
607
608
609
bool
610
GNEAttributeProperties::isNeteditEditor() const {
611
return myEditProperty & Edit::NETEDITEDITOR;
612
}
613
614
615
bool
616
GNEAttributeProperties::isCreateMode() const {
617
return myEditProperty & Edit::CREATEMODE;
618
}
619
620
621
bool
622
GNEAttributeProperties::isEditMode() const {
623
return myEditProperty & Edit::EDITMODE;
624
}
625
626
627
bool
628
GNEAttributeProperties::isDialogEditor() const {
629
return myEditProperty & Edit::DIALOGEDITOR;
630
}
631
632
633
void
634
GNEAttributeProperties::checkBuildConstraints() const {
635
// check integrity only in debug mode
636
#ifdef DEBUG
637
// empty definition aren't valid
638
if (myDefinition.empty()) {
639
throw FormatException("Missing definition for AttributeProperty '" + toString(myAttribute) + "'");
640
}
641
// if default value isn't empty, but attribute doesn't support default values, throw exception.
642
if (!myDefaultStringValue.empty() && !(myAttributeProperty & Property::DEFAULTVALUE)) {
643
throw FormatException("AttributeProperty for '" + toString(myAttribute) + "' doesn't support default values");
644
}
645
// Attributes cannot be flowdefinition and enabilitablet at the same time
646
if ((myAttributeProperty & Property::FLOW) && (myAttributeProperty & Property::ACTIVATABLE)) {
647
throw FormatException("Attribute '" + toString(myAttribute) + "' cannot be flow definition and activatable at the same time");
648
}
649
// Check that attribute wasn't already inserted
650
for (const auto& attrProperty : myTagPropertyParent->myAttributeProperties) {
651
if (attrProperty->getAttr() == myAttribute) {
652
throw ProcessError(TLF("Attribute '%' already inserted", toString(myAttribute)));
653
}
654
}
655
#endif // DEBUG
656
}
657
658
659
void
660
GNEAttributeProperties::parseDefaultValues(const std::string& defaultValue, const bool overWritteDefaultString) {
661
// in every case parse default value back (to avoid problems during comparations)
662
if (isInt()) {
663
myDefaultIntValue = GNEAttributeCarrier::parse<int>(defaultValue);
664
if (overWritteDefaultString) {
665
myDefaultStringValue = toString(myDefaultIntValue);
666
}
667
} else if (isFloat()) {
668
myDefaultDoubleValue = GNEAttributeCarrier::parse<double>(defaultValue);
669
if (overWritteDefaultString) {
670
myDefaultStringValue = toString(myDefaultDoubleValue);
671
}
672
} else if (isSUMOTime()) {
673
myDefaultTimeValue = GNEAttributeCarrier::parse<SUMOTime>(defaultValue);
674
if (overWritteDefaultString) {
675
myDefaultStringValue = time2string(myDefaultTimeValue);
676
}
677
} else if (isBool()) {
678
myDefaultBoolValue = GNEAttributeCarrier::parse<bool>(defaultValue);
679
if (overWritteDefaultString) {
680
myDefaultStringValue = myDefaultBoolValue ? GNEAttributeCarrier::TRUE_STR : GNEAttributeCarrier::FALSE_STR;
681
}
682
} else if (isColor()) {
683
myDefaultColorValue = GNEAttributeCarrier::parse<RGBColor>(defaultValue);
684
if (overWritteDefaultString) {
685
myDefaultStringValue = toString(myDefaultColorValue);
686
}
687
} else if (isPosition()) {
688
myDefaultPositionValue = GNEAttributeCarrier::parse<Position>(defaultValue);
689
if (overWritteDefaultString) {
690
myDefaultStringValue = toString(myDefaultPositionValue);
691
}
692
}
693
}
694
695
/****************************************************************************/
696
697