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_TEST_COORDINATES, GUIGLObjectPopupMenu::onCmdCopyTestCoordinates),
49 : FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_POSITION, GUIGLObjectPopupMenu::onCmdCopyCursorPosition),
50 : FXMAPFUNC(SEL_COMMAND, MID_COPY_CURSOR_GEOPOSITION, GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition),
51 : FXMAPFUNC(SEL_COMMAND, MID_COPY_VIEW_GEOBOUNDARY, GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary),
52 : FXMAPFUNC(SEL_COMMAND, MID_SHOW_GEOPOSITION_ONLINE, GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline),
53 : FXMAPFUNC(SEL_COMMAND, MID_SHOWPARS, GUIGLObjectPopupMenu::onCmdShowPars),
54 : FXMAPFUNC(SEL_COMMAND, MID_SHOWTYPEPARS, GUIGLObjectPopupMenu::onCmdShowTypePars),
55 : FXMAPFUNC(SEL_COMMAND, MID_ADDSELECT, GUIGLObjectPopupMenu::onCmdAddSelected),
56 : FXMAPFUNC(SEL_COMMAND, MID_REMOVESELECT, GUIGLObjectPopupMenu::onCmdRemoveSelected)
57 : };
58 :
59 : // Object implementation
60 0 : FXIMPLEMENT(GUIGLObjectPopupMenu, FXMenuPane, GUIGLObjectPopupMenuMap, ARRAYNUMBER(GUIGLObjectPopupMenuMap))
61 :
62 :
63 : // ===========================================================================
64 : // method definitions
65 : // ===========================================================================
66 :
67 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject& o) :
68 : FXMenuPane(&parent),
69 0 : myParent(&parent),
70 0 : myObject(&o),
71 0 : myApplication(&app),
72 0 : myPopupType(PopupType::ATTRIBUTES),
73 0 : myNetworkPosition(parent.getPositionInformation()),
74 0 : myTestCoordinates((toString(parent.getWindowCursorPosition().x() - 24.0) + " " + toString(parent.getWindowCursorPosition().y() - 25.0))) {
75 0 : }
76 :
77 :
78 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu(GUIMainWindow* app, GUISUMOAbstractView* parent, PopupType popupType) :
79 : FXMenuPane(parent),
80 0 : myParent(parent),
81 0 : myObject(nullptr),
82 0 : myApplication(app),
83 0 : myPopupType(popupType),
84 0 : myNetworkPosition(parent->getPositionInformation()) {
85 0 : }
86 :
87 :
88 0 : GUIGLObjectPopupMenu::~GUIGLObjectPopupMenu() {
89 : // Delete MenuPane children
90 0 : for (const auto& pane : myMenuPanes) {
91 0 : delete pane;
92 : }
93 0 : }
94 :
95 :
96 : void
97 0 : GUIGLObjectPopupMenu::insertMenuPaneChild(FXMenuPane* child) {
98 : // Check that MenuPaneChild isn't NULL
99 0 : if (child == nullptr) {
100 0 : throw ProcessError("MenuPaneChild cannot be NULL");
101 : }
102 : // Check that MenuPaneChild wasn't already inserted
103 0 : for (const auto& pane : myMenuPanes) {
104 0 : if (pane == child) {
105 0 : throw ProcessError("MenuPaneChild already inserted");
106 : }
107 : }
108 : // Insert MenuPaneChild
109 0 : myMenuPanes.push_back(child);
110 0 : }
111 :
112 :
113 : void
114 0 : GUIGLObjectPopupMenu::removePopupFromObject() {
115 : // remove popup menu from object
116 0 : if (myObject) {
117 0 : myObject->removedPopupMenu();
118 : }
119 0 : }
120 :
121 : GUISUMOAbstractView*
122 0 : GUIGLObjectPopupMenu::getParentView() {
123 0 : return myParent;
124 : }
125 :
126 :
127 : GUIGLObjectPopupMenu::PopupType
128 0 : GUIGLObjectPopupMenu::getPopupType() const {
129 0 : return myPopupType;
130 : }
131 :
132 :
133 : long
134 0 : GUIGLObjectPopupMenu::onCmdCenter(FXObject*, FXSelector, void*) {
135 : // we already know where the object is since we clicked on it -> zoom on Boundary
136 0 : if (myObject) {
137 0 : myParent->centerTo(myObject->getGlID(), true, -1);
138 : } else {
139 0 : throw ProcessError("Object is NULL");
140 : }
141 0 : return 1;
142 : }
143 :
144 :
145 : long
146 0 : GUIGLObjectPopupMenu::onCmdCopyName(FXObject*, FXSelector, void*) {
147 0 : if (myObject) {
148 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getMicrosimID());
149 : } else {
150 0 : throw ProcessError("Object is NULL");
151 : }
152 0 : return 1;
153 : }
154 :
155 :
156 : long
157 0 : GUIGLObjectPopupMenu::onCmdCopyTypedName(FXObject*, FXSelector, void*) {
158 0 : if (myObject) {
159 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getFullName());
160 : } else {
161 0 : throw ProcessError("Object is NULL");
162 : }
163 0 : return 1;
164 : }
165 :
166 :
167 : long
168 0 : GUIGLObjectPopupMenu::onCmdCopyEdgeName(FXObject*, FXSelector, void*) {
169 0 : if (myObject == nullptr) {
170 0 : throw ProcessError("Object is NULL");
171 0 : } else if (myObject->getType() != GLO_LANE) {
172 0 : throw ProcessError(TL("Object must be a lane"));
173 : } else {
174 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myObject->getParentName());
175 : }
176 0 : return 1;
177 : }
178 :
179 :
180 : long
181 0 : GUIGLObjectPopupMenu::onCmdCopyTestCoordinates(FXObject*, FXSelector, void*) {
182 0 : if (myObject) {
183 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), myTestCoordinates);
184 : } else {
185 0 : throw ProcessError("Object is NULL");
186 : }
187 0 : return 1;
188 : }
189 :
190 :
191 : long
192 0 : GUIGLObjectPopupMenu::onCmdCopyCursorPosition(FXObject*, FXSelector, void*) {
193 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), toString(myNetworkPosition));
194 0 : return 1;
195 : }
196 :
197 :
198 : long
199 0 : GUIGLObjectPopupMenu::onCmdCopyCursorGeoPosition(FXObject*, FXSelector, void*) {
200 0 : Position pos = myNetworkPosition;
201 0 : GeoConvHelper::getFinal().cartesian2geo(pos);
202 : // formatted for pasting into google maps
203 0 : const std::string posString = toString(pos.y(), gPrecisionGeo) + ", " + toString(pos.x(), gPrecisionGeo);
204 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), posString);
205 0 : return 1;
206 : }
207 :
208 :
209 : long
210 0 : GUIGLObjectPopupMenu::onCmdCopyViewGeoBoundary(FXObject*, FXSelector, void*) {
211 0 : const Boundary b = myParent->getVisibleBoundary();
212 0 : Position lowLeft(b.xmin(), b.ymin());
213 0 : GeoConvHelper::getFinal().cartesian2geo(lowLeft);
214 0 : Position upRight(b.xmax(), b.ymax());
215 0 : GeoConvHelper::getFinal().cartesian2geo(upRight);
216 : // formatted for usage with osmconvert
217 0 : const std::string posString = toString(lowLeft.x(), gPrecisionGeo) + "," + toString(lowLeft.y(), gPrecisionGeo) + "," +
218 0 : toString(upRight.x(), gPrecisionGeo) + "," + toString(upRight.y(), gPrecisionGeo);
219 0 : GUIUserIO::copyToClipboard(*myParent->getApp(), posString);
220 0 : return 1;
221 0 : }
222 :
223 :
224 : long
225 0 : GUIGLObjectPopupMenu::onCmdShowCursorGeoPositionOnline(FXObject* item, FXSelector, void*) {
226 0 : FXMenuCommand* const mc = dynamic_cast<FXMenuCommand*>(item);
227 0 : Position pos = myNetworkPosition;
228 0 : GeoConvHelper::getFinal().cartesian2geo(pos);
229 0 : std::string url = myApplication->getOnlineMaps().find(mc->getText().text())->second;
230 0 : url = StringUtils::replace(StringUtils::replace(url, "%lat", toString(pos.y(), gPrecisionGeo)), "%lon", toString(pos.x(), gPrecisionGeo));
231 0 : MFXLinkLabel::fxexecute(url.c_str());
232 0 : return 1;
233 : }
234 :
235 :
236 : long
237 0 : GUIGLObjectPopupMenu::onCmdShowPars(FXObject*, FXSelector, void*) {
238 0 : if (myObject) {
239 0 : myObject->getParameterWindow(*myApplication, *myParent);
240 : } else {
241 0 : throw ProcessError("Object is NULL");
242 : }
243 0 : return 1;
244 : }
245 :
246 :
247 :
248 : long
249 0 : GUIGLObjectPopupMenu::onCmdShowTypePars(FXObject*, FXSelector, void*) {
250 0 : if (myObject) {
251 0 : myObject->getTypeParameterWindow(*myApplication, *myParent);
252 : } else {
253 0 : throw ProcessError("Object is NULL");
254 : }
255 0 : return 1;
256 : }
257 :
258 :
259 : long
260 0 : GUIGLObjectPopupMenu::onCmdAddSelected(FXObject*, FXSelector, void*) {
261 0 : if (myObject) {
262 0 : gSelected.select(myObject->getGlID());
263 0 : myParent->update();
264 : } else {
265 0 : throw ProcessError("Object is NULL");
266 : }
267 0 : return 1;
268 : }
269 :
270 :
271 : long
272 0 : GUIGLObjectPopupMenu::onCmdRemoveSelected(FXObject*, FXSelector, void*) {
273 0 : if (myObject) {
274 0 : gSelected.deselect(myObject->getGlID());
275 0 : myParent->update();
276 : } else {
277 0 : throw ProcessError("Object is NULL");
278 : }
279 0 : return 1;
280 : }
281 :
282 :
283 0 : GUIGLObjectPopupMenu::GUIGLObjectPopupMenu() :
284 : FXMenuPane(),
285 0 : myParent(nullptr),
286 0 : myObject(nullptr),
287 0 : myApplication(nullptr),
288 0 : myPopupType(PopupType::PROPERTIES) {
289 0 : }
290 :
291 : /****************************************************************************/
|