Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/dialogs/elements/lists/GNETemplateElementList.h
169688 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 GNETemplateElementList.h
15
/// @author Pablo Alvarez Lopez
16
/// @date Aug 2025
17
///
18
// Template used for Element lists
19
/****************************************************************************/
20
#pragma once
21
22
#include <netedit/dialogs/elements/GNETemplateElementDialog.h>
23
#include <netedit/GNEApplicationWindow.h>
24
25
#include "GNEElementTable.h"
26
#include "GNEElementList.h"
27
28
// ===========================================================================
29
// class definitions
30
// ===========================================================================
31
32
template <typename elementDialogType, typename elementType, typename GNEChange_Type>
33
class GNETemplateElementList : public GNEElementList {
34
35
public:
36
/// @brief constructor
37
GNETemplateElementList(GNETemplateElementDialog<elementDialogType>* elementDialogParent,
38
FXVerticalFrame* contentFrame, SumoXMLTag tag, GNEElementList::Options options) :
39
GNEElementList(contentFrame, elementDialogParent->getApplicationWindow()->getTagPropertiesDatabase()->getTagProperty(tag, true), options),
40
myElementDialogParent(elementDialogParent) {
41
// update table
42
updateList();
43
}
44
45
/// @brief get edited elements
46
const std::vector<elementType*>& getEditedElements() const {
47
return myEditedElements;
48
}
49
50
/// @brief insert element
51
long insertElement(elementType* element) {
52
// add change command
53
element->getNet()->getViewNet()->getUndoList()->add(new GNEChange_Type(element, true), true);
54
// update table
55
return updateList();
56
}
57
58
/// @brief update element list
59
long updateList() {
60
// reset edited element
61
myEditedElements.clear();
62
for (const auto& child : myElementDialogParent->getElement()->getChildren().template get<elementType*>()) {
63
if (child->getTagProperty()->getTag() == myTagProperty->getTag()) {
64
myEditedElements.push_back(child);
65
}
66
}
67
// first resize table (used if we removed some elements)
68
myElementTable->resizeTable(myEditedElements.size());
69
// now update all rows
70
for (size_t i = 0; i < myEditedElements.size(); i++) {
71
myElementTable->updateRow(i, myEditedElements.at(i));
72
}
73
return 1;
74
}
75
76
/// @brief check if the elements are sorted
77
bool checkSort() const {
78
// get sort tuples
79
const auto tuples = getSortTuples(false);
80
// check if the elements are sorted
81
for (int i = 0; i < ((int)tuples.size() - 1); i++) {
82
if (tuples.at(i) > tuples.at(i)) {
83
return false;
84
}
85
}
86
return true;
87
}
88
89
/// @brief open dialog
90
long sortRows() {
91
// get sort tuples sorted
92
const auto sortedTuples = getSortTuples(true);
93
// now update edited elements list using sortTuples
94
myEditedElements.clear();
95
for (const auto& element : sortedTuples) {
96
myEditedElements.push_back(std::get<6>(element));
97
}
98
// update table
99
return updateList();
100
}
101
102
/// @brief remove element (using index)
103
long removeElement(const size_t rowIndex) {
104
// delete element recursively
105
removeElementRecursively(myEditedElements.at(rowIndex));
106
// update table
107
return updateList();
108
}
109
110
/// @brief remove element
111
long removeElement(const elementType* element) {
112
// search index
113
for (size_t rowIndex = 0; rowIndex < myEditedElements.size(); rowIndex++) {
114
if (myEditedElements.at(rowIndex) == element) {
115
return removeElement(rowIndex);
116
}
117
}
118
// if we reach this point, the element was not found
119
throw ProcessError("Element not found in removeElement");
120
}
121
122
/// @brief add new element (must be implemented in children)
123
virtual long addNewElement() = 0;
124
125
/// @brief open element dialog (optional
126
virtual long openElementDialog(const size_t rowIndex) = 0;
127
128
protected:
129
/// @brief element dialog parent
130
GNETemplateElementDialog<elementDialogType>* myElementDialogParent = nullptr;
131
132
/// @brief edited elements
133
std::vector<elementType*> myEditedElements;
134
135
private:
136
/// @brief typedef used for sorting elements by attributes
137
typedef std::tuple<double, double, double, double, double, double, elementType*> SortTuple;
138
139
/// @brief get element sorted
140
std::vector<SortTuple> getSortTuples(const bool sort) const {
141
// declare sorted element set
142
std::vector<SortTuple> elementSortKeyVector;
143
// add all elements
144
for (size_t i = 0; i < myEditedElements.size(); i++) {
145
// create tuple with max 6 sortable attributes
146
auto tuple = std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, myEditedElements.at(i));
147
// update tuple with sortable attributes
148
const auto& sortableAttributes = myElementTable->getColumnHeader()->getSortableAttributes();
149
// fill tuple
150
if (sortableAttributes.size() > 0) {
151
std::get<0>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(0)));
152
}
153
if (sortableAttributes.size() > 1) {
154
std::get<1>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(1)));
155
}
156
if (sortableAttributes.size() > 2) {
157
std::get<2>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(2)));
158
}
159
if (sortableAttributes.size() > 3) {
160
std::get<3>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(3)));
161
}
162
if (sortableAttributes.size() > 4) {
163
std::get<4>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(4)));
164
}
165
if (sortableAttributes.size() > 5) {
166
std::get<5>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(5)));
167
}
168
elementSortKeyVector.push_back(tuple);
169
}
170
// check if sort tuples
171
if (sort) {
172
std::set<SortTuple> elementSortKeySet;
173
for (const auto& element : elementSortKeyVector) {
174
// insert tuple into set
175
elementSortKeySet.insert(element);
176
}
177
// clear vector and copy set into vector
178
elementSortKeyVector.clear();
179
for (const auto& element : elementSortKeySet) {
180
elementSortKeyVector.push_back(element);
181
}
182
}
183
return elementSortKeyVector;
184
}
185
186
/// @brief Invalidated copy constructor
187
GNETemplateElementList(const GNETemplateElementList&) = delete;
188
189
/// @brief Invalidated assignment operator
190
GNETemplateElementList& operator=(const GNETemplateElementList&) = delete;
191
};
192
193