Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEOptionsEditor.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-2026 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#include <utils/xml/XMLSubSys.h>
22
23#include <fstream>
24
27#include <netedit/GNEViewNet.h>
35#include <xercesc/parsers/SAXParser.hpp>
36
37#include "GNEOptionsEditor.h"
38
39// ===========================================================================
40// Defines
41// ===========================================================================
42
43#define TREELISTWIDTH 200
44
45// ===========================================================================
46// FOX callback mapping
47// ===========================================================================
48
58
59// Object implementation
60FXIMPLEMENT(GNEOptionsEditor, FXVerticalFrame, GNEOptionsEditorMap, ARRAYNUMBER(GNEOptionsEditorMap))
61
62// ===========================================================================
63// method definitions
64// ===========================================================================
65
66GNEOptionsEditor::GNEOptionsEditor(GNEDialog* dialog, const std::string& titleName, OptionsCont& optionsContainer,
67 const OptionsCont& originalOptionsContainer) :
68 FXVerticalFrame(dialog->getContentFrame(), GUIDesignAuxiliarFrame),
69 myDialog(dialog),
70 myOptionsContainer(optionsContainer),
71 myCopyOfOptionsContainer(optionsContainer.clone()),
72 myOriginalOptionsContainer(originalOptionsContainer) {
73 // get staticTooltipMenu
74 auto staticTooltipMenu = dialog->getApplicationWindow()->getStaticTooltipMenu();
75 // add buttons frame
76 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(this, GUIDesignHorizontalFrameNoPadding);
77 myShowToolTipsMenu = new MFXCheckableButton(false, buttonsFrame, staticTooltipMenu,
78 (std::string("\t") + TL("Toggle Menu Tooltips") + std::string("\t") + TL("Toggles whether tooltips in the menu shall be shown.")).c_str(),
80 auto saveFile = new MFXButtonTooltip(buttonsFrame, staticTooltipMenu, TL("Save options"),
82 saveFile->setTipText(TL("Save configuration file"));
83 auto loadFile = new MFXButtonTooltip(buttonsFrame, staticTooltipMenu, TL("Load options"),
85 loadFile->setTipText(TL("Load configuration file"));
86 auto resetDefault = new MFXButtonTooltip(buttonsFrame, staticTooltipMenu, TL("Default options"),
88 resetDefault->setTipText(TL("Reset all options to default"));
89 // add separator
90 new FXSeparator(this);
91 // create elements frame
92 FXHorizontalFrame* elementsFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarFrame);
93 FXVerticalFrame* elementsFrameTree = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarVerticalFrame);
94 FXVerticalFrame* elementsFrameValues = new FXVerticalFrame(elementsFrame, GUIDesignAuxiliarFrame);
95 // Create GroupBox modules
96 GNEGroupBoxModule* groupBoxTree = new GNEGroupBoxModule(elementsFrameTree, TL("Topics"));
97 GNEGroupBoxModule* groupBoxOptions = new GNEGroupBoxModule(elementsFrameValues, TL("Options"));
98 // create FXTreeList
101 // add root item
102 myRootItem = myTopicsTreeList->appendItem(nullptr, titleName.c_str());
103 myRootItem->setExpanded(TRUE);
104 // create scroll
105 FXScrollWindow* scrollTabEntries = new FXScrollWindow(groupBoxOptions->getCollapsableFrame(), LAYOUT_FILL_X | LAYOUT_FILL_Y);
106 // create vertical frame for entries
107 myEntriesFrame = new FXVerticalFrame(scrollTabEntries, GUIDesignAuxiliarFrame);
108 // iterate over all topics
109 for (const auto& topic : myOptionsContainer.getSubTopics()) {
110 // check if we have to ignore this topic
111 if (myIgnoredTopics.count(topic) == 0) {
112 // add topic into myTreeItemTopics and tree
113 myTreeItemTopics[myTopicsTreeList->appendItem(myRootItem, topic.c_str())] = topic;
114 // processing options require save network
115 const bool requireSaveNetwork = (topic == "Processing");
116 // iterate over entries
117 const std::vector<std::string> entries = myOptionsContainer.getSubTopicsEntries(topic);
118 for (const auto& entry : entries) {
119 // check if we have to ignore this entry
120 if (myIgnoredEntries.count(entry) == 0) {
121 // get type
122 const std::string type = myOptionsContainer.getTypeName(entry);
123 // get description
124 const std::string description = myOptionsContainer.getDescription(entry);
125 // get default value
126 const std::string defaultValue = myOptionsContainer.getValueString(entry);
127 // check if is editable
128 const bool editable = myOptionsContainer.isEditable(entry);
129 // continue depending of type
130 if (type == "STR") {
131 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionString(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
132 } else if (type == "TIME") {
133 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionTime(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
134 } else if ((type == "FILE") || (type == "NETWORK") || (type == "ADDITIONAL") || (type == "ROUTE") || (type == "DATA")) {
135 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionFilename(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
136 } else if (type == "BOOL") {
137 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionBool(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
138 } else if (type == "INT") {
139 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionInt(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
140 } else if (type == "FLOAT") {
141 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionFloat(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
142 } else if (type == "INT[]") {
143 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionIntVector(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
144 } else if (type == "STR[]") {
145 myOptionRowEntries.push_back(new GNEOptionsEditorRow::OptionStringVector(this, myEntriesFrame, topic, entry, description, defaultValue, editable, requireSaveNetwork));
146 }
147 }
148 }
149 }
150 }
151 // create search elements
152 FXHorizontalFrame* searchFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
153 new FXLabel(searchFrame, TL("Search"), nullptr, GUIDesignLabelThickedFixed(TREELISTWIDTH - GUIDesignHeight + 14));
155 myDescriptionSearchCheckButton->setToolTipText(TL("Include description in search"));
156 mySearchButton = new MFXTextFieldSearch(searchFrame, staticTooltipMenu, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
157 // after creation, adjust entries name sizes
158 for (const auto& entry : myOptionRowEntries) {
159 entry->adjustNameSize();
160 }
161 // set myShowToolTipsMenu
162 myShowToolTipsMenu->setChecked(getApp()->reg().readIntEntry("gui", "menuToolTips", 0) != 1);
163}
164
165
169
170
171void
173 // not finished yet
174}
175
176
177bool
181
182
183bool
187
188
189void
191 for (const auto& entry : myOptionRowEntries) {
192 entry->onCmdResetOption(nullptr, 0, nullptr);
193 }
194 myOptionsModified = false;
195 myRequireSaveNetwork = false;
196}
197
198
199long
200GNEOptionsEditor::onCmdSelectTopic(FXObject*, FXSelector, void*) {
201 if (mySearchButton->getText().count() == 0) {
203 }
204 return 1;
205}
206
207
208long
209GNEOptionsEditor::onCmdSearch(FXObject*, FXSelector, void*) {
210 if (mySearchButton->getText().count() > 0) {
212 } else {
214 }
215 return 1;
216}
217
218
219long
220GNEOptionsEditor::onCmdShowToolTipsMenu(FXObject*, FXSelector, void*) {
221 // get staticTooltipMenu
222 auto viewNet = myDialog->getApplicationWindow()->getViewNet();
223 // toggle check
224 myShowToolTipsMenu->setChecked(!myShowToolTipsMenu->amChecked());
225 if (viewNet) {
226 viewNet->getViewParent()->getShowToolTipsMenu()->setChecked(myShowToolTipsMenu->amChecked());
227 viewNet->getViewParent()->getShowToolTipsMenu()->update();
228 }
229 // enable/disable static tooltip
230 myDialog->getApplicationWindow()->getStaticTooltipMenu()->enableStaticToolTip(myShowToolTipsMenu->amChecked());
231 // save in registry
232 getApp()->reg().writeIntEntry("gui", "menuToolTips", myShowToolTipsMenu->amChecked() ? 0 : 1);
233 update();
234
235 return 1;
236}
237
238
239long
240GNEOptionsEditor::onCmdSaveOptions(FXObject*, FXSelector, void*) {
241 // open file dialog
242 const GNEFileDialog optionsFileDialog(myDialog->getApplicationWindow(), myDialog,
243 TL("options file"),
247 // check file
248 if (optionsFileDialog.getResult() == GNEDialog::Result::ACCEPT) {
249 std::ofstream out(XMLSubSys::transcodeToLocal(optionsFileDialog.getFilename()));
250 myOptionsContainer.writeConfiguration(out, true, false, false, optionsFileDialog.getFilename(), true);
251 out.close();
252 }
253 return 1;
254}
255
256
257long
258GNEOptionsEditor::onCmdLoadOptions(FXObject*, FXSelector, void*) {
259 // open file dialog
260 const GNEFileDialog optionsFileDialog(myDialog->getApplicationWindow(), myDialog,
261 TL("options file"),
265 // check file
266 if ((optionsFileDialog.getResult() == GNEDialog::Result::ACCEPT) && loadConfiguration(optionsFileDialog.getFilename())) {
267 // update entries
268 for (const auto& entry : myOptionRowEntries) {
269 entry->updateOption();
270 }
271 }
272 return 1;
273}
274
275
276long
277GNEOptionsEditor::onCmdResetDefault(FXObject*, FXSelector, void*) {
278 // restore entries
279 for (const auto& entry : myOptionRowEntries) {
280 if (entry->isEditable()) {
281 entry->restoreOption();
282 }
283 }
284 return 1;
285}
286
287
292
293
294bool
296 // iterate over tree elements and get the selected item
297 for (const auto& treeItemTopic : myTreeItemTopics) {
298 if (treeItemTopic.first->isSelected()) {
299 // iterate over entries
300 for (const auto& entry : myOptionRowEntries) {
301 if (entry->getTopic() == treeItemTopic.second) {
302 entry->show();
303 } else {
304 entry->hide();
305 }
306 }
307 myEntriesFrame->recalc();
308 myEntriesFrame->update();
309 return true;
310 }
311 }
312 // no topic selected, then show all
313 for (const auto& entry : myOptionRowEntries) {
314 entry->show();
315 }
316 myEntriesFrame->recalc();
317 myEntriesFrame->update();
318 return true;
319}
320
321
322void
324 // first lower case search text
325 searchText = StringUtils::to_lower_case(searchText);
326 // iterate over entries
327 for (const auto& entry : myOptionRowEntries) {
328 if (searchText.empty()) {
329 // show all entries if searchText is empty
330 entry->show();
331 } else if (entry->getNameLower().find(searchText) != std::string::npos) {
332 entry->show();
333 } else if ((myDescriptionSearchCheckButton->getCheck() == TRUE) &&
334 (entry->getDescriptionLower().find(searchText) != std::string::npos)) {
335 entry->show();
336 } else {
337 entry->hide();
338 }
339 }
340 myEntriesFrame->recalc();
341 myEntriesFrame->update();
342}
343
344
345bool
346GNEOptionsEditor::loadConfiguration(const std::string& file) {
347 // make all options writable
348 myOptionsContainer.resetWritable();
349 // build parser
350 XERCES_CPP_NAMESPACE::SAXParser parser;
351 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
352 parser.setDisableDefaultEntityResolution(true);
353 // start the parsing
355 try {
356 parser.setDocumentHandler(&handler);
357 parser.setErrorHandler(&handler);
358 parser.parse(XMLSubSys::transcodeToLocal(file).c_str());
359 if (handler.errorOccurred()) {
360 WRITE_ERROR(TL("Could not load configuration '") + file + "'.");
361 return false;
362 }
363 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
364 WRITE_ERROR(TL("Could not load tool configuration '") + file + "':\n " + XMLSubSys::transcode(e.getMessage()));
365 return false;
366 }
367 // write info
368 WRITE_MESSAGE(TL("Loaded configuration."));
369 return true;
370}
371
372/****************************************************************************/
#define TREELISTWIDTH
FXDEFMAP(GNEOptionsEditor) GNEOptionsEditorMap[]
@ MID_GNE_SET_ATTRIBUTE
attribute edited
@ MID_CHOOSEN_SAVE
Save set.
Definition GUIAppEnum.h:605
@ MID_SHOWTOOLTIPS_MENU
Show tool tips in menus - button.
Definition GUIAppEnum.h:389
@ MID_GNE_SEARCH_USEDESCRIPTION
use search description
@ MID_GNE_BUTTON_DEFAULT
default button
@ MID_CHOOSEN_LOAD
Load set.
Definition GUIAppEnum.h:603
@ MID_GNE_SELECT
select element
@ MID_MTEXTFIELDSEARCH_UPDATED
callback for MFXTextFieldSearch
#define GUIDesignCheckButtonThick
checkButton placed in left position
Definition GUIDesigns.h:197
#define GUIDesignTextField
Definition GUIDesigns.h:74
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:430
#define GUIDesignButtonConfiguration
Configuration Button.
Definition GUIDesigns.h:177
#define GUIDesignTreeListFixedWidth
Definition GUIDesigns.h:693
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:439
#define GUIDesignMFXCheckableButtonSquare
Definition GUIDesigns.h:158
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frame extended in all directions
Definition GUIDesigns.h:409
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:254
#define GUIDesignHorizontalFrameNoPadding
Horizontal frame extended over frame parent without padding and spacing.
Definition GUIDesigns.h:350
@ SHOWTOOLTIPS_MENU
Definition GUIIcons.h:192
@ OPEN
open icons
Definition GUIIcons.h:79
@ SAVE
save icons
Definition GUIIcons.h:92
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:304
int GUIDesignHeight
the default height for GUI elements
Definition StdDefs.cpp:41
Result getResult() const
get result to indicate if this dialog was closed accepting or rejecting changes
std::string getFilename() const
Return file name, if any.
GNEGroupBoxModule (based on FXGroupBox).
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
long onCmdSaveOptions(FXObject *, FXSelector, void *)
save options
void resetAllOptions()
reset options
bool loadConfiguration(const std::string &file)
load configuration
long onCmdShowToolTipsMenu(FXObject *, FXSelector, void *)
enable/disable show toolTip
FXVerticalFrame * myEntriesFrame
vertical frame for entries
long onCmdSearch(FXObject *, FXSelector, void *)
called when user searches
const OptionsCont & myOriginalOptionsContainer
reference to original Option container, used for restoring
long onCmdLoadOptions(FXObject *, FXSelector, void *)
load options
MFXTextFieldSearch * mySearchButton
search button
bool requireSaveNetwork() const
check if option require save network
GNEDialog * myDialog
reference to dialog
OptionsCont & myOptionsContainer
reference to edited Option container
bool myOptionsModified
flag for check if options was modified
MFXCheckButtonTooltip * myDescriptionSearchCheckButton
checkbox for enable/disable search by description
void runInternalTest(const InternalTestStep::DialogArgument *dialogArgument)
run internal test
long onCmdResetDefault(FXObject *, FXSelector, void *)
reset default
MFXCheckableButton * myShowToolTipsMenu
checkable button for show toolTips
long onCmdSelectTopic(FXObject *, FXSelector, void *)
called when user select a topic in the list
OptionsCont * myCopyOfOptionsContainer
copy of edited Option container, used for reset
GNEOptionsEditor()
FOX needs this.
const std::set< std::string > myIgnoredEntries
ignores entries
FXTreeItem * myRootItem
root item
GNEOptionsEditor(GNEDialog *dialog, const std::string &titleName, OptionsCont &optionsContainer, const OptionsCont &originalOptionsContainer)
Constructor.
std::map< FXTreeItem *, std::string > myTreeItemTopics
map with topics and their associated FXTreeItem
bool myRequireSaveNetwork
flag for check if options require save network
const std::set< std::string > myIgnoredTopics
ignores topics
bool updateVisibleEntriesByTopic()
update visible entries by selected topic
void updateVisibleEntriesBySearch(std::string searchText)
update visible entries by search
bool isOptionModified() const
check if option was modified
std::vector< GNEOptionsEditorRow::OptionRow * > myOptionRowEntries
Input option entries.
~GNEOptionsEditor()
Destructor.
FXTreeList * myTopicsTreeList
Topics elements tree.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
dialog arguments, used for certain modal dialogs that can not be edited using tab
FXTextFieldIcon (based on FXTextFieldIcon).
A storage for options typed value containers).
Definition OptionsCont.h:89
A SAX-Handler for loading options.
bool errorOccurred() const
Returns the information whether an error occurred.
static StringBijection< XMLFileExtension > XMLFileExtensions
XML file Extensions.
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
static std::string transcode(const XMLCh *const data, int length=-1)
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
Definition json.hpp:4471