Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/dialogs/elements/lists/GNETemplateElementList.h
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 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(elementDialogParent, contentFrame, tag, 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()->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
// sort children
99
myElementDialogParent->getElement()->sortChildren(myEditedElements);
100
// update table
101
return updateList();
102
}
103
104
/// @brief remove element (using index)
105
long removeElement(const size_t rowIndex) {
106
// delete element recursively
107
removeElementRecursively(myEditedElements.at(rowIndex));
108
// update table
109
return updateList();
110
}
111
112
/// @brief remove element
113
long removeElement(const elementType* element) {
114
// search index
115
for (size_t rowIndex = 0; rowIndex < myEditedElements.size(); rowIndex++) {
116
if (myEditedElements.at(rowIndex) == element) {
117
return removeElement(rowIndex);
118
}
119
}
120
// if we reach this point, the element was not found
121
throw ProcessError("Element not found in removeElement");
122
}
123
124
/// @brief add new element (must be implemented in children)
125
virtual long addNewElement() = 0;
126
127
/// @brief open element dialog (optional
128
virtual long openElementDialog(const size_t rowIndex) = 0;
129
130
protected:
131
/// @brief element dialog parent
132
GNETemplateElementDialog<elementDialogType>* myElementDialogParent = nullptr;
133
134
/// @brief edited elements
135
std::vector<elementType*> myEditedElements;
136
137
private:
138
/// @brief typedef used for sorting elements by attributes
139
typedef std::tuple<double, double, double, double, double, double, elementType*> SortTuple;
140
141
/// @brief get element sorted
142
std::vector<SortTuple> getSortTuples(const bool sort) const {
143
// declare sorted element set
144
std::vector<SortTuple> elementSortKeyVector;
145
// add all elements
146
for (size_t i = 0; i < myEditedElements.size(); i++) {
147
// create tuple with max 6 sortable attributes
148
auto tuple = std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, myEditedElements.at(i));
149
// update tuple with sortable attributes
150
const auto& sortableAttributes = myElementTable->getColumnHeader()->getSortableAttributes();
151
// fill tuple
152
if (sortableAttributes.size() > 0) {
153
std::get<0>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(0)));
154
}
155
if (sortableAttributes.size() > 1) {
156
std::get<1>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(1)));
157
}
158
if (sortableAttributes.size() > 2) {
159
std::get<2>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(2)));
160
}
161
if (sortableAttributes.size() > 3) {
162
std::get<3>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(3)));
163
}
164
if (sortableAttributes.size() > 4) {
165
std::get<4>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(4)));
166
}
167
if (sortableAttributes.size() > 5) {
168
std::get<5>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(5)));
169
}
170
elementSortKeyVector.push_back(tuple);
171
}
172
// check if sort tuples
173
if (sort) {
174
std::set<SortTuple> elementSortKeySet;
175
for (const auto& element : elementSortKeyVector) {
176
// insert tuple into set
177
elementSortKeySet.insert(element);
178
}
179
// clear vector and copy set into vector
180
elementSortKeyVector.clear();
181
for (const auto& element : elementSortKeySet) {
182
elementSortKeyVector.push_back(element);
183
}
184
}
185
return elementSortKeyVector;
186
}
187
188
/// @brief Invalidated copy constructor
189
GNETemplateElementList(const GNETemplateElementList&) = delete;
190
191
/// @brief Invalidated assignment operator
192
GNETemplateElementList& operator=(const GNETemplateElementList&) = delete;
193
};
194
195