Path: blob/main/src/netedit/dialogs/elements/lists/GNETemplateElementList.h
193674 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNETemplateElementList.h14/// @author Pablo Alvarez Lopez15/// @date Aug 202516///17// Template used for Element lists18/****************************************************************************/19#pragma once2021#include <netedit/dialogs/elements/GNETemplateElementDialog.h>22#include <netedit/GNEApplicationWindow.h>2324#include "GNEElementTable.h"25#include "GNEElementList.h"2627// ===========================================================================28// class definitions29// ===========================================================================3031template <typename elementDialogType, typename elementType, typename GNEChange_Type>32class GNETemplateElementList : public GNEElementList {3334public:35/// @brief constructor36GNETemplateElementList(GNETemplateElementDialog<elementDialogType>* elementDialogParent,37FXVerticalFrame* contentFrame, SumoXMLTag tag, GNEElementList::Options options) :38GNEElementList(elementDialogParent, contentFrame, tag, options),39myElementDialogParent(elementDialogParent) {40// update table41updateList();42}4344/// @brief get edited elements45const std::vector<elementType*>& getEditedElements() const {46return myEditedElements;47}4849/// @brief insert element50long insertElement(elementType* element) {51// add change command52element->getNet()->getUndoList()->add(new GNEChange_Type(element, true), true);53// update table54return updateList();55}5657/// @brief update element list58long updateList() {59// reset edited element60myEditedElements.clear();61for (const auto& child : myElementDialogParent->getElement()->getChildren().template get<elementType*>()) {62if (child->getTagProperty()->getTag() == myTagProperty->getTag()) {63myEditedElements.push_back(child);64}65}66// first resize table (used if we removed some elements)67myElementTable->resizeTable(myEditedElements.size());68// now update all rows69for (size_t i = 0; i < myEditedElements.size(); i++) {70myElementTable->updateRow(i, myEditedElements.at(i));71}72return 1;73}7475/// @brief check if the elements are sorted76bool checkSort() const {77// get sort tuples78const auto tuples = getSortTuples(false);79// check if the elements are sorted80for (int i = 0; i < ((int)tuples.size() - 1); i++) {81if (tuples.at(i) > tuples.at(i)) {82return false;83}84}85return true;86}8788/// @brief open dialog89long sortRows() {90// get sort tuples sorted91const auto sortedTuples = getSortTuples(true);92// now update edited elements list using sortTuples93myEditedElements.clear();94for (const auto& element : sortedTuples) {95myEditedElements.push_back(std::get<6>(element));96}97// sort children98myElementDialogParent->getElement()->sortChildren(myEditedElements);99// update table100return updateList();101}102103/// @brief remove element (using index)104long removeElement(const size_t rowIndex) {105// delete element recursively106removeElementRecursively(myEditedElements.at(rowIndex));107// update table108return updateList();109}110111/// @brief remove element112long removeElement(const elementType* element) {113// search index114for (size_t rowIndex = 0; rowIndex < myEditedElements.size(); rowIndex++) {115if (myEditedElements.at(rowIndex) == element) {116return removeElement(rowIndex);117}118}119// if we reach this point, the element was not found120throw ProcessError("Element not found in removeElement");121}122123/// @brief add new element (must be implemented in children)124virtual long addNewElement() = 0;125126/// @brief open element dialog (optional127virtual long openElementDialog(const size_t rowIndex) = 0;128129protected:130/// @brief element dialog parent131GNETemplateElementDialog<elementDialogType>* myElementDialogParent = nullptr;132133/// @brief edited elements134std::vector<elementType*> myEditedElements;135136private:137/// @brief typedef used for sorting elements by attributes138typedef std::tuple<double, double, double, double, double, double, elementType*> SortTuple;139140/// @brief get element sorted141std::vector<SortTuple> getSortTuples(const bool sort) const {142// declare sorted element set143std::vector<SortTuple> elementSortKeyVector;144// add all elements145for (size_t i = 0; i < myEditedElements.size(); i++) {146// create tuple with max 6 sortable attributes147auto tuple = std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, myEditedElements.at(i));148// update tuple with sortable attributes149const auto& sortableAttributes = myElementTable->getColumnHeader()->getSortableAttributes();150// fill tuple151if (sortableAttributes.size() > 0) {152std::get<0>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(0)));153}154if (sortableAttributes.size() > 1) {155std::get<1>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(1)));156}157if (sortableAttributes.size() > 2) {158std::get<2>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(2)));159}160if (sortableAttributes.size() > 3) {161std::get<3>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(3)));162}163if (sortableAttributes.size() > 4) {164std::get<4>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(4)));165}166if (sortableAttributes.size() > 5) {167std::get<5>(tuple) = GNEAttributeCarrier::parse<double>(myEditedElements.at(i)->getAttribute(sortableAttributes.at(5)));168}169elementSortKeyVector.push_back(tuple);170}171// check if sort tuples172if (sort) {173std::set<SortTuple> elementSortKeySet;174for (const auto& element : elementSortKeyVector) {175// insert tuple into set176elementSortKeySet.insert(element);177}178// clear vector and copy set into vector179elementSortKeyVector.clear();180for (const auto& element : elementSortKeySet) {181elementSortKeyVector.push_back(element);182}183}184return elementSortKeyVector;185}186187/// @brief Invalidated copy constructor188GNETemplateElementList(const GNETemplateElementList&) = delete;189190/// @brief Invalidated assignment operator191GNETemplateElementList& operator=(const GNETemplateElementList&) = delete;192};193194195