Path: blob/main/src/utils/gui/globjects/GUIGLObjectPopupMenu.cpp
169684 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 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 GUIGLObjectPopupMenu.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Sept 200218///19// The popup menu of a globject20/****************************************************************************/21#include <config.h>2223#include <iostream>24#include <cassert>25#include <utils/common/StringTokenizer.h>26#include <utils/common/StringUtils.h>27#include <utils/geom/GeoConvHelper.h>28#include <utils/gui/windows/GUISUMOAbstractView.h>29#include <utils/gui/globjects/GUIGlObject.h>30#include <utils/gui/windows/GUIAppEnum.h>31#include <utils/gui/windows/GUIMainWindow.h>32#include <utils/gui/div/GUIParameterTableWindow.h>33#include <utils/gui/div/GUIGlobalSelection.h>34#include <utils/gui/div/GUIUserIO.h>35#include <utils/common/ToString.h>36#include "GUIGLObjectPopupMenu.h"37#include <utils/foxtools/MFXLinkLabel.h>3839// ===========================================================================40// FOX callback mapping41// ===========================================================================42FXDEFMAP(GUIGLObjectPopupMenu) GUIGLObjectPopupMenuMap[] = {43FXMAPFUNC(SEL_COMMAND, MID_CENTER, GUIGLObjectPopupMenu::onCmdCenter),44FXMAPFUNC(SEL_COMMAND, MID_COPY_NAME, GUIGLObjectPopupMenu::onCmdCopyName),45FXMAPFUNC(SEL_COMMAND, MID_COPY_TYPED_NAME, GUIGLObjectPopupMenu::onCmdCopyTypedName),46FXMAPFUNC(SEL_COMMAND, MID_COPY_EDGE_NAME, GUIGLObjectPopupMenu::onCmdCopyEdgeName),47FXMAPFUNC(SEL_COMMAND, MID_COPY_TEST_COORDINATES, GUIGLObjectPopupMenu::onCmdCopyTestCoordinates),48FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_POSITION, GUIGLObjectPopupMenu::onCmdCopyCursorPosition),49FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_GEOPOSITION, GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition),50FXMAPFUNC(SEL_COMMAND, MID_COPY_VIEW_GEOBOUNDARY, GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary),51FXMAPFUNC(SEL_COMMAND, MID_SHOW_GEOPOSITION_ONLINE, GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline),52FXMAPFUNC(SEL_COMMAND, MID_SHOWPARS, GUIGLObjectPopupMenu::onCmdShowPars),53FXMAPFUNC(SEL_COMMAND, MID_SHOWTYPEPARS, GUIGLObjectPopupMenu::onCmdShowTypePars),54FXMAPFUNC(SEL_COMMAND, MID_ADDSELECT, GUIGLObjectPopupMenu::onCmdAddSelected),55FXMAPFUNC(SEL_COMMAND, MID_REMOVESELECT, GUIGLObjectPopupMenu::onCmdRemoveSelected)56};5758// Object implementation59FXIMPLEMENT(GUIGLObjectPopupMenu, FXMenuPane, GUIGLObjectPopupMenuMap, ARRAYNUMBER(GUIGLObjectPopupMenuMap))606162// ===========================================================================63// method definitions64// ===========================================================================6566GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject* o) :67FXMenuPane(&parent),68myParent(&parent),69myObject(o),70myApplication(&app),71myPopupType(PopupType::ATTRIBUTES),72myNetworkPosition(parent.getPositionInformation()),73myTestCoordinates((toString(parent.getWindowCursorPosition().x() - 24.0) + " " + toString(parent.getWindowCursorPosition().y() - 25.0))) {74}757677GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow* app, GUISUMOAbstractView* parent, PopupType popupType) :78FXMenuPane(parent),79myParent(parent),80myObject(nullptr),81myApplication(app),82myPopupType(popupType),83myNetworkPosition(parent->getPositionInformation()) {84}858687GUIGLObjectPopupMenu::~GUIGLObjectPopupMenu() {88// Delete MenuPane children89for (const auto& pane : myMenuPanes) {90delete pane;91}92}939495void96GUIGLObjectPopupMenu::insertMenuPaneChild(FXMenuPane* child) {97// Check that MenuPaneChild isn't NULL98if (child == nullptr) {99throw ProcessError("MenuPaneChild cannot be NULL");100}101// Check that MenuPaneChild wasn't already inserted102for (const auto& pane : myMenuPanes) {103if (pane == child) {104throw ProcessError("MenuPaneChild already inserted");105}106}107// Insert MenuPaneChild108myMenuPanes.push_back(child);109}110111112void113GUIGLObjectPopupMenu::removePopupFromObject() {114// remove popup menu from object115if (myObject) {116myObject->removedPopupMenu();117}118}119120GUISUMOAbstractView*121GUIGLObjectPopupMenu::getParentView() {122return myParent;123}124125126GUIGlObject*127GUIGLObjectPopupMenu::getGLObject() const {128return myObject;129}130131132GUIGLObjectPopupMenu::PopupType133GUIGLObjectPopupMenu::getPopupType() const {134return myPopupType;135}136137138long139GUIGLObjectPopupMenu::onCmdCenter(FXObject*, FXSelector, void*) {140// we already know where the object is since we clicked on it -> zoom on Boundary141if (myObject) {142myParent->centerTo(myObject->getGlID(), true, -1);143} else {144throw ProcessError("Object is NULL");145}146return 1;147}148149150long151GUIGLObjectPopupMenu::onCmdCopyName(FXObject*, FXSelector, void*) {152if (myObject) {153GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getMicrosimID());154} else {155throw ProcessError("Object is NULL");156}157return 1;158}159160161long162GUIGLObjectPopupMenu::onCmdCopyTypedName(FXObject*, FXSelector, void*) {163if (myObject) {164GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getFullName());165} else {166throw ProcessError("Object is NULL");167}168return 1;169}170171172long173GUIGLObjectPopupMenu::onCmdCopyEdgeName(FXObject*, FXSelector, void*) {174if (myObject == nullptr) {175throw ProcessError("Object is NULL");176} else if (myObject->getType() != GLO_LANE) {177throw ProcessError(TL("Object must be a lane"));178} else {179GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getParentName());180}181return 1;182}183184185long186GUIGLObjectPopupMenu::onCmdCopyTestCoordinates(FXObject*, FXSelector, void*) {187if (myObject) {188GUIUserIO::copyToClipboard(*myParent->getApp(), myTestCoordinates);189} else {190throw ProcessError("Object is NULL");191}192return 1;193}194195196long197GUIGLObjectPopupMenu::onCmdCopyCursorPosition(FXObject*, FXSelector, void*) {198GUIUserIO::copyToClipboard(*myParent->getApp(), toString(myNetworkPosition));199return 1;200}201202203long204GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition(FXObject*, FXSelector, void*) {205Position pos = myNetworkPosition;206GeoConvHelper::getFinal().cartesian2geo(pos);207// formatted for pasting into google maps208const std::string posString = toString(pos.y(), gPrecisionGeo) + ", " + toString(pos.x(), gPrecisionGeo);209GUIUserIO::copyToClipboard(*myParent->getApp(), posString);210return 1;211}212213214long215GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary(FXObject*, FXSelector, void*) {216const Boundary b = myParent->getVisibleBoundary();217Position lowLeft(b.xmin(), b.ymin());218GeoConvHelper::getFinal().cartesian2geo(lowLeft);219Position upRight(b.xmax(), b.ymax());220GeoConvHelper::getFinal().cartesian2geo(upRight);221// formatted for usage with osmconvert222const std::string posString = toString(lowLeft.x(), gPrecisionGeo) + "," + toString(lowLeft.y(), gPrecisionGeo) + "," +223toString(upRight.x(), gPrecisionGeo) + "," + toString(upRight.y(), gPrecisionGeo);224GUIUserIO::copyToClipboard(*myParent->getApp(), posString);225return 1;226}227228229long230GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline(FXObject* item, FXSelector, void*) {231FXMenuCommand* const mc = dynamic_cast<FXMenuCommand*>(item);232Position pos = myNetworkPosition;233GeoConvHelper::getFinal().cartesian2geo(pos);234std::string url = myApplication->getOnlineMaps().find(mc->getText().text())->second;235url = StringUtils::replace(StringUtils::replace(url, "%lat", toString(pos.y(), gPrecisionGeo)), "%lon", toString(pos.x(), gPrecisionGeo));236MFXLinkLabel::fxexecute(url.c_str());237return 1;238}239240241long242GUIGLObjectPopupMenu::onCmdShowPars(FXObject*, FXSelector, void*) {243if (myObject) {244myObject->getParameterWindow(*myApplication, *myParent);245} else {246throw ProcessError("Object is NULL");247}248return 1;249}250251252253long254GUIGLObjectPopupMenu::onCmdShowTypePars(FXObject*, FXSelector, void*) {255if (myObject) {256myObject->getTypeParameterWindow(*myApplication, *myParent);257} else {258throw ProcessError("Object is NULL");259}260return 1;261}262263264long265GUIGLObjectPopupMenu::onCmdAddSelected(FXObject*, FXSelector, void*) {266if (myObject) {267gSelected.select(myObject->getGlID());268myParent->update();269} else {270throw ProcessError("Object is NULL");271}272return 1;273}274275276long277GUIGLObjectPopupMenu::onCmdRemoveSelected(FXObject*, FXSelector, void*) {278if (myObject) {279gSelected.deselect(myObject->getGlID());280myParent->update();281} else {282throw ProcessError("Object is NULL");283}284return 1;285}286287288GUIGLObjectPopupMenu::GUIGLObjectPopupMenu() :289FXMenuPane(),290myParent(nullptr),291myObject(nullptr),292myApplication(nullptr),293myPopupType(PopupType::PROPERTIES) {294}295296/****************************************************************************/297298299