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-2025 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>
25#include <netedit/GNEViewNet.h>
36#include <xercesc/parsers/SAXParser.hpp>
37
38#include "GNEOptionsDialog.h"
39
40// ===========================================================================
41// Defines
42// ===========================================================================
43
44#define TREELISTWIDTH 200
45
46// ===========================================================================
47// FOX callback mapping
48// ===========================================================================
49
62
63// Object implementation
64FXIMPLEMENT(GNEOptionsDialog, MFXDialogBox, GUIDialogOptionsMap, ARRAYNUMBER(GUIDialogOptionsMap))
65
66// ===========================================================================
67// method definitions
68// ===========================================================================
69
70std::pair<int, bool>
71GNEOptionsDialog::Options(GNEApplicationWindow* GNEApp, GUIIcon icon, OptionsCont& optionsContainer, const OptionsCont& originalOptionsContainer, const char* titleName) {
72 GNEOptionsDialog* optionsDialog = new GNEOptionsDialog(GNEApp, icon, optionsContainer, originalOptionsContainer, titleName, false);
73 auto result = std::make_pair(optionsDialog->openModalDialog(GNEApp->getInternalTest()), optionsDialog->myOptionsModified);
74 delete optionsDialog;
75 return result;
76}
77
78
79std::pair<int, bool>
80GNEOptionsDialog::Run(GNEApplicationWindow* GNEApp, GUIIcon icon, OptionsCont& optionsContainer, const OptionsCont& originalOptionsContainer, const char* titleName) {
81 GNEOptionsDialog* optionsDialog = new GNEOptionsDialog(GNEApp, icon, optionsContainer, originalOptionsContainer, titleName, true);
82 auto result = std::make_pair(optionsDialog->openModalDialog(GNEApp->getInternalTest()), optionsDialog->myOptionsModified);
83 delete optionsDialog;
84 return result;
85}
86
87
89
90
91void
93 // finish
94}
95
96
97long
98GNEOptionsDialog::onCmdCancel(FXObject*, FXSelector, void*) {
99 // reset entries
100 for (const auto& entry : myInputOptionEntries) {
101 entry->onCmdResetOption(nullptr, 0, nullptr);
102 }
103 // close dialog canceling changes
104 return handle(this, FXSEL(SEL_COMMAND, FXDialogBox::ID_CANCEL), nullptr);
105}
106
107
108long
109GNEOptionsDialog::onCmdReset(FXObject*, FXSelector, void*) {
110 // reset entries
111 for (const auto& entry : myInputOptionEntries) {
112 entry->onCmdResetOption(nullptr, 0, nullptr);
113 }
114 return 1;
115}
116
117
118long
119GNEOptionsDialog::onCmdRunNetgenerate(FXObject*, FXSelector, void*) {
120 // close dialog accepting changes
121 handle(this, FXSEL(SEL_COMMAND, FXDialogBox::ID_ACCEPT), nullptr);
122 // run tool in mainWindow
123 return myGNEApp->handle(this, FXSEL(SEL_COMMAND, MID_GNE_RUNNETGENERATE), nullptr);
124}
125
126
127long
128GNEOptionsDialog::onCmdSelectTopic(FXObject*, FXSelector, void*) {
129 if (mySearchButton->getText().count() == 0) {
131 }
132 return 1;
133}
134
135
136long
137GNEOptionsDialog::onCmdSearch(FXObject*, FXSelector, void*) {
138 if (mySearchButton->getText().count() > 0) {
140 } else {
142 }
143 return 1;
144}
145
146
147long
148GNEOptionsDialog::onCmdShowToolTipsMenu(FXObject*, FXSelector, void*) {
149 // toggle check
151 if (myGNEApp->getViewNet()) {
154 }
155 // enable/disable static tooltip
157 // save in registry
158 getApp()->reg().writeIntEntry("gui", "menuToolTips", myShowToolTipsMenu->amChecked() ? 0 : 1);
159 update();
160
161 return 1;
162}
163
164
165long
166GNEOptionsDialog::onCmdSaveOptions(FXObject*, FXSelector, void*) {
167 // open save dialog
168 const std::string file = GNEApplicationWindowHelper::openOptionFileDialog(this, true);
169 // check file
170 if (file.size() > 0) {
171 std::ofstream out(StringUtils::transcodeToLocal(file));
172 myOptionsContainer.writeConfiguration(out, true, false, false, file, true);
173 out.close();
174 }
175 return 1;
176}
177
178
179long
180GNEOptionsDialog::onCmdLoadOptions(FXObject*, FXSelector, void*) {
181 // open file dialog
182 const std::string file = GNEApplicationWindowHelper::openOptionFileDialog(this, false);
183 // check file
184 if ((file.size() > 0) && loadConfiguration(file)) {
185 // update entries
186 for (const auto& entry : myInputOptionEntries) {
187 entry->updateOption();
188 }
189 }
190 return 1;
191}
192
193
194long
195GNEOptionsDialog::onCmdResetDefault(FXObject*, FXSelector, void*) {
196 // restore entries
197 for (const auto& entry : myInputOptionEntries) {
198 entry->restoreOption();
199 }
200 return 1;
201}
202
203
205 myGNEApp(nullptr),
206 myOptionsContainer(OptionsCont::EMPTY_OPTIONS),
207 myOriginalOptionsContainer(OptionsCont::EMPTY_OPTIONS) {
208}
209
210
211bool
213 // iterate over tree elements and get the selected item
214 for (const auto& treeItemTopic : myTreeItemTopics) {
215 if (treeItemTopic.first->isSelected()) {
216 // iterate over entries
217 for (const auto& entry : myInputOptionEntries) {
218 if (entry->getTopic() == treeItemTopic.second) {
219 entry->show();
220 } else {
221 entry->hide();
222 }
223 }
224 myEntriesFrame->recalc();
225 myEntriesFrame->update();
226 return true;
227 }
228 }
229 // no topic selected, then show all
230 for (const auto& entry : myInputOptionEntries) {
231 entry->show();
232 }
233 myEntriesFrame->recalc();
234 myEntriesFrame->update();
235 return true;
236}
237
238
239void
241 // first lower case search text
242 searchText = StringUtils::to_lower_case(searchText);
243 // iterate over entries
244 for (const auto& entry : myInputOptionEntries) {
245 if (searchText.empty()) {
246 // show all entries if searchText is empty
247 entry->show();
248 } else if (entry->getNameLower().find(searchText) != std::string::npos) {
249 entry->show();
250 } else if ((myDescriptionSearchCheckButton->getCheck() == TRUE) &&
251 (entry->getDescriptionLower().find(searchText) != std::string::npos)) {
252 entry->show();
253 } else {
254 entry->hide();
255 }
256 }
257 myEntriesFrame->recalc();
258 myEntriesFrame->update();
259}
260
261
262bool
263GNEOptionsDialog::loadConfiguration(const std::string& file) {
264 // make all options writable
266 // build parser
267 XERCES_CPP_NAMESPACE::SAXParser parser;
268 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
269 parser.setDisableDefaultEntityResolution(true);
270 // start the parsing
272 try {
273 parser.setDocumentHandler(&handler);
274 parser.setErrorHandler(&handler);
275 parser.parse(StringUtils::transcodeToLocal(file).c_str());
276 if (handler.errorOccurred()) {
277 WRITE_ERROR(TL("Could not load configuration '") + file + "'.");
278 return false;
279 }
280 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
281 WRITE_ERROR(TL("Could not load tool configuration '") + file + "':\n " + StringUtils::transcode(e.getMessage()));
282 return false;
283 }
284 // write info
285 WRITE_MESSAGE(TL("Loaded configuration."));
286 return true;
287}
288
289
291 const OptionsCont& originalOptionsContainer, const char* titleName, const bool runDialog) :
292 MFXDialogBox(GNEApp, titleName, GUIDesignDialogBoxExplicitStretchable(800, 600)),
293 myGNEApp(GNEApp),
294 myOptionsContainer(optionsContainer),
295 myOriginalOptionsContainer(originalOptionsContainer) {
296 // set icon
297 setIcon(GUIIconSubSys::getIcon(icon));
298 // create content frame
299 FXVerticalFrame* contentFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);
300 // add buttons frame
301 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(contentFrame, GUIDesignHorizontalFrameNoPadding);
302 myShowToolTipsMenu = new MFXCheckableButton(false, buttonsFrame,
303 myGNEApp->getStaticTooltipMenu(), (std::string("\t") + TL("Toggle Menu Tooltips") + std::string("\t") + TL("Toggles whether tooltips in the menu shall be shown.")).c_str(),
305 auto saveFile = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Save options"),
307 saveFile->setTipText(TL("Save configuration file"));
308 auto loadFile = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Load options"),
310 loadFile->setTipText(TL("Load configuration file"));
311 auto resetDefault = new MFXButtonTooltip(buttonsFrame, myGNEApp->getStaticTooltipMenu(), TL("Default options"),
313 resetDefault->setTipText(TL("Reset all options to default"));
314 // add separator
315 new FXSeparator(contentFrame);
316 // create elements frame
317 FXHorizontalFrame* elementsFrame = new FXHorizontalFrame(contentFrame, GUIDesignAuxiliarFrame);
318 FXVerticalFrame* elementsFrameTree = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarVerticalFrame);
319 FXVerticalFrame* elementsFrameValues = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarFrame);
320 // Create GroupBox modules
321 MFXGroupBoxModule* groupBoxTree = new MFXGroupBoxModule(elementsFrameTree, TL("Topics"));
322 MFXGroupBoxModule* groupBoxOptions = new MFXGroupBoxModule(elementsFrameValues, TL("Options"));
323 // create FXTreeList
324 myTopicsTreeList = new FXTreeList(groupBoxTree->getCollapsableFrame(), this, MID_GNE_SELECT, GUIDesignTreeListFixedWidth);
326 // add root item
327 myRootItem = myTopicsTreeList->appendItem(nullptr, titleName);
328 myRootItem->setExpanded(TRUE);
329 // create scroll
330 FXScrollWindow* scrollTabEntries = new FXScrollWindow(groupBoxOptions->getCollapsableFrame(), LAYOUT_FILL_X | LAYOUT_FILL_Y);
331 // create vertical frame for entries
332 myEntriesFrame = new FXVerticalFrame(scrollTabEntries, GUIDesignAuxiliarFrame);
333 // iterate over all topics
334 for (const auto& topic : myOptionsContainer.getSubTopics()) {
335 // check if we have to ignore this topic
336 if (myIgnoredTopics.count(topic) == 0) {
337 // add topic into myTreeItemTopics and tree
338 myTreeItemTopics[myTopicsTreeList->appendItem(myRootItem, topic.c_str())] = topic;
339 // iterate over entries
340 const std::vector<std::string> entries = myOptionsContainer.getSubTopicsEntries(topic);
341 for (const auto& entry : entries) {
342 // check if we have to ignore this entry
343 if (myIgnoredEntries.count(entry) == 0) {
344 // get type
345 const std::string type = myOptionsContainer.getTypeName(entry);
346 // get description
347 const std::string description = myOptionsContainer.getDescription(entry);
348 // get default value
349 const std::string defaultValue = myOptionsContainer.getValueString(entry);
350 // continue depending of type
351 if (type == "STR") {
352 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputString(this, myEntriesFrame, topic, entry, description, defaultValue));
353 } else if (type == "TIME") {
354 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputTime(this, myEntriesFrame, topic, entry, description, defaultValue));
355 } else if ((type == "FILE") || (type == "NETWORK") || (type == "ADDITIONAL") || (type == "ROUTE") || (type == "DATA")) {
356 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputFilename(this, myEntriesFrame, topic, entry, description, defaultValue));
357 } else if (type == "BOOL") {
358 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputBool(this, myEntriesFrame, topic, entry, description, defaultValue));
359 } else if (type == "INT") {
360 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputInt(this, myEntriesFrame, topic, entry, description, defaultValue));
361 } else if (type == "FLOAT") {
362 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputFloat(this, myEntriesFrame, topic, entry, description, defaultValue));
363 } else if (type == "INT[]") {
364 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputIntVector(this, myEntriesFrame, topic, entry, description, defaultValue));
365 } else if (type == "STR[]") {
366 myInputOptionEntries.push_back(new GNEOptionsDialogElements::InputStringVector(this, myEntriesFrame, topic, entry, description, defaultValue));
367 }
368 }
369 }
370 }
371 }
372 // create search elements
373 FXHorizontalFrame* searchFrame = new FXHorizontalFrame(contentFrame, GUIDesignAuxiliarHorizontalFrame);
374 new FXLabel(searchFrame, TL("Search"), nullptr, GUIDesignLabelThickedFixed(TREELISTWIDTH - GUIDesignHeight + 14));
376 myDescriptionSearchCheckButton->setToolTipText(TL("Include description in search"));
378 // add separator
379 new FXSeparator(contentFrame);
380 // create buttons frame
381 buttonsFrame = new FXHorizontalFrame(contentFrame, GUIDesignHorizontalFrame);
382 new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
383 // continue depending of dialog type
384 if (runDialog) {
386 } else {
387 GUIDesigns::buildFXButton(buttonsFrame, TL("OK"), "", "", GUIIconSubSys::getIcon(GUIIcon::ACCEPT), this, FXDialogBox::ID_ACCEPT, GUIDesignButtonOK);
388 }
391 new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
392 // create dialog
393 create();
394 // after creation, adjust entries name sizes
395 for (const auto& entry : myInputOptionEntries) {
396 entry->adjustNameSize();
397 }
398 // set myShowToolTipsMenu
399 myShowToolTipsMenu->setChecked(getApp()->reg().readIntEntry("gui", "menuToolTips", 0) != 1);
400}
401
402/****************************************************************************/
#define TREELISTWIDTH
FXDEFMAP(GNEOptionsDialog) GUIDialogOptionsMap[]
@ MID_GNE_RUNNETGENERATE
run netgenerate tool
Definition GUIAppEnum.h:773
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition GUIAppEnum.h:991
@ 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
@ MID_GNE_RESET
reset element
Definition GUIAppEnum.h:999
@ 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:289
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define TL(string)
Definition MsgHandler.h:305
int GUIDesignHeight
the default size for GUI elements
Definition StdDefs.cpp:36
The main window of Netedit.
GNEInternalTest * getInternalTest() const
get netedit test system
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
void runInternalTest(const InternalTestStep::DialogTest *modalArguments)
run internal test
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
dialog arguments (used for certain functions that opens modal dialogs)
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
FXuint openModalDialog(InternalTest *internalTests, FXuint placement=PLACEMENT_CURSOR)
Run modal invocation of the dialog.
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