#include <netedit/GNEApplicationWindow.h>
#include <utils/common/FileHelpers.h>
#include <utils/common/MsgHandler.h>
#include <utils/common/SysUtils.h>
#include <utils/common/StringTokenizer.h>
#include <utils/gui/div/GUIDesigns.h>
#include <utils/handlers/TemplateHandler.h>
#include <utils/options/OptionsLoader.h>
#include <xercesc/parsers/SAXParser.hpp>
#include "GNEPythonTool.h"
GNEPythonTool::GNEPythonTool(GNEApplicationWindow* applicationWindow, const std::string& toolPath,
const std::string& templateStr, FXMenuPane* menu) :
myApplicationWindow(applicationWindow),
myToolPath(toolPath),
myPythonToolName(FileHelpers::getFileFromPath(toolPath, true)) {
myMenuCommand = GUIDesigns::buildFXMenuCommandShortcut(menu, myPythonToolName, "", TL("Execute python tool '") + myPythonToolName + "'.",
GUIIconSubSys::getIcon(GUIIcon::TOOL_PYTHON), applicationWindow, MID_GNE_OPENPYTHONTOOLDIALOG);
if (templateStr.size() > 0) {
try {
TemplateHandler::parseTemplate(myPythonToolsOptions, templateStr);
TemplateHandler::parseTemplate(myPythonToolsOptionsOriginal, templateStr);
} catch (ProcessError& e) {
WRITE_ERROR("Error parsing template of tool: " + myPythonToolName + " (" + e.what() + ")");
}
}
}
GNEPythonTool::~GNEPythonTool() {}
const std::string&
GNEPythonTool::getToolName() const {
return myPythonToolName;
}
OptionsCont&
GNEPythonTool::getToolsOptions() {
return myPythonToolsOptions;
}
FXMenuCommand*
GNEPythonTool::getMenuCommand() const {
return myMenuCommand;
}
void
GNEPythonTool::setCurrentValues() {
}
void
GNEPythonTool::postProcessing() {
}
std::string
GNEPythonTool::getCommandPath() const {
const char* pythonEnv = getenv("PYTHON");
const std::string python = (pythonEnv == nullptr) ? "python" : pythonEnv;
const char* sumoHomeEnv = getenv("SUMO_HOME");
std::string sumoHome = "";
if (sumoHomeEnv != nullptr && sumoHomeEnv != std::string("")) {
sumoHome = std::string(sumoHomeEnv);
if (sumoHome.back() == '\\') {
sumoHome.pop_back();
}
if (sumoHome.back() != '/') {
sumoHome += "/";
}
if (sumoHome.front() != '"') {
sumoHome = "\"" + sumoHome;
}
if (sumoHome.back() == '"') {
sumoHome.pop_back();
}
}
return python + " " + sumoHome + myToolPath + "\"";
}
std::string
GNEPythonTool::getCommand() const {
std::string arguments;
for (const auto& option : myPythonToolsOptions) {
if (!option.second->isDefault()) {
if (option.second->isBool()) {
arguments += ("--" + option.first + " ");
} else {
if (!option.second->isPositional()) {
arguments += ("--" + option.first + " ");
}
const std::string listSeparator = option.second->getListSeparator();
if (listSeparator != "") {
StringTokenizer st(option.second->getValueString(), " ", true);
bool first = true;
for (const std::string& v : st.getVector()) {
if (first) {
first = false;
} else {
arguments += listSeparator;
}
arguments += ("\"" + v + "\"");
}
arguments += " ";
} else {
arguments += ("\"" + StringUtils::escapeShell(option.second->getValueString()) + "\" ");
}
}
}
}
return getCommandPath() + " " + arguments;
}
const std::string
GNEPythonTool::getDefaultValue(const std::string& name) const {
const auto value = myPythonToolsOptionsOriginal.getValueString(name);
if (value == "none") {
return "";
} else {
return value;
}
}
bool
GNEPythonTool::loadConfiguration(const std::string& file) {
myPythonToolsOptions.resetWritable();
XERCES_CPP_NAMESPACE::SAXParser parser;
parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
parser.setDisableDefaultEntityResolution(true);
OptionsLoader handler(myPythonToolsOptions);
try {
parser.setDocumentHandler(&handler);
parser.setErrorHandler(&handler);
parser.parse(StringUtils::transcodeToLocal(file).c_str());
if (handler.errorOccurred()) {
WRITE_ERROR(TL("Could not load tool configuration '") + file + "'.");
return false;
}
} catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
WRITE_ERROR(TL("Could not load tool configuration '") + file + "':\n " + StringUtils::transcode(e.getMessage()));
return false;
}
WRITE_MESSAGE(TLF("Loaded % configuration.", myPythonToolName));
return true;
}
void
GNEPythonTool::saveConfiguration(const std::string& file) const {
std::string command = getCommand() + " -C \"" + file + "\" ";
#ifndef WIN32
command = command + " &";
#else
command = "start /B \"\" " + command;
#endif
WRITE_MESSAGE(TLF("Saved % configuration.", myPythonToolName));
SysUtils::runHiddenCommand(command);
}