Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEPythonTool.cpp
Go to the documentation of this file.
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/****************************************************************************/
18// Python tools used in netedit
19/****************************************************************************/
20
29#include <xercesc/parsers/SAXParser.hpp>
30
31#include "GNEPythonTool.h"
32
33// ============================================-===============================
34// member method definitions
35// ===========================================================================
36
37GNEPythonTool::GNEPythonTool(GNEApplicationWindow* GNEApp, const std::string& toolPath,
38 const std::string& templateStr, FXMenuPane* menu) :
39 myGNEApp(GNEApp),
40 myToolPath(toolPath),
41 myPythonToolName(FileHelpers::getFileFromPath(toolPath, true)) {
42 // build menu command
45 // parse tool options
46 if (templateStr.size() > 0) {
47 try {
49 // make a copy (needed for reset)
51 } catch (ProcessError& e) {
52 WRITE_ERROR("Error parsing template of tool: " + myPythonToolName + " (" + e.what() + ")");
53 }
54 }
55}
56
57
59
60
63 return myGNEApp;
64}
65
66
67const std::string&
71
72
77
78
79FXMenuCommand*
83
84
85void
87 // nothing to do here, use in children
88}
89
90
91void
93 // nothing to do here, use in children
94}
95
96
97std::string
99 // add python script
100 const char* pythonEnv = getenv("PYTHON");
101 const std::string python = (pythonEnv == nullptr) ? "python" : pythonEnv;
102 const char* sumoHomeEnv = getenv("SUMO_HOME");
103 std::string sumoHome = "";
104 if (sumoHomeEnv != nullptr && sumoHomeEnv != std::string("")) {
105 sumoHome = std::string(sumoHomeEnv);
106 // harmonise slash
107 if (sumoHome.back() == '\\') {
108 sumoHome.pop_back();
109 }
110 if (sumoHome.back() != '/') {
111 sumoHome += "/";
112 }
113 // quote string to handle spaces but prevent double quotes
114 if (sumoHome.front() != '"') {
115 sumoHome = "\"" + sumoHome;
116 }
117 if (sumoHome.back() == '"') {
118 sumoHome.pop_back();
119 }
120 }
121 return python + " " + sumoHome + myToolPath + "\"";
122}
123
124
125std::string
127 std::string arguments;
128 // add arguments
129 for (const auto& option : myPythonToolsOptions) {
130 // only add modified values
131 if (!option.second->isDefault()) {
132 // for boolean values avoid use "true"
133 if (option.second->isBool()) {
134 arguments += ("--" + option.first + " ");
135 } else {
136 if (!option.second->isPositional()) {
137 arguments += ("--" + option.first + " ");
138 }
139 const std::string listSeparator = option.second->getListSeparator();
140 if (listSeparator != "") {
141 StringTokenizer st(option.second->getValueString(), " ", true);
142 bool first = true;
143 for (const std::string& v : st.getVector()) {
144 if (first) {
145 first = false;
146 } else {
147 arguments += listSeparator;
148 }
149 arguments += ("\"" + v + "\"");
150 }
151 arguments += " ";
152 } else {
153 arguments += ("\"" + StringUtils::escapeShell(option.second->getValueString()) + "\" ");
154 }
155 }
156 }
157 }
158 return getCommandPath() + " " + arguments;
159}
160
161
162const std::string
163GNEPythonTool::getDefaultValue(const std::string& name) const {
164 const auto value = myPythonToolsOptionsOriginal.getValueString(name);
165 // filter "none" values
166 if (value == "none") {
167 return "";
168 } else {
169 return value;
170 }
171}
172
173
174bool
175GNEPythonTool::loadConfiguration(const std::string& file) {
176 // make all options writable
178 // build parser
179 XERCES_CPP_NAMESPACE::SAXParser parser;
180 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
181 parser.setDisableDefaultEntityResolution(true);
182 // start the parsing
184 try {
185 parser.setDocumentHandler(&handler);
186 parser.setErrorHandler(&handler);
187 parser.parse(StringUtils::transcodeToLocal(file).c_str());
188 if (handler.errorOccurred()) {
189 WRITE_ERROR(TL("Could not load tool configuration '") + file + "'.");
190 return false;
191 }
192 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
193 WRITE_ERROR(TL("Could not load tool configuration '") + file + "':\n " + StringUtils::transcode(e.getMessage()));
194 return false;
195 }
196 // write info
197 WRITE_MESSAGE(TLF("Loaded % configuration.", myPythonToolName));
198 return true;
199}
200
201
202void
203GNEPythonTool::saveConfiguration(const std::string& file) const {
204 std::string command = getCommandPath() + " -C \"" + file + "\" ";
205 // add arguments
206 for (const auto& option : myPythonToolsOptions) {
207 // only write modified values
208 if (!option.second->isDefault()) {
209 if (option.second->isBool()) {
210 command += ("--" + option.first + " ");
211 } else {
212 command += ("--" + option.first + " \"" + StringUtils::escapeShell(option.second->getValueString()) + "\" ");
213 }
214 }
215 }
216 // start in background
217#ifndef WIN32
218 command = command + " &";
219#else
220 // see "help start" for the parameters
221 command = "start /B \"\" " + command;
222#endif
223 // write info
224 WRITE_MESSAGE(TLF("Saved % configuration.", myPythonToolName));
225 // yay! fun with dangerous commands... Never use this over the internet
227}
228
229/****************************************************************************/
@ MID_GNE_OPENPYTHONTOOLDIALOG
call tool
Definition GUIAppEnum.h:755
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
Functions for an easier usage of files and paths.
Definition FileHelpers.h:38
The main window of Netedit.
GNEPythonTool(GNEApplicationWindow *GNEApp, const std::string &toolPath, const std::string &templateStr, FXMenuPane *menu)
Constructor.
OptionsCont myPythonToolsOptionsOriginal
original tools options
FXMenuCommand * myMenuCommand
menu command associated with this tool
virtual std::string getCommand() const
get command (python + script + arguments)
GNEApplicationWindow * getGNEApp() const
get to GNEApplicationWindow
void saveConfiguration(const std::string &file) const
save configuration
bool loadConfiguration(const std::string &file)
load configuration
virtual void setCurrentValues()
set current values (used for set values like current folder and similar)
virtual ~GNEPythonTool()
destructor
const std::string getDefaultValue(const std::string &name) const
get default value of the given parameter
GNEApplicationWindow * myGNEApp
pointer to GNEApplicationWindow
std::string getCommandPath() const
get command (python + script)
const std::string & getToolName() const
get tool name
FXMenuCommand * getMenuCommand() const
get menu command
const std::string myPythonToolName
tool name
virtual void postProcessing()
execute post processing
OptionsCont & getToolsOptions()
get tools options
const std::string myToolPath
python tool path relative to SUMO_HOME
OptionsCont myPythonToolsOptions
tools options
static FXMenuCommand * buildFXMenuCommandShortcut(FXComposite *p, const std::string &text, const std::string &shortcut, const std::string &info, FXIcon *icon, FXObject *tgt, FXSelector sel)
build menu command
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
A storage for options typed value containers)
Definition OptionsCont.h:89
std::string getValueString(const std::string &name) const
Returns the string-value of the named option (all options)
void resetWritable()
Resets all options to be writeable.
A SAX-Handler for loading options.
bool errorOccurred() const
Returns the information whether an error occurred.
std::vector< std::string > getVector()
return vector of strings
static std::string escapeShell(const std::string &orig)
Escape special characters with backslash.
static std::string transcode(const XMLCh *const data)
converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8
static std::string transcodeToLocal(const std::string &utf8String)
convert a string from UTF-8 to the local codepage
static unsigned long runHiddenCommand(const std::string &cmd)
run a shell command without popping up any windows (particuarly on win32)
Definition SysUtils.cpp:69
static void parseTemplate(OptionsCont &options, const std::string &templateString)
run parser