Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 GUIGLObjectPopupMenu.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Sept 2002
19 : ///
20 : // The popup menu of a globject
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <iostream>
25 : #include <cassert>
26 : #include <utils/common/StringTokenizer.h>
27 : #include <utils/common/StringUtils.h>
28 : #include <utils/geom/GeoConvHelper.h>
29 : #include <utils/gui/windows/GUISUMOAbstractView.h>
30 : #include <utils/gui/globjects/GUIGlObject.h>
31 : #include <utils/gui/windows/GUIAppEnum.h>
32 : #include <utils/gui/windows/GUIMainWindow.h>
33 : #include <utils/gui/div/GUIParameterTableWindow.h>
34 : #include <utils/gui/div/GUIGlobalSelection.h>
35 : #include <utils/gui/div/GUIUserIO.h>
36 : #include <utils/common/ToString.h>
37 : #include "GUIGLObjectPopupMenu.h"
38 : #include <utils/foxtools/MFXLinkLabel.h>
39 :
40 : // ===========================================================================
41 : // FOX callback mapping
42 : // ===========================================================================
43 : FXDEFMAP(GUIGLObjectPopupMenu) GUIGLObjectPopupMenuMap[] = {
44 : FXMAPFUNC(SEL_COMMAND, MID_CENTER, GUIGLObjectPopupMenu::onCmdCenter),
45 : FXMAPFUNC(SEL_COMMAND, MID_COPY_NAME, GUIGLObjectPopupMenu::onCmdCopyName),
46 : FXMAPFUNC(SEL_COMMAND, MID_COPY_TYPED_NAME, GUIGLObjectPopupMenu::onCmdCopyTypedName),
47 : FXMAPFUNC(SEL_COMMAND, MID_COPY_EDGE_NAME, GUIGLObjectPopupMenu::onCmdCopyEdgeName),
48 : FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_POSITION, GUIGLObjectPopupMenu::onCmdCopyCursorPosition),
49 : FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_GEOPOSITION, GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition),
50 : FXMAPFUNC(SEL_COMMAND, MID_COPY_VIEW_GEOBOUNDARY, GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary),
51 : FXMAPFUNC(SEL_COMMAND, MID_SHOW_GEOPOSITION_ONLINE, GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline),
52 : FXMAPFUNC(SEL_COMMAND, MID_SHOWPARS, GUIGLObjectPopupMenu::onCmdShowPars),
53 : FXMAPFUNC(SEL_COMMAND, MID_SHOWTYPEPARS, GUIGLObjectPopupMenu::onCmdShowTypePars),
54 : FXMAPFUNC(SEL_COMMAND, MID_ADDSELECT, GUIGLObjectPopupMenu::onCmdAddSelected),
55 : FXMAPFUNC(SEL_COMMAND, MID_REMOVESELECT, GUIGLObjectPopupMenu::onCmdRemoveSelected)
56 : };
57 :
58 : // Object implementation
59 0 : FXIMPLEMENT(GUIGLObjectPopupMenu, FXMenuPane, GUIGLObjectPopupMenuMap, ARRAYNUMBER(GUIGLObjectPopupMenuMap))
60 :
61 :
62 : // ===========================================================================
63 : // method definitions
64 : // ===========================================================================
65 :
66 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject& o) :
67 : FXMenuPane(&parent),
68 0 : myParent(&parent),
69 0 : myObject(&o),
70 0 : myApplication(&app),
71 0 : myPopupType(PopupType::ATTRIBUTES),
72 0 : myNetworkPosition(parent.getPositionInformation()) {
73 0 : }
74 :
75 :
76 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow* app, GUISUMOAbstractView* parent, PopupType popupType) :
77 : FXMenuPane(parent),
78 0 : myParent(parent),
79 0 : myObject(nullptr),
80 0 : myApplication(app),
81 0 : myPopupType(popupType),
82 0 : myNetworkPosition(parent->getPositionInformation()) {
83 0 : }
84 :
85 :
86 0 : GUIGLObjectPopupMenu::~GUIGLObjectPopupMenu() {
87 : // Delete MenuPane children
88 0 : for (const auto& pane : myMenuPanes) {
89 0 : delete pane;
90 : }
91 0 : }
92 :
93 :
94 : void
95 0 : GUIGLObjectPopupMenu::insertMenuPaneChild(FXMenuPane* child) {
96 : // Check that MenuPaneChild isn't NULL
97 0 : if (child == nullptr) {
98 0 : throw ProcessError("MenuPaneChild cannot be NULL");
99 : }
100 : // Check that MenuPaneChild wasn't already inserted
101 0 : for (const auto& pane : myMenuPanes) {
102 0 : if (pane == child) {
103 0 : throw ProcessError("MenuPaneChild already inserted");
104 : }
105 : }
106 : // Insert MenuPaneChild
107 0 : myMenuPanes.push_back(child);
108 0 : }
109 :
110 :
111 : void
112 0 : GUIGLObjectPopupMenu::removePopupFromObject() {
113 : // remove popup menu from object
114 0 : if (myObject) {
115 0 : myObject->removedPopupMenu();
116 : }
117 0 : }
118 :
119 : GUISUMOAbstractView*
120 0 : GUIGLObjectPopupMenu::getParentView() {
121 0 : return myParent;
122 : }
123 :
124 :
125 : GUIGLObjectPopupMenu::PopupType
126 0 : GUIGLObjectPopupMenu::getPopupType() const {
127 0 : return myPopupType;
128 : }
129 :
130 :
131 : long
132 0 : GUIGLObjectPopupMenu::onCmdCenter(FXObject*, FXSelector, void*) {
133 : // we already know where the object is since we clicked on it -> zoom on Boundary
134 0 : if (myObject) {
135 0 : myParent->centerTo(myObject->getGlID(), true, -1);
136 : } else {
137 0 : throw ProcessError("Object is NULL");
138 : }
139 0 : return 1;
140 : }
141 :
142 :
143 : long
144 0 : GUIGLObjectPopupMenu::onCmdCopyName(FXObject*, FXSelector, void*) {
145 0 : if (myObject) {
146 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getMicrosimID());
147 : } else {
148 0 : throw ProcessError("Object is NULL");
149 : }
150 0 : return 1;
151 : }
152 :
153 :
154 : long
155 0 : GUIGLObjectPopupMenu::onCmdCopyTypedName(FXObject*, FXSelector, void*) {
156 0 : if (myObject) {
157 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getFullName());
158 : } else {
159 0 : throw ProcessError("Object is NULL");
160 : }
161 0 : return 1;
162 : }
163 :
164 :
165 : long
166 0 : GUIGLObjectPopupMenu::onCmdCopyEdgeName(FXObject*, FXSelector, void*) {
167 0 : if (myObject == nullptr) {
168 0 : throw ProcessError("Object is NULL");
169 0 : } else if (myObject->getType() != GLO_LANE) {
170 0 : throw ProcessError(TL("Object must be a lane"));
171 : } else {
172 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getParentName());
173 : }
174 0 : return 1;
175 : }
176 :
177 :
178 : long
179 0 : GUIGLObjectPopupMenu::onCmdCopyCursorPosition(FXObject*, FXSelector, void*) {
180 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), toString(myNetworkPosition));
181 0 : return 1;
182 : }
183 :
184 :
185 : long
186 0 : GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition(FXObject*, FXSelector, void*) {
187 0 : Position pos = myNetworkPosition;
188 0 : GeoConvHelper::getFinal().cartesian2geo(pos);
189 : // formatted for pasting into google maps
190 0 : const std::string posString = toString(pos.y(), gPrecisionGeo) + ", " + toString(pos.x(), gPrecisionGeo);
191 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), posString);
192 0 : return 1;
193 : }
194 :
195 :
196 : long
197 0 : GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary(FXObject*, FXSelector, void*) {
198 0 : const Boundary b = myParent->getVisibleBoundary();
199 0 : Position lowLeft(b.xmin(), b.ymin());
200 0 : GeoConvHelper::getFinal().cartesian2geo(lowLeft);
201 0 : Position upRight(b.xmax(), b.ymax());
202 0 : GeoConvHelper::getFinal().cartesian2geo(upRight);
203 : // formatted for usage with osmconvert
204 0 : const std::string posString = toString(lowLeft.x(), gPrecisionGeo) + "," + toString(lowLeft.y(), gPrecisionGeo) + "," +
205 0 : toString(upRight.x(), gPrecisionGeo) + "," + toString(upRight.y(), gPrecisionGeo);
206 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), posString);
207 0 : return 1;
208 0 : }
209 :
210 :
211 : long
212 0 : GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline(FXObject* item, FXSelector, void*) {
213 0 : FXMenuCommand* const mc = dynamic_cast<FXMenuCommand*>(item);
214 0 : Position pos = myNetworkPosition;
215 0 : GeoConvHelper::getFinal().cartesian2geo(pos);
216 0 : std::string url = myApplication->getOnlineMaps().find(mc->getText().text())->second;
217 0 : url = StringUtils::replace(StringUtils::replace(url, "%lat", toString(pos.y(), gPrecisionGeo)), "%lon", toString(pos.x(), gPrecisionGeo));
218 0 : MFXLinkLabel::fxexecute(url.c_str());
219 0 : return 1;
220 : }
221 :
222 :
223 : long
224 0 : GUIGLObjectPopupMenu::onCmdShowPars(FXObject*, FXSelector, void*) {
225 0 : if (myObject) {
226 0 : myObject->getParameterWindow(*myApplication, *myParent);
227 : } else {
228 0 : throw ProcessError("Object is NULL");
229 : }
230 0 : return 1;
231 : }
232 :
233 :
234 :
235 : long
236 0 : GUIGLObjectPopupMenu::onCmdShowTypePars(FXObject*, FXSelector, void*) {
237 0 : if (myObject) {
238 0 : myObject->getTypeParameterWindow(*myApplication, *myParent);
239 : } else {
240 0 : throw ProcessError("Object is NULL");
241 : }
242 0 : return 1;
243 : }
244 :
245 :
246 : long
247 0 : GUIGLObjectPopupMenu::onCmdAddSelected(FXObject*, FXSelector, void*) {
248 0 : if (myObject) {
249 0 : gSelected.select(myObject->getGlID());
250 0 : myParent->update();
251 : } else {
252 0 : throw ProcessError("Object is NULL");
253 : }
254 0 : return 1;
255 : }
256 :
257 :
258 : long
259 0 : GUIGLObjectPopupMenu::onCmdRemoveSelected(FXObject*, FXSelector, void*) {
260 0 : if (myObject) {
261 0 : gSelected.deselect(myObject->getGlID());
262 0 : myParent->update();
263 : } else {
264 0 : throw ProcessError("Object is NULL");
265 : }
266 0 : return 1;
267 : }
268 :
269 :
270 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu() :
271 : FXMenuPane(),
272 0 : myParent(nullptr),
273 0 : myObject(nullptr),
274 0 : myApplication(nullptr),
275 0 : myPopupType(PopupType::PROPERTIES) {
276 0 : }
277 :
278 : /****************************************************************************/
|