#include <netedit/GNEApplicationWindow.h>
#include <netedit/GNENet.h>
#include <netedit/GNETagProperties.h>
#include <netedit/GNEUndoList.h>
#include <netedit/GNEViewNet.h>
#include <netedit/GNEViewParent.h>
#include <netedit/changes/GNEChange_Children.h>
#include <netedit/elements/data/GNEDataInterval.h>
#include <netedit/elements/network/GNEConnection.h>
#include <netedit/elements/network/GNECrossing.h>
#include <netedit/frames/common/GNEInspectorFrame.h>
#include <utils/foxtools/MFXMenuHeader.h>
#include <utils/gui/div/GUIDesigns.h>
#include <utils/gui/windows/GUIAppEnum.h>
#include "GNEElementTree.h"
FXDEFMAP(GNEElementTree) HierarchicalElementTreeMap[] = {
FXMAPFUNC(SEL_COMMAND, MID_GNE_CENTER, GNEElementTree::onCmdCenterItem),
FXMAPFUNC(SEL_COMMAND, MID_GNE_INSPECT, GNEElementTree::onCmdInspectItem),
FXMAPFUNC(SEL_COMMAND, MID_GNE_DELETE, GNEElementTree::onCmdDeleteItem),
FXMAPFUNC(SEL_COMMAND, MID_GNE_ACHIERARCHY_MOVEUP, GNEElementTree::onCmdMoveItemUp),
FXMAPFUNC(SEL_COMMAND, MID_GNE_ACHIERARCHY_MOVEDOWN, GNEElementTree::onCmdMoveItemDown),
FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, MID_GNE_ACHIERARCHY_SHOWCHILDMENU, GNEElementTree::onCmdShowChildMenu)
};
FXIMPLEMENT(GNEElementTree, MFXGroupBoxModule, HierarchicalElementTreeMap, ARRAYNUMBER(HierarchicalElementTreeMap))
GNEElementTree::GNEElementTree(GNEFrame* frameParent) :
MFXGroupBoxModule(frameParent, TL("Hierarchy")),
myFrameParent(frameParent) {
myTreeListDynamic = new MFXTreeListDynamic(getCollapsableFrame(), this, MID_GNE_ACHIERARCHY_SHOWCHILDMENU, GUIDesignTreeListFixedHeight);
hide();
}
GNEElementTree::~GNEElementTree() {}
void
GNEElementTree::showHierarchicalElementTree(GNEAttributeCarrier* AC) {
myHierarchicalElement = AC;
if (myHierarchicalElement) {
refreshHierarchicalElementTree();
myTreeListDynamic->show();
show();
}
}
void
GNEElementTree::hideHierarchicalElementTree() {
myHierarchicalElement = nullptr;
myClickedAC = nullptr;
myClickedJunction = nullptr;
myClickedEdge = nullptr;
myClickedLane = nullptr;
myClickedCrossing = nullptr;
myClickedConnection = nullptr;
myClickedAdditional = nullptr;
myClickedTAZSourceSink = nullptr;
myClickedDemandElement = nullptr;
myClickedDataSet = nullptr;
myClickedDataInterval = nullptr;
myClickedGenericData = nullptr;
myTreeListDynamic->hide();
hide();
}
void
GNEElementTree::refreshHierarchicalElementTree() {
myTreeListDynamic->clearItems();
myTreeItemToACMap.clear();
myTreeItemsConnections.clear();
if (myHierarchicalElement) {
showHierarchicalElementChildren(myHierarchicalElement, showAttributeCarrierParents());
}
}
void
GNEElementTree::removeCurrentEditedAttributeCarrier(const GNEAttributeCarrier* AC) {
if (AC == myHierarchicalElement) {
myHierarchicalElement = nullptr;
}
}
long
GNEElementTree::onCmdShowChildMenu(FXObject*, FXSelector, void* eventData) {
FXEvent* e = (FXEvent*)eventData;
FXTreeItem* item = myTreeListDynamic->getItemAt(e->win_x, e->win_y);
if (item && (myTreeItemsConnections.find(item) == myTreeItemsConnections.end())) {
createPopUpMenu(e->root_x, e->root_y, myTreeItemToACMap[item]);
}
return 1;
}
long
GNEElementTree::onCmdCenterItem(FXObject*, FXSelector, void*) {
if (myClickedJunction) {
myFrameParent->getViewNet()->centerTo(myClickedJunction->getGlID(), true, -1);
} else if (myClickedEdge) {
myFrameParent->getViewNet()->centerTo(myClickedEdge->getGlID(), true, -1);
} else if (myClickedLane) {
myFrameParent->getViewNet()->centerTo(myClickedLane->getGlID(), true, -1);
} else if (myClickedCrossing) {
myFrameParent->getViewNet()->centerTo(myClickedCrossing->getGlID(), true, -1);
} else if (myClickedConnection) {
myFrameParent->getViewNet()->centerTo(myClickedConnection->getGlID(), true, -1);
} else if (myClickedAdditional) {
myFrameParent->getViewNet()->centerTo(myClickedAdditional->getGlID(), true, -1);
} else if (myClickedTAZSourceSink) {
myFrameParent->getViewNet()->centerTo(myClickedTAZSourceSink->getParentEdges().front()->getGlID(), true, -1);
} else if (myClickedDemandElement) {
myFrameParent->getViewNet()->centerTo(myClickedDemandElement->getGlID(), true, -1);
} else if (myClickedGenericData) {
myFrameParent->getViewNet()->centerTo(myClickedGenericData->getGlID(), true, -1);
}
myFrameParent->getViewNet()->updateViewNet();
return 1;
}
long
GNEElementTree::onCmdInspectItem(FXObject*, FXSelector, void*) {
myFrameParent->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(myClickedAC, myHierarchicalElement);
return 1;
}
long
GNEElementTree::onCmdDeleteItem(FXObject*, FXSelector, void*) {
const auto& inspectedElements = myFrameParent->getViewNet()->getInspectedElements();
if (myClickedJunction) {
myFrameParent->getViewNet()->getNet()->deleteJunction(myClickedJunction, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedEdge) {
myFrameParent->getViewNet()->getNet()->deleteEdge(myClickedEdge, myFrameParent->getViewNet()->getUndoList(), false);
} else if (myClickedLane) {
myFrameParent->getViewNet()->getNet()->deleteLane(myClickedLane, myFrameParent->getViewNet()->getUndoList(), false);
} else if (myClickedCrossing) {
myFrameParent->getViewNet()->getNet()->deleteCrossing(myClickedCrossing, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedConnection) {
myFrameParent->getViewNet()->getNet()->deleteConnection(myClickedConnection, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedAdditional) {
myFrameParent->getViewNet()->getNet()->deleteAdditional(myClickedAdditional, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedTAZSourceSink) {
myFrameParent->getViewNet()->getNet()->deleteTAZSourceSink(myClickedTAZSourceSink, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedDemandElement) {
if ((myClickedDemandElement->getTagProperty()->getTag() == SUMO_TAG_VTYPE) && (GNEAttributeCarrier::parse<bool>(myClickedDemandElement->getAttribute(GNE_ATTR_DEFAULT_VTYPE)))) {
WRITE_WARNINGF(TL("Default Vehicle Type '%' cannot be removed"), myClickedDemandElement->getAttribute(SUMO_ATTR_ID));
return 1;
} else if (myClickedDemandElement->getTagProperty()->isPlan()) {
auto planParent = myClickedDemandElement->getParentDemandElements().front();
if (planParent->getChildDemandElements().size() == 1) {
myFrameParent->getViewNet()->getNet()->deleteDemandElement(planParent, myFrameParent->getViewNet()->getUndoList());
} else {
myFrameParent->getViewNet()->getNet()->deleteDemandElement(myClickedDemandElement, myFrameParent->getViewNet()->getUndoList());
}
}
} else if (myClickedDataSet) {
myFrameParent->getViewNet()->getNet()->deleteDataSet(myClickedDataSet, myFrameParent->getViewNet()->getUndoList());
} else if (myClickedDataInterval) {
if (myClickedDataInterval->getDataSetParent()->getDataIntervalChildren().size() == 1) {
myFrameParent->getViewNet()->getNet()->deleteDataSet(myClickedDataInterval->getDataSetParent(), myFrameParent->getViewNet()->getUndoList());
} else {
myFrameParent->getViewNet()->getNet()->deleteDataInterval(myClickedDataInterval, myFrameParent->getViewNet()->getUndoList());
}
} else if (myClickedGenericData) {
if (myClickedGenericData->getDataIntervalParent()->getGenericDataChildren().size() == 1) {
if (myClickedGenericData->getDataIntervalParent()->getDataSetParent()->getDataIntervalChildren().size() == 1) {
myFrameParent->getViewNet()->getNet()->deleteDataSet(myClickedGenericData->getDataIntervalParent()->getDataSetParent(), myFrameParent->getViewNet()->getUndoList());
} else {
myFrameParent->getViewNet()->getNet()->deleteDataInterval(myClickedGenericData->getDataIntervalParent(), myFrameParent->getViewNet()->getUndoList());
}
} else {
myFrameParent->getViewNet()->getNet()->deleteGenericData(myClickedGenericData, myFrameParent->getViewNet()->getUndoList());
}
}
refreshHierarchicalElementTree();
if (inspectedElements.isInspectingSingleElement()) {
if (inspectedElements.getFirstAC() != myClickedAC) {
myFrameParent->getViewNet()->getViewParent()->getInspectorFrame()->inspectElement(inspectedElements.getFirstAC());
} else {
myFrameParent->getViewNet()->getViewParent()->getInspectorFrame()->clearInspection();
}
}
return 1;
}
long
GNEElementTree::onCmdMoveItemUp(FXObject*, FXSelector, void*) {
if (myClickedDemandElement) {
myFrameParent->getViewNet()->getUndoList()->begin(myClickedDemandElement, ("moving up " + myClickedDemandElement->getTagStr()).c_str());
myFrameParent->getViewNet()->getUndoList()->add(new GNEChange_Children(myClickedDemandElement->getParentDemandElements().at(0), myClickedDemandElement,
GNEChange_Children::Operation::MOVE_BACK), true);
myFrameParent->getViewNet()->getUndoList()->end();
}
refreshHierarchicalElementTree();
return 1;
}
long
GNEElementTree::onCmdMoveItemDown(FXObject*, FXSelector, void*) {
if (myClickedDemandElement) {
myFrameParent->getViewNet()->getUndoList()->begin(myClickedDemandElement, ("moving down " + myClickedDemandElement->getTagStr()).c_str());
myFrameParent->getViewNet()->getUndoList()->add(new GNEChange_Children(myClickedDemandElement->getParentDemandElements().at(0), myClickedDemandElement,
GNEChange_Children::Operation::MOVE_FRONT), true);
myFrameParent->getViewNet()->getUndoList()->end();
}
refreshHierarchicalElementTree();
return 1;
}
void
GNEElementTree::createPopUpMenu(int X, int Y, GNEAttributeCarrier* clickedAC) {
const auto& attributeCarriers = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
if (clickedAC) {
myClickedAC = clickedAC;
myClickedJunction = attributeCarriers->retrieveJunction(clickedAC->getID(), false);
myClickedEdge = attributeCarriers->retrieveEdge(clickedAC->getID(), false);
myClickedLane = attributeCarriers->retrieveLane(clickedAC->getGUIGlObject(), false);
myClickedCrossing = attributeCarriers->retrieveCrossing(clickedAC->getGUIGlObject(), false);
myClickedConnection = attributeCarriers->retrieveConnection(clickedAC->getGUIGlObject(), false);
myClickedAdditional = attributeCarriers->retrieveAdditional(clickedAC->getGUIGlObject(), false);
myClickedTAZSourceSink = attributeCarriers->retrieveTAZSourceSink(clickedAC, false);
myClickedDemandElement = attributeCarriers->retrieveDemandElement(clickedAC->getGUIGlObject(), false);
myClickedDataSet = attributeCarriers->retrieveDataSet(clickedAC->getID(), false);
myClickedDataInterval = attributeCarriers->retrieveDataInterval(clickedAC, false);
myClickedGenericData = attributeCarriers->retrieveGenericData(clickedAC->getGUIGlObject(), false);
FXMenuPane* pane = new FXMenuPane(myTreeListDynamic->getFXWindow());
new MFXMenuHeader(pane, myFrameParent->getViewNet()->getViewParent()->getGUIMainWindow()->getBoldFont(), myClickedAC->getPopUpID().c_str(), myClickedAC->getACIcon());
if (myClickedTAZSourceSink) {
new FXMenuSeparator(pane);
GUIDesigns::buildFXMenuCommand(pane, TLF("Edge: %", myClickedTAZSourceSink->getParentEdges().front()->getID()), nullptr, nullptr, 0);
}
new FXMenuSeparator(pane);
FXMenuCommand* centerMenuCommand = GUIDesigns::buildFXMenuCommand(pane, TL("Center"), GUIIconSubSys::getIcon(GUIIcon::RECENTERVIEW), this, MID_GNE_CENTER);
if (myClickedAC->getTagProperty()->isType() || (myClickedAC->getTagProperty()->getTag() == SUMO_TAG_DATASET) ||
(myClickedAC->getTagProperty()->getTag() == SUMO_TAG_DATAINTERVAL)) {
centerMenuCommand->disable();
}
FXMenuCommand* inspectMenuCommand = GUIDesigns::buildFXMenuCommand(pane, TL("Inspect"), GUIIconSubSys::getIcon(GUIIcon::MODEINSPECT), this, MID_GNE_INSPECT);
FXMenuCommand* deleteMenuCommand = GUIDesigns::buildFXMenuCommand(pane, TL("Delete"), GUIIconSubSys::getIcon(GUIIcon::MODEDELETE), this, MID_GNE_DELETE);
if (!isSupermodeValid(myClickedAC)) {
inspectMenuCommand->disable();
deleteMenuCommand->disable();
}
pane->setX(X);
pane->setY(Y);
pane->create();
pane->show();
} else {
myClickedAC = nullptr;
myClickedJunction = nullptr;
myClickedEdge = nullptr;
myClickedLane = nullptr;
myClickedCrossing = nullptr;
myClickedConnection = nullptr;
myClickedAdditional = nullptr;
myClickedTAZSourceSink = nullptr;
myClickedDemandElement = nullptr;
myClickedDataSet = nullptr;
myClickedDataInterval = nullptr;
myClickedGenericData = nullptr;
}
}
FXTreeItem*
GNEElementTree::showAttributeCarrierParents() {
const auto& attributeCarriers = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
if (myHierarchicalElement->getTagProperty()->isNetworkElement()) {
switch (myHierarchicalElement->getTagProperty()->getTag()) {
case SUMO_TAG_EDGE: {
GNEEdge* edge = attributeCarriers->retrieveEdge(myHierarchicalElement->getID(), false);
if (edge == nullptr) {
return nullptr;
} else {
FXTreeItem* junctionSourceItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" origin")).c_str(), edge->getFromJunction()->getACIcon());
FXTreeItem* junctionDestinationItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" destination")).c_str(), edge->getFromJunction()->getACIcon());
junctionDestinationItem->setExpanded(true);
myTreeItemToACMap[junctionSourceItem] = edge->getFromJunction();
myTreeItemToACMap[junctionDestinationItem] = edge->getToJunction();
return junctionDestinationItem;
}
}
case SUMO_TAG_LANE: {
GNELane* lane = attributeCarriers->retrieveLane(myHierarchicalElement->getID(), false);
if (lane == nullptr) {
return nullptr;
} else {
GNEEdge* edge = attributeCarriers->retrieveEdge(lane->getParentEdge()->getID());
FXTreeItem* junctionSourceItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" origin")).c_str(), edge->getFromJunction()->getACIcon());
FXTreeItem* junctionDestinationItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" destination")).c_str(), edge->getFromJunction()->getACIcon());
junctionDestinationItem->setExpanded(true);
FXTreeItem* edgeItem = myTreeListDynamic->appendItem(junctionDestinationItem, edge->getHierarchyName().c_str(), edge->getACIcon());
edgeItem->setExpanded(true);
myTreeItemToACMap[junctionSourceItem] = edge->getFromJunction();
myTreeItemToACMap[junctionDestinationItem] = edge->getToJunction();
myTreeItemToACMap[edgeItem] = edge;
return edgeItem;
}
}
case SUMO_TAG_CROSSING: {
auto crossing = attributeCarriers->retrieveCrossing(myHierarchicalElement->getGUIGlObject(), false);
if (crossing == nullptr) {
return nullptr;
} else {
GNEJunction* junction = crossing->getParentJunctions().front();
FXTreeItem* junctionItem = myTreeListDynamic->appendItem(nullptr, junction->getHierarchyName().c_str(), junction->getACIcon());
junctionItem->setExpanded(true);
myTreeItemToACMap[junctionItem] = junction;
return junctionItem;
}
}
case SUMO_TAG_CONNECTION: {
GNEConnection* connection = attributeCarriers->retrieveConnection(myHierarchicalElement->getID(), false);
if (connection == nullptr) {
return nullptr;
} else {
FXTreeItem* edgeFromItem = myTreeListDynamic->appendItem(nullptr, connection->getEdgeFrom()->getHierarchyName().c_str(), connection->getEdgeFrom()->getACIcon());
edgeFromItem->setExpanded(true);
FXTreeItem* edgeToItem = myTreeListDynamic->appendItem(nullptr, connection->getEdgeTo()->getHierarchyName().c_str(), connection->getEdgeTo()->getACIcon());
edgeToItem->setExpanded(true);
FXTreeItem* connectionItem = myTreeListDynamic->appendItem(edgeToItem, connection->getHierarchyName().c_str(), connection->getACIcon());
connectionItem->setExpanded(true);
myTreeItemToACMap[edgeFromItem] = connection->getEdgeFrom();
myTreeItemToACMap[edgeToItem] = connection->getEdgeTo();
myTreeItemToACMap[connectionItem] = connection;
return connectionItem;
}
}
default:
break;
}
} else if (myHierarchicalElement->getTagProperty()->getTag() == GNE_TAG_POILANE) {
const auto* POILane = attributeCarriers->retrieveAdditional(myHierarchicalElement->getGUIGlObject(), false);
if (POILane == nullptr) {
return nullptr;
} else {
GNELane* lane = attributeCarriers->retrieveLane(POILane->getParentLanes().at(0)->getID());
GNEEdge* edge = attributeCarriers->retrieveEdge(lane->getParentEdge()->getID());
FXTreeItem* junctionSourceItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" origin")).c_str(), edge->getFromJunction()->getACIcon());
FXTreeItem* junctionDestinationItem = myTreeListDynamic->appendItem(nullptr, (edge->getFromJunction()->getHierarchyName() + TL(" destination")).c_str(), edge->getFromJunction()->getACIcon());
junctionDestinationItem->setExpanded(true);
FXTreeItem* edgeItem = myTreeListDynamic->appendItem(junctionDestinationItem, edge->getHierarchyName().c_str(), edge->getACIcon());
edgeItem->setExpanded(true);
FXTreeItem* laneItem = myTreeListDynamic->appendItem(edgeItem, lane->getHierarchyName().c_str(), lane->getACIcon());
laneItem->setExpanded(true);
myTreeItemToACMap[junctionSourceItem] = edge->getFromJunction();
myTreeItemToACMap[junctionDestinationItem] = edge->getToJunction();
myTreeItemToACMap[edgeItem] = edge;
myTreeItemToACMap[laneItem] = lane;
return laneItem;
}
} else if (myHierarchicalElement->getTagProperty()->isAdditionalElement()) {
const GNEAdditional* additional = attributeCarriers->retrieveAdditional(myHierarchicalElement->getGUIGlObject(), false);
if (additional == nullptr) {
return nullptr;
} else {
FXTreeItem* root = nullptr;
if (additional->getParentAdditionals().size() > 0) {
if (additional->getParentAdditionals().size() > 1) {
addListItem(additional->getParentAdditionals().front());
if (additional->getParentAdditionals().size() > 2) {
addListItem(nullptr, ("..." + toString((int)additional->getParentAdditionals().size() - 2) + TL(" additionals...")).c_str(), 0, false);
}
}
root = addListItem(additional->getParentAdditionals().back());
}
if (additional->getParentDemandElements().size() > 0) {
if (additional->getParentDemandElements().size() > 1) {
addListItem(additional->getParentDemandElements().front());
if (additional->getParentDemandElements().size() > 2) {
addListItem(nullptr, ("..." + toString((int)additional->getParentDemandElements().size() - 2) + TL(" demand elements...")).c_str(), 0, false);
}
}
root = addListItem(additional->getParentDemandElements().back());
}
if (additional->getParentEdges().size() > 0) {
if (additional->getParentEdges().size() > 1) {
addListItem(additional->getParentEdges().front());
if (additional->getParentEdges().size() > 2) {
addListItem(nullptr, ("..." + toString((int)additional->getParentEdges().size() - 2) + TL(" edges...")).c_str(), 0, false);
}
}
root = addListItem(additional->getParentEdges().back());
}
if (additional->getParentLanes().size() > 0) {
if (additional->getParentLanes().size() > 1) {
addListItem(additional->getParentLanes().front());
if (additional->getParentLanes().size() > 2) {
addListItem(nullptr, ("..." + toString((int)additional->getParentLanes().size() - 2) + TL(" lanes...")).c_str(), 0, false);
}
}
root = addListItem(additional->getParentLanes().back());
}
return root;
}
} else if (myHierarchicalElement->getTagProperty()->isTAZElement()) {
const GNEAdditional* TAZElement = attributeCarriers->retrieveAdditional(myHierarchicalElement->getGUIGlObject(), false);
if (TAZElement == nullptr) {
return nullptr;
} else {
FXTreeItem* root = nullptr;
if (TAZElement->getParentAdditionals().size() > 0) {
if (TAZElement->getParentAdditionals().size() > 1) {
addListItem(TAZElement->getParentAdditionals().front());
if (TAZElement->getParentAdditionals().size() > 2) {
addListItem(nullptr, ("..." + toString((int)TAZElement->getParentAdditionals().size() - 2) + TL(" TAZElements...")).c_str(), 0, false);
}
}
root = addListItem(TAZElement->getParentAdditionals().back());
}
if (TAZElement->getParentDemandElements().size() > 0) {
if (TAZElement->getParentDemandElements().size() > 1) {
addListItem(TAZElement->getParentDemandElements().front());
if (TAZElement->getParentDemandElements().size() > 2) {
addListItem(nullptr, ("..." + toString((int)TAZElement->getParentDemandElements().size() - 2) + TL(" demand elements...")).c_str(), 0, false);
}
}
root = addListItem(TAZElement->getParentDemandElements().back());
}
if (TAZElement->getParentEdges().size() > 0) {
if (TAZElement->getParentEdges().size() > 1) {
addListItem(TAZElement->getParentEdges().front());
if (TAZElement->getParentEdges().size() > 2) {
addListItem(nullptr, ("..." + toString((int)TAZElement->getParentEdges().size() - 2) + TL(" edges...")).c_str(), 0, false);
}
}
root = addListItem(TAZElement->getParentEdges().back());
}
if (TAZElement->getParentLanes().size() > 0) {
if (TAZElement->getParentLanes().size() > 1) {
addListItem(TAZElement->getParentLanes().front());
if (TAZElement->getParentLanes().size() > 2) {
addListItem(nullptr, ("..." + toString((int)TAZElement->getParentLanes().size() - 2) + TL(" lanes...")).c_str(), 0, false);
}
}
root = addListItem(TAZElement->getParentLanes().back());
}
return root;
}
} else if (myHierarchicalElement->getTagProperty()->isDemandElement()) {
GNEDemandElement* demandElement = attributeCarriers->retrieveDemandElement(myHierarchicalElement->getGUIGlObject(), false);
if (demandElement == nullptr) {
return nullptr;
} else {
FXTreeItem* root = nullptr;
if (demandElement->getParentAdditionals().size() > 0) {
if (demandElement->getParentAdditionals().size() > 1) {
addListItem(demandElement->getParentAdditionals().front());
if (demandElement->getParentAdditionals().size() > 2) {
addListItem(nullptr, ("..." + toString((int)demandElement->getParentAdditionals().size() - 2) + TL(" additionals...")).c_str(), 0, false);
}
}
root = addListItem(demandElement->getParentAdditionals().back());
}
if (demandElement->getParentDemandElements().size() > 0) {
if (demandElement->getParentDemandElements().size() > 1) {
addListItem(demandElement->getParentDemandElements().front());
if (demandElement->getParentDemandElements().size() > 2) {
addListItem(nullptr, ("..." + toString((int)demandElement->getParentDemandElements().size() - 2) + TL(" demand elements...")).c_str(), 0, false);
}
}
root = addListItem(demandElement->getParentDemandElements().back());
}
if (demandElement->getParentEdges().size() > 0) {
if (demandElement->getParentEdges().size() > 1) {
addListItem(demandElement->getParentEdges().front());
if (demandElement->getParentEdges().size() > 2) {
addListItem(nullptr, ("..." + toString((int)demandElement->getParentEdges().size() - 2) + TL(" edges...")).c_str(), 0, false);
}
}
root = addListItem(demandElement->getParentEdges().back());
}
if (demandElement->getParentLanes().size() > 0) {
if (demandElement->getParentLanes().size() > 1) {
addListItem(demandElement->getParentLanes().front());
if (demandElement->getParentLanes().size() > 2) {
addListItem(nullptr, ("..." + toString((int)demandElement->getParentLanes().size() - 2) + TL(" lanes...")).c_str(), 0, false);
}
}
root = addListItem(demandElement->getParentLanes().back());
}
return root;
}
} else if (myHierarchicalElement->getTagProperty()->isDataElement()) {
if (myHierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_DATASET) {
return nullptr;
} else if (myHierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_DATAINTERVAL) {
auto dataInterval = attributeCarriers->retrieveDataInterval(myHierarchicalElement, false);
if (dataInterval == nullptr) {
return nullptr;
} else {
return addListItem(dataInterval);
}
} else {
GNEGenericData* dataElement = dynamic_cast<GNEGenericData*>(myHierarchicalElement);
if (dataElement == nullptr) {
return nullptr;
} else {
FXTreeItem* root = nullptr;
addListItem(dataElement->getDataIntervalParent()->getDataSetParent());
addListItem(dataElement->getDataIntervalParent());
if (dataElement->getParentAdditionals().size() > 0) {
if (dataElement->getParentAdditionals().size() > 1) {
addListItem(dataElement->getParentAdditionals().front());
if (dataElement->getParentAdditionals().size() > 2) {
addListItem(nullptr, ("..." + toString((int)dataElement->getParentAdditionals().size() - 2) + TL(" additionals...")).c_str(), 0, false);
}
}
root = addListItem(dataElement->getParentAdditionals().back());
}
if (dataElement->getParentDemandElements().size() > 0) {
if (dataElement->getParentDemandElements().size() > 1) {
addListItem(dataElement->getParentDemandElements().front());
if (dataElement->getParentDemandElements().size() > 2) {
addListItem(nullptr, ("..." + toString((int)dataElement->getParentDemandElements().size() - 2) + TL(" demand elements...")).c_str(), 0, false);
}
}
root = addListItem(dataElement->getParentDemandElements().back());
}
if (dataElement->getParentEdges().size() > 0) {
if (dataElement->getParentEdges().size() > 1) {
if (dataElement->getTagProperty()->getTag() == SUMO_TAG_EDGEREL) {
addListItem(dataElement->getParentEdges().front(), nullptr, "from ");
} else {
addListItem(dataElement->getParentEdges().front());
}
if (dataElement->getParentEdges().size() > 2) {
addListItem(nullptr, ("..." + toString((int)dataElement->getParentEdges().size() - 2) + TL(" edges...")).c_str(), 0, false);
}
}
if (dataElement->getTagProperty()->getTag() == SUMO_TAG_EDGEREL) {
addListItem(dataElement->getParentEdges().back(), nullptr, "to ");
} else {
addListItem(dataElement->getParentEdges().back());
}
}
if (dataElement->getParentLanes().size() > 0) {
if (dataElement->getParentLanes().size() > 1) {
addListItem(dataElement->getParentLanes().front());
if (dataElement->getParentLanes().size() > 2) {
addListItem(nullptr, ("..." + toString((int)dataElement->getParentLanes().size() - 2) + TL(" lanes...")).c_str(), 0, false);
}
}
root = addListItem(dataElement->getParentLanes().back());
}
return root;
}
}
}
return nullptr;
}
void
GNEElementTree::showHierarchicalElementChildren(GNEAttributeCarrier* hierarchicalElement, FXTreeItem* itemParent) {
const auto& attributeCarriers = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
FXTreeItem* item = addListItem(hierarchicalElement, itemParent);
for (const auto& junction : hierarchicalElement->getHierarchicalElement()->getChildJunctions()) {
showHierarchicalElementChildren(junction, item);
}
for (const auto& edge : hierarchicalElement->getHierarchicalElement()->getChildEdges()) {
showHierarchicalElementChildren(edge, item);
}
for (const auto& lane : hierarchicalElement->getHierarchicalElement()->getChildLanes()) {
showHierarchicalElementChildren(lane, item);
}
if (hierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_JUNCTION) {
GNEJunction* junction = attributeCarriers->retrieveJunction(hierarchicalElement->getID(), false);
if (junction) {
for (const auto& crossing : junction->getGNECrossings()) {
showHierarchicalElementChildren(crossing, item);
}
}
}
if (hierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_LANE) {
GNELane* lane = attributeCarriers->retrieveLane(hierarchicalElement->getID(), false);
if (lane) {
if (lane->getGNEIncomingConnections().size() > 0) {
std::vector<GNEConnection*> incomingLaneConnections = lane->getGNEIncomingConnections();
FXTreeItem* incomingConnections = addListItem(item, TL("Incomings"), incomingLaneConnections.front()->getACIcon(), false);
for (const auto& connection : incomingLaneConnections) {
showHierarchicalElementChildren(connection, incomingConnections);
}
}
if (lane->getGNEOutcomingConnections().size() > 0) {
std::vector<GNEConnection*> outcomingLaneConnections = lane->getGNEOutcomingConnections();
FXTreeItem* outgoingConnections = addListItem(item, TL("Outgoing"), outcomingLaneConnections.front()->getACIcon(), false);
for (const auto& connection : outcomingLaneConnections) {
showHierarchicalElementChildren(connection, outgoingConnections);
}
}
}
}
for (const auto& additional : hierarchicalElement->getHierarchicalElement()->getChildAdditionals()) {
if (!additional->getTagProperty()->isSymbol()) {
showHierarchicalElementChildren(additional, item);
}
}
for (const auto& additional : hierarchicalElement->getHierarchicalElement()->getChildAdditionals()) {
if (additional->getTagProperty()->isSymbol()) {
showHierarchicalElementChildren(additional, item);
}
}
if (hierarchicalElement->getHierarchicalElement()->getChildTAZSourceSinks().size() > 20) {
addListItem(item, TLF("SourceSinks (%)", toString(hierarchicalElement->getHierarchicalElement()->getChildTAZSourceSinks().size())), GUIIconSubSys::getIcon(GUIIcon::TAZ), false);
} else {
for (const auto& TAZSource : hierarchicalElement->getHierarchicalElement()->getChildTAZSourceSinks()) {
if (TAZSource->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) {
showHierarchicalElementChildren(TAZSource, item);
}
}
for (const auto& TAZSink : hierarchicalElement->getHierarchicalElement()->getChildTAZSourceSinks()) {
if (TAZSink->getTagProperty()->getTag() == SUMO_TAG_TAZSINK) {
showHierarchicalElementChildren(TAZSink, item);
}
}
}
for (const auto& demandElement : hierarchicalElement->getHierarchicalElement()->getChildDemandElements()) {
showHierarchicalElementChildren(demandElement, item);
}
if (hierarchicalElement->getHierarchicalElement()->getChildGenericDatas().size() > 0) {
FXTreeItem* dataElements = addListItem(item, TL("Data elements"), GUIIconSubSys::getIcon(GUIIcon::SUPERMODEDATA), false);
for (const auto& genericDatas : hierarchicalElement->getHierarchicalElement()->getChildGenericDatas()) {
showHierarchicalElementChildren(genericDatas, dataElements);
}
}
if (hierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_DATASET) {
GNEDataSet* dataSet = attributeCarriers->retrieveDataSet(hierarchicalElement->getID(), false);
if (dataSet) {
for (const auto& interval : dataSet->getDataIntervalChildren()) {
showHierarchicalElementChildren(interval.second, item);
}
}
}
if (hierarchicalElement->getTagProperty()->getTag() == SUMO_TAG_DATAINTERVAL) {
auto dataInterval = attributeCarriers->retrieveDataInterval(hierarchicalElement, false);
if (dataInterval) {
for (const auto& genericData : dataInterval->getGenericDataChildren()) {
showHierarchicalElementChildren(genericData, item);
}
}
} else if (hierarchicalElement->getHierarchicalElement()->getChildGenericDatas().size() > 0) {
FXTreeItem* dataElements = addListItem(item, TL("Data elements"), GUIIconSubSys::getIcon(GUIIcon::SUPERMODEDATA), false);
for (const auto& genericDatas : hierarchicalElement->getHierarchicalElement()->getChildGenericDatas()) {
showHierarchicalElementChildren(genericDatas, dataElements);
}
}
}
FXTreeItem*
GNEElementTree::addListItem(GNEAttributeCarrier* AC, FXTreeItem* itemParent, std::string prefix, std::string sufix) {
if (AC) {
FXTreeItem* item = myTreeListDynamic->appendItem(itemParent, (prefix + AC->getHierarchyName() + sufix).c_str(), AC->getACIcon());
myTreeItemToACMap[item] = AC;
item->setExpanded(true);
return item;
} else {
return nullptr;
}
}
FXTreeItem*
GNEElementTree::addListItem(FXTreeItem* itemParent, const std::string& text, FXIcon* icon, bool expanded) {
if (itemParent) {
FXTreeItem* item = myTreeListDynamic->appendItem(itemParent, text.c_str(), icon);
item->setExpanded(expanded);
return item;
} else {
return nullptr;
}
}
bool
GNEElementTree::isSupermodeValid(const GNEAttributeCarrier* AC) const {
const auto& editModes = myFrameParent->getViewNet()->getEditModes();
const auto tagProperty = AC->getTagProperty();
if (editModes.isCurrentSupermodeNetwork()) {
if (tagProperty->isNetworkElement() || tagProperty->isAdditionalElement()) {
return true;
} else if ((tagProperty->getTag() == SUMO_TAG_TAZSOURCE) || (tagProperty->getTag() == SUMO_TAG_TAZSINK)) {
return true;
} else {
return false;
}
} else if (editModes.isCurrentSupermodeDemand() &&
tagProperty->isDemandElement()) {
return true;
} else if (editModes.isCurrentSupermodeData() &&
(tagProperty->isDataElement() || tagProperty->isMeanData())) {
return true;
} else {
return false;
}
}