Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEOptionsDialog.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// A Dialog for setting options (see OptionsCont)
19/****************************************************************************/
20#include <config.h>
21
22#include <algorithm>
23#include <fstream>
32#include <xercesc/parsers/SAXParser.hpp>
34#include <netedit/GNEViewNet.h>
36
37#include "GNEOptionsDialog.h"
38
39#define TREELISTWIDTH 200
40
41// ===========================================================================
42// FOX callback mapping
43// ===========================================================================
44
57
58// Object implementation
59FXIMPLEMENT(GNEOptionsDialog, FXDialogBox, GUIDialogOptionsMap, ARRAYNUMBER(GUIDialogOptionsMap))
60
61// ===========================================================================
62// method definitions
63// ===========================================================================
64
65std::pair<int, bool>
66GNEOptionsDialog::Options(GNEApplicationWindow* GNEApp, GUIIcon icon, OptionsCont& optionsContainer, const OptionsCont& originalOptionsContainer, const char* titleName) {
67 GNEOptionsDialog* optionsDialog = new GNEOptionsDialog(GNEApp, icon, optionsContainer, originalOptionsContainer, titleName, false);
68 auto result = std::make_pair(optionsDialog->execute(), optionsDialog->myOptionsModified);
69 delete optionsDialog;
70 return result;
71}
72
73
74std::pair<int, bool>
75GNEOptionsDialog::Run(GNEApplicationWindow* GNEApp, GUIIcon icon, OptionsCont& optionsContainer, const OptionsCont& originalOptionsContainer, const char* titleName) {
76 GNEOptionsDialog* optionsDialog = new GNEOptionsDialog(GNEApp, icon, optionsContainer, originalOptionsContainer, titleName, true);
77 auto result = std::make_pair(optionsDialog->execute(), optionsDialog->myOptionsModified);
78 delete optionsDialog;
79 return result;
80}
81
82
84
85
86long
87GNEOptionsDialog::onCmdCancel(FXObject*, FXSelector, void*) {
88 // reset entries
89 for (const auto& entry : myInputOptionEntries) {
90 entry->onCmdResetOption(nullptr, 0, nullptr);
91 }
92 // close dialog canceling changes
93 return handle(this, FXSEL(SEL_COMMAND, ID_CANCEL), nullptr);
94}
95
96
97long
98GNEOptionsDialog::onCmdReset(FXObject*, FXSelector, void*) {
99 // reset entries
100 for (const auto& entry : myInputOptionEntries) {
101 entry->onCmdResetOption(nullptr, 0, nullptr);
102 }
103 return 1;
104}
105
106
107long
108GNEOptionsDialog::onCmdRunNetgenerate(FXObject*, FXSelector, void*) {
109 // close dialog accepting changes
110 handle(this, FXSEL(SEL_COMMAND, ID_ACCEPT), nullptr);
111 // run tool in mainWindow
112 return myGNEApp->handle(this, FXSEL(SEL_COMMAND, MID_GNE_RUNNETGENERATE), nullptr);
113}
114
115
116long
117GNEOptionsDialog::onCmdSelectTopic(FXObject*, FXSelector, void*) {
118 if (mySearchButton->getText().count() == 0) {
120 }
121 return 1;
122}
123
124
125long
126GNEOptionsDialog::onCmdSearch(FXObject*, FXSelector, void*) {
127 if (mySearchButton->getText().count() > 0) {
129 } else {
131 }
132 return 1;
133}
134
135
136long
137GNEOptionsDialog::onCmdShowToolTipsMenu(FXObject*, FXSelector, void*) {
138 // toggle check
140 if (myGNEApp->getViewNet()) {
143 }
144 // enable/disable static tooltip
146 // save in registry
147 getApp()->reg().writeIntEntry("gui", "menuToolTips", myShowToolTipsMenu->amChecked() ? 0 : 1);
148 update();
149
150 return 1;
151}
152
153
154long
155GNEOptionsDialog::onCmdSaveOptions(FXObject*, FXSelector, void*) {
156 // open save dialog
157 const std::string file = GNEApplicationWindowHelper::openOptionFileDialog(this, true);
158 // check file
159 if (file.size() > 0) {
160 std::ofstream out(StringUtils::transcodeToLocal(file));
161 myOptionsContainer.writeConfiguration(out, true, false, false, file, true);
162 out.close();
163 }
164 return 1;
165}
166
167
168long
169GNEOptionsDialog::onCmdLoadOptions(FXObject*, FXSelector, void*) {
170 // open file dialog
171 const std::string file = GNEApplicationWindowHelper::openOptionFileDialog(this, false);
172 // check file
173 if ((file.size() > 0) && loadConfiguration(file)) {
174 // update entries
175 for (const auto& entry : myInputOptionEntries) {
176 entry->updateOption();
177 }
178 }
179 return 1;
180}
181
182
183long
184GNEOptionsDialog::onCmdResetDefault(FXObject*, FXSelector, void*) {
185 // restore entries
186 for (const auto& entry : myInputOptionEntries) {
187 entry->restoreOption();
188 }
189 return 1;
190}
191
192
194 myGNEApp(nullptr),
195 myOptionsContainer(OptionsCont::EMPTY_OPTIONS),
196 myOriginalOptionsContainer(OptionsCont::EMPTY_OPTIONS) {
197}
198
199
200bool
202 // iterate over tree elements and get the selected item
203 for (const auto& treeItemTopic : myTreeItemTopics) {
204 if (treeItemTopic.first->isSelected()) {
205 // iterate over entries
206 for (const auto& entry : myInputOptionEntries) {
207 if (entry->getTopic() == treeItemTopic.second) {
208 entry->show();
209 } else {
210 entry->hide();
211 }
212 }
213 myEntriesFrame->recalc();
214 myEntriesFrame->update();
215 return true;
216 }
217 }
218 // no topic selected, then show all
219 for (const auto& entry : myInputOptionEntries) {
220 entry->show();
221 }
222 myEntriesFrame->recalc();
223 myEntriesFrame->update();
224 return true;
225}
226
227
228void
230 // first lower case search text
231 searchText = StringUtils::to_lower_case(searchText);
232 // iterate over entries
233 for (const auto& entry : myInputOptionEntries) {
234 if (searchText.empty()) {
235 // show all entries if searchText is empty
236 entry->show();
237 } else if (entry->getNameLower().find(searchText) != std::string::npos) {
238 entry->show();
239 } else if ((myDescriptionSearchCheckButton->getCheck() == TRUE) &&
240 (entry->getDescriptionLower().find(searchText) != std::string::npos)) {
241 entry->show();
242 } else {
243 entry->hide();
244 }
245 }
246 myEntriesFrame->recalc();
247 myEntriesFrame->update();
248}
249
250
251bool
252GNEOptionsDialog::loadConfiguration(const std::string& file) {
253 // make all options writable
255 // build parser
256 XERCES_CPP_NAMESPACE::SAXParser parser;
257 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
258 parser.setDisableDefaultEntityResolution(true);
259 // start the parsing
261 try {
262 parser.setDocumentHandler(&handler);
263 parser.setErrorHandler(&handler);
264 parser.parse(StringUtils::transcodeToLocal(file).c_str());
265 if (handler.errorOccurred()) {
266 WRITE_ERROR(TL("Could not load configuration '") + file + "'.");
267 return false;
268 }
269 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
270 WRITE_ERROR(TL("Could not load tool configuration '") + file + "':\n " + StringUtils::transcode(e.getMessage()));
271 return false;
272 }
273 // write info
274 WRITE_MESSAGE(TL("Loaded configuration."));
275 return true;
276}
277
278
280 const OptionsCont& originalOptionsContainer, const char* titleName, const bool runDialog) :
281 FXDialogBox(GNEApp, titleName, GUIDesignDialogBoxExplicitStretchable(800, 600)),
282 myGNEApp(GNEApp),
283 myOptionsContainer(optionsContainer),
284 myOriginalOptionsContainer(originalOptionsContainer) {
285 // set icon
286 setIcon(GUIIconSubSys::getIcon(icon));
287 // create content frame
288 FXVerticalFrame* contentFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);
289 // add buttons frame
290 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(contentFrame, GUIDesignHorizontalFrameNoPadding);
291 myShowToolTipsMenu = new MFXCheckableButton(false, buttonsFrame,
292 myGNEApp->getStaticTooltipMenu(), (std::string("\t") + TL("Toggle Menu Tooltips") + std::string("\t") + TL("Toggles whether tooltips in the menu shall be shown.")).c_str(),
294 auto saveFile = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Save options"),
296 saveFile->setTipText(TL("Save configuration file"));
297 auto loadFile = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Load options"),
299 loadFile->setTipText(TL("Load configuration file"));
300 auto resetDefault = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Default options"),
302 resetDefault->setTipText(TL("Reset all options to default"));
303 // add separator
304 new FXSeparator(contentFrame);
305 // create elements frame
306 FXHorizontalFrame* elementsFrame = new FXHorizontalFrame(contentFrame, GUIDesignAuxiliarFrame);
307 FXVerticalFrame* elementsFrameTree = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarVerticalFrame);
308 FXVerticalFrame* elementsFrameValues = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarFrame);
309 // Create GroupBox modules
310 MFXGroupBoxModule* groupBoxTree = new MFXGroupBoxModule(elementsFrameTree, TL("Topics"));
311 MFXGroupBoxModule* groupBoxOptions = new MFXGroupBoxModule(elementsFrameValues, TL("Options"));
312 // create FXTreeList
313 myTopicsTreeList = new FXTreeList(groupBoxTree->getCollapsableFrame(), this, MID_GNE_SELECT, GUIDesignTreeListFixedWidth);
315 // add root item
316 myRootItem = myTopicsTreeList->appendItem(nullptr, titleName);
317 myRootItem->setExpanded(TRUE);
318 // create scroll
319 FXScrollWindow* scrollTabEntries = new FXScrollWindow(groupBoxOptions->getCollapsableFrame(), LAYOUT_FILL_X | LAYOUT_FILL_Y);
320 // create vertical frame for entries
321 myEntriesFrame = new FXVerticalFrame(scrollTabEntries, GUIDesignAuxiliarFrame);
322 // iterate over all topics
323 for (const auto& topic : myOptionsContainer.getSubTopics()) {
324 // check if we have to ignore this topic
325 if (myIgnoredTopics.count(topic) == 0) {
326 // add topic into myTreeItemTopics and tree
327 myTreeItemTopics[myTopicsTreeList->appendItem(myRootItem, topic.c_str())] = topic;
328 // iterate over entries
329 const std::vector<std::string> entries = myOptionsContainer.getSubTopicsEntries(topic);
330 for (const auto& entry : entries) {
331 // check if we have to ignore this entry
332 if (myIgnoredEntries.count(entry) == 0) {
333 // get type
334 const std::string type = myOptionsContainer.getTypeName(entry);
335 // get description
336 const std::string description = myOptionsContainer.getDescription(entry);
337 // get default value
338 const std::string defaultValue = myOptionsContainer.getValueString(entry);
339 // continue depending of type
340 if (type == "STR") {
341 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputString(this, myEntriesFrame, topic, entry, description, defaultValue));
342 } else if (type == "TIME") {
343 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputTime(this, myEntriesFrame, topic, entry, description, defaultValue));
344 } else if ((type == "FILE") || (type == "NETWORK") || (type == "ADDITIONAL") || (type == "ROUTE") || (type == "DATA")) {
345 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputFilename(this, myEntriesFrame, topic, entry, description, defaultValue));
346 } else if (type == "BOOL") {
347 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputBool(this, myEntriesFrame, topic, entry, description, defaultValue));
348 } else if (type == "INT") {
349 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputInt(this, myEntriesFrame, topic, entry, description, defaultValue));
350 } else if (type == "FLOAT") {
351 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputFloat(this, myEntriesFrame, topic, entry, description, defaultValue));
352 } else if (type == "INT[]") {
353 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputIntVector(this, myEntriesFrame, topic, entry, description, defaultValue));
354 } else if (type == "STR[]") {
355 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputStringVector(this, myEntriesFrame, topic, entry, description, defaultValue));
356 }
357 }
358 }
359 }
360 }
361 // create search elements
362 FXHorizontalFrame* searchFrame = new FXHorizontalFrame(contentFrame, GUIDesignAuxiliarHorizontalFrame);
363 new FXLabel(searchFrame, TL("Search"), nullptr, GUIDesignLabelThickedFixed(TREELISTWIDTH - GUIDesignHeight + 14));
365 myDescriptionSearchCheckButton->setToolTipText(TL("Include description in search"));
367 // add separator
368 new FXSeparator(contentFrame);
369 // create buttons frame
370 buttonsFrame = new FXHorizontalFrame(contentFrame, GUIDesignHorizontalFrame);
371 new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
372 // continue depending of dialog type
373 if (runDialog) {
375 } else {
376 GUIDesigns::buildFXButton(buttonsFrame, TL("OK"), "", "", GUIIconSubSys::getIcon(GUIIcon::ACCEPT), this, ID_ACCEPT, GUIDesignButtonOK);
377 }
380 new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
381 // create dialog
382 create();
383 // after creation, adjust entries name sizes
384 for (const auto& entry : myInputOptionEntries) {
385 entry->adjustNameSize();
386 }
387 // set myShowToolTipsMenu
388 myShowToolTipsMenu->setChecked(getApp()->reg().readIntEntry("gui", "menuToolTips", 0) != 1);
389}
390
391/****************************************************************************/
#define TREELISTWIDTH
FXDEFMAP(GNEOptionsDialog) GUIDialogOptionsMap[]
@ MID_GNE_RUNNETGENERATE
run netgenerate tool
Definition GUIAppEnum.h:773
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition GUIAppEnum.h:939
@ MID_CANCEL
Cancel-button pressed.
Definition GUIAppEnum.h:308
@ MID_CHOOSEN_SAVE
Save set.
Definition GUIAppEnum.h:603
@ MID_SHOWTOOLTIPS_MENU
Show tool tips in menus - button.
Definition GUIAppEnum.h:387
@ MID_GNE_SEARCH_USEDESCRIPTION
use search description
@ MID_GNE_BUTTON_DEFAULT
default button
@ MID_CHOOSEN_LOAD
Load set.
Definition GUIAppEnum.h:601
@ MID_GNE_SELECT
select element
Definition GUIAppEnum.h:957
@ MID_GNE_RESET
reset element
Definition GUIAppEnum.h:947
@ MID_MTEXTFIELDSEARCH_UPDATED
callback for MFXTextFieldSearch
#define GUIDesignCheckButtonThick
checkButton placed in left position
Definition GUIDesigns.h:195
#define GUIDesignContentsFrame
design for the main content frame of every frame/dialog with padding and spacing
Definition GUIDesigns.h:387
#define GUIDesignTextField
Definition GUIDesigns.h:59
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:399
#define GUIDesignButtonConfiguration
Configuration Button.
Definition GUIDesigns.h:159
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition GUIDesigns.h:74
#define GUIDesignTreeListFixedWidth
Definition GUIDesigns.h:677
#define GUIDesignButtonOK
Definition GUIDesigns.h:153
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:408
#define GUIDesignMFXCheckableButtonSquare
Definition GUIDesigns.h:137
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frame extended in all directions
Definition GUIDesigns.h:390
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:252
#define GUIDesignHorizontalFrameNoPadding
Horizontal frame extended over frame parent without padding and spacing.
Definition GUIDesigns.h:331
#define GUIDesignHorizontalFrame
Horizontal frame extended over frame parent with padding and spacing.
Definition GUIDesigns.h:328
#define GUIDesignDialogBoxExplicitStretchable(width, height)
design for dialog box with specific width and height that can be stretched (But not shrunk)
Definition GUIDesigns.h:617
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
@ SHOWTOOLTIPS_MENU
@ OPEN
open icons
@ SAVE
save icons
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define TL(string)
Definition MsgHandler.h:315
int GUIDesignHeight
the default size for GUI elements
Definition StdDefs.cpp:35
The main window of Netedit.
GNEViewNet * getViewNet()
get pointer to viewNet
long onCmdSaveOptions(FXObject *, FXSelector, void *)
save options
FXTreeItem * myRootItem
root item
FXTreeList * myTopicsTreeList
Topics elements tree.
void updateVisibleEntriesBySearch(std::string searchText)
update visible entries by search
MFXCheckableButton * myShowToolTipsMenu
checkable button for show toolTips
long onCmdCancel(FXObject *, FXSelector, void *)
called when user press cancel button
const std::set< std::string > myIgnoredEntries
ignores entries
long onCmdSelectTopic(FXObject *, FXSelector, void *)
called when user select a topic in the list
std::vector< GNEOptionsDialogElements::InputOption * > myInputOptionEntries
Input option entries.
const std::set< std::string > myIgnoredTopics
ignores topics
long onCmdReset(FXObject *, FXSelector, void *)
called when user press reset button
std::map< FXTreeItem *, std::string > myTreeItemTopics
map with topics and their associated FXTreeItem
GNEApplicationWindow * myGNEApp
pointer to main window parent
~GNEOptionsDialog()
Destructor.
MFXTextFieldSearch * mySearchButton
search button
static std::pair< int, bool > Run(GNEApplicationWindow *GNEApp, GUIIcon icon, OptionsCont &optionsContainer, const OptionsCont &originalOptionsContainer, const char *titleName)
Constructor for run dialogs.
bool loadConfiguration(const std::string &file)
load configuration
static std::pair< int, bool > Options(GNEApplicationWindow *GNEApp, GUIIcon icon, OptionsCont &optionsContainer, const OptionsCont &originalOptionsContainer, const char *titleName)
Constructor for options dialogs.
OptionsCont & myOptionsContainer
reference to edited Option container
FXVerticalFrame * myEntriesFrame
vertical frame for entries
MFXCheckButtonTooltip * myDescriptionSearchCheckButton
checkbox for enable/disable search by description
long onCmdShowToolTipsMenu(FXObject *, FXSelector, void *)
enable/disable show toolTip
long onCmdResetDefault(FXObject *, FXSelector, void *)
reset default
long onCmdSearch(FXObject *, FXSelector, void *)
called when user searches
long onCmdLoadOptions(FXObject *, FXSelector, void *)
load options
bool myOptionsModified
flag for check if options was modified
bool updateVisibleEntriesByTopic()
update visible entries by selected topic
GNEOptionsDialog()
FOX needs this.
long onCmdRunNetgenerate(FXObject *, FXSelector, void *)
called when user press reset button
GNEViewParent * getViewParent() const
get the net object
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
MFXCheckableButton * getShowToolTipsMenu() const
get menu for tooltips menu
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus
void setToolTipText(const FXString &toolTip)
set toolTip
bool amChecked() const
check if this MFXCheckableButton is checked
void setChecked(bool val, const bool inform=false)
check or uncheck this MFXCheckableButton
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
void enableStaticToolTip(const bool value)
enable/disable static tooltip
FXString getText() const
Get the text for this label.
FXTextFieldIcon (based on FXTextFieldIcon)
A storage for options typed value containers)
Definition OptionsCont.h:89
const std::vector< std::string > & getSubTopics() const
return the list of subtopics
std::string getTypeName(const std::string name)
return the type name for the given option
void writeConfiguration(std::ostream &os, const bool filled, const bool complete, const bool addComments, const std::string &relativeTo="", const bool forceRelative=false, const bool inComment=false) const
Writes the configuration.
std::string getValueString(const std::string &name) const
Returns the string-value of the named option (all options)
const std::string & getDescription(const std::string &name) const
Returns the option description.
void resetWritable()
Resets all options to be writeable.
std::vector< std::string > getSubTopicsEntries(const std::string &subtopic) const
return the list of entries for the given subtopic
A SAX-Handler for loading options.
bool errorOccurred() const
Returns the information whether an error occurred.
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
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 std::string openOptionFileDialog(FXWindow *window, bool save)
open option dialog