Eclipse SUMO - Simulation of Urban MObility
GNEFlowEditor.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 /****************************************************************************/
19 /****************************************************************************/
20 #include <config.h>
21 
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
25 #include <netedit/GNEViewParent.h>
31 
32 #include "GNEFlowEditor.h"
33 
34 
35 // ===========================================================================
36 // FOX callback mapping
37 // ===========================================================================
38 
39 FXDEFMAP(GNEFlowEditor) FlowEditorMap[] = {
41 };
42 
43 // Object implementation
44 FXIMPLEMENT(GNEFlowEditor, MFXGroupBoxModule, FlowEditorMap, ARRAYNUMBER(FlowEditorMap))
45 
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 
51 GNEFlowEditor::GNEFlowEditor(GNEViewNet* viewNet, GNEFrame* frameParent) :
52  MFXGroupBoxModule(frameParent, TL("Flow attributes")),
53  myViewNet(viewNet) {
54  const auto staticTooltip = frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
55  // create comboBox for option A
56  FXHorizontalFrame* auxiliarHorizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
57  auto terminatelabel = new FXLabel(auxiliarHorizontalFrame, "terminate", nullptr, GUIDesignLabelThickedFixed(100));
58  terminatelabel->setTipText("Terminate attribute");
59  myTerminateComboBox = new MFXComboBoxIcon(auxiliarHorizontalFrame, GUIDesignComboBoxNCol, false, GUIDesignComboBoxVisibleItemsMedium,
61  // create comboBox for spacing
62  mySpacingFrameComboBox = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
63  auto spacingAttribute = new FXLabel(mySpacingFrameComboBox, "spacing", nullptr, GUIDesignLabelThickedFixed(100));
64  spacingAttribute->setTipText("Terminate attribute");
65  mySpacingComboBox = new MFXComboBoxIcon(mySpacingFrameComboBox, GUIDesignComboBoxNCol, false, GUIDesignComboBoxVisibleItemsMedium,
67  // create textField for option A
68  myTerminateFrameTextField = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
69  myTerminateLabel = new MFXLabelTooltip(myTerminateFrameTextField, staticTooltip, "A", nullptr, GUIDesignLabelThickedFixed(100));
70  myTerminateTextField = new FXTextField(myTerminateFrameTextField, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
71  // create textField for spacing
72  mySpacingFrameTextField = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
73  mySpacingLabel = new MFXLabelTooltip(mySpacingFrameTextField, staticTooltip, "B", nullptr, GUIDesignLabelThickedFixed(100));
74  mySpacingTextField = new FXTextField(mySpacingFrameTextField, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
75  // fill terminate
76  myTerminateComboBox->appendIconItem(toString(SUMO_ATTR_END).c_str());
77  myTerminateComboBox->appendIconItem(toString(SUMO_ATTR_NUMBER).c_str());
78  myTerminateComboBox->appendIconItem((toString(SUMO_ATTR_END) + "-" + toString(SUMO_ATTR_NUMBER)).c_str());
79  // fill comboBox B
80  mySpacingComboBox->appendIconItem(toString(SUMO_ATTR_VEHSPERHOUR).c_str());
81  mySpacingComboBox->appendIconItem(toString(SUMO_ATTR_PERIOD).c_str());
82  mySpacingComboBox->appendIconItem(toString(GNE_ATTR_POISSON).c_str());
83  mySpacingComboBox->appendIconItem(toString(SUMO_ATTR_PROB).c_str());
84 }
85 
86 
88 
89 
90 void
91 GNEFlowEditor::showFlowEditor(const std::vector<GNEAttributeCarrier*> editedFlows) {
92  // update flows
93  myEditedFlows = editedFlows;
94  // check number of flows
95  if (myEditedFlows.size() > 0) {
96  // update per hour attr
97  if (myEditedFlows.front()->getTagProperty().hasAttribute(SUMO_ATTR_PERSONSPERHOUR)) {
99  } else if (myEditedFlows.front()->getTagProperty().hasAttribute(SUMO_ATTR_CONTAINERSPERHOUR)) {
101  } else {
103  }
104  // clear and update comboBoxB
110  // refresh
112  // show
113  show();
114  }
115 }
116 
117 
118 void
120  hide();
121 }
122 
123 
124 bool
126  return shown();
127 }
128 
129 
130 void
132  // show both attributes
134  mySpacingFrameTextField->show();
135  // reset colors
136  myTerminateTextField->setTextColor(FXRGB(0, 0, 0));
137  myTerminateTextField->killFocus();
138  mySpacingTextField->setTextColor(FXRGB(0, 0, 0));
139  mySpacingTextField->killFocus();
140  // continue depending of number of flow
141  if (myEditedFlows.size() == 1) {
143  } else if (myEditedFlows.size() > 1) {
145  }
146  // recalc
147  recalc();
148 }
149 
150 
151 void
153  // case end-number
154  if (myTerminateLabel->getText().text() == toString(SUMO_ATTR_END)) {
155  baseObject->addTimeAttribute(SUMO_ATTR_END, GNEAttributeCarrier::parse<SUMOTime>(myTerminateTextField->getText().text()));
156  }
157  if (mySpacingLabel->getText().text() == toString(SUMO_ATTR_NUMBER)) {
158  baseObject->addIntAttribute(SUMO_ATTR_NUMBER, GNEAttributeCarrier::parse<int>(mySpacingTextField->getText().text()));
159  }
160  // other cases
161  if (myTerminateLabel->getText().text() == toString(SUMO_ATTR_NUMBER)) {
162  baseObject->addIntAttribute(SUMO_ATTR_NUMBER, GNEAttributeCarrier::parse<int>(myTerminateTextField->getText().text()));
163  }
164  if (mySpacingLabel->getText().text() == toString(myPerHourAttr)) {
165  baseObject->addTimeAttribute(myPerHourAttr, GNEAttributeCarrier::parse<SUMOTime>(mySpacingTextField->getText().text()));
166  }
167  if (mySpacingLabel->getText().text() == toString(SUMO_ATTR_PERIOD)) {
168  baseObject->addTimeAttribute(SUMO_ATTR_PERIOD, GNEAttributeCarrier::parse<SUMOTime>(mySpacingTextField->getText().text()));
169  }
170  if (mySpacingLabel->getText() == TL("rate")) {
171  baseObject->addTimeAttribute(GNE_ATTR_POISSON, GNEAttributeCarrier::parse<SUMOTime>(mySpacingTextField->getText().text()));
172  }
173  if (mySpacingLabel->getText().text() == toString(SUMO_ATTR_PROB)) {
174  baseObject->addDoubleAttribute(SUMO_ATTR_PROB, GNEAttributeCarrier::parse<double>(mySpacingTextField->getText().text()));
175  }
176 }
177 
178 
179 bool
181  // check text fields
182  if (myTerminateFrameTextField->shown() && (myTerminateTextField->getTextColor() == FXRGB(0, 0, 0)) &&
183  mySpacingFrameTextField->shown() && (mySpacingTextField->getTextColor() == FXRGB(0, 0, 0))) {
184  return true;
185  } else {
186  return false;
187  }
188 }
189 
190 
191 long
192 GNEFlowEditor::onCmdSetFlowAttribute(FXObject* obj, FXSelector, void*) {
193  // check number of flows
194  if (myEditedFlows.front()) {
195  // declare vectors for enable/disable attributes
196  std::vector<SumoXMLAttr> enableAttrs, disableAttrs;
197  // check if all spacing attributes are disabled
198  const bool spacingEnabled = myEditedFlows.front()->isAttributeEnabled(myPerHourAttr) ||
199  myEditedFlows.front()->isAttributeEnabled(SUMO_ATTR_PERIOD) ||
200  myEditedFlows.front()->isAttributeEnabled(GNE_ATTR_POISSON) ||
201  myEditedFlows.front()->isAttributeEnabled(SUMO_ATTR_PROB);
202  // get special case endNumber
203  const bool endNumber = (myTerminateComboBox->getText().text() == (toString(SUMO_ATTR_END) + "-" + toString(SUMO_ATTR_NUMBER)));
204  // get terminate attribute
205  SumoXMLAttr terminateAttribute = SUMO_ATTR_NOTHING;
206  if (myTerminateComboBox->getText().text() == toString(SUMO_ATTR_END) || endNumber) {
207  terminateAttribute = SUMO_ATTR_END;
208  } else if (myTerminateComboBox->getText().text() == toString(SUMO_ATTR_NUMBER)) {
209  terminateAttribute = SUMO_ATTR_NUMBER;
210  }
211  // get spacing attribute
212  SumoXMLAttr spacingAttribute = SUMO_ATTR_NOTHING;
213  if (endNumber) {
214  spacingAttribute = SUMO_ATTR_NUMBER;
215  } else if (mySpacingComboBox->getText().text() == toString(myPerHourAttr)) {
216  spacingAttribute = myPerHourAttr;
217  } else if (mySpacingComboBox->getText().text() == toString(SUMO_ATTR_PERIOD)) {
218  spacingAttribute = SUMO_ATTR_PERIOD;
219  } else if (mySpacingComboBox->getText().text() == toString(GNE_ATTR_POISSON)) {
220  spacingAttribute = GNE_ATTR_POISSON;
221  } else if (mySpacingComboBox->getText().text() == toString(SUMO_ATTR_PROB)) {
222  spacingAttribute = SUMO_ATTR_PROB;
223  }
224  // check if obj is a comboBox or a text field
225  if (obj == myTerminateComboBox) {
226  if (endNumber) {
227  enableAttrs.push_back(SUMO_ATTR_END);
228  enableAttrs.push_back(SUMO_ATTR_NUMBER);
229  // disable others
230  disableAttrs.push_back(myPerHourAttr);
231  disableAttrs.push_back(SUMO_ATTR_PERIOD);
232  disableAttrs.push_back(GNE_ATTR_POISSON);
233  disableAttrs.push_back(SUMO_ATTR_PROB);
234  // reset color
235  myTerminateComboBox->setTextColor(FXRGB(0, 0, 0));
236  myTerminateComboBox->killFocus();
237  } else if (terminateAttribute == SUMO_ATTR_END) {
238  enableAttrs.push_back(SUMO_ATTR_END);
239  disableAttrs.push_back(SUMO_ATTR_NUMBER);
240  // at least enable one spacing attribute
241  if (!spacingEnabled) {
242  enableAttrs.push_back(myPerHourAttr);
243  }
244  // reset color
245  myTerminateComboBox->setTextColor(FXRGB(0, 0, 0));
246  myTerminateComboBox->killFocus();
247  } else if (terminateAttribute == SUMO_ATTR_NUMBER) {
248  disableAttrs.push_back(SUMO_ATTR_END);
249  enableAttrs.push_back(SUMO_ATTR_NUMBER);
250  // at least enable one spacing attribute
251  if (!spacingEnabled) {
252  enableAttrs.push_back(myPerHourAttr);
253  }
254  // reset color
255  myTerminateComboBox->setTextColor(FXRGB(0, 0, 0));
256  myTerminateComboBox->killFocus();
257  } else {
258  // disable both
259  disableAttrs.push_back(SUMO_ATTR_END);
260  disableAttrs.push_back(SUMO_ATTR_NUMBER);
261  // set invalid color
262  myTerminateComboBox->setTextColor(FXRGB(255, 0, 0));
263  }
264  } else if (obj == mySpacingComboBox) {
265  if (spacingAttribute == myPerHourAttr) {
266  enableAttrs.push_back(myPerHourAttr);
267  disableAttrs.push_back(SUMO_ATTR_PERIOD);
268  disableAttrs.push_back(GNE_ATTR_POISSON);
269  disableAttrs.push_back(SUMO_ATTR_PROB);
270  // reset color
271  mySpacingComboBox->setTextColor(FXRGB(0, 0, 0));
272  mySpacingComboBox->killFocus();
273  } else if (spacingAttribute == SUMO_ATTR_PERIOD) {
274  disableAttrs.push_back(myPerHourAttr);
275  enableAttrs.push_back(SUMO_ATTR_PERIOD);
276  disableAttrs.push_back(GNE_ATTR_POISSON);
277  disableAttrs.push_back(SUMO_ATTR_PROB);
278  // reset color
279  mySpacingComboBox->setTextColor(FXRGB(0, 0, 0));
280  mySpacingComboBox->killFocus();
281  } else if (spacingAttribute == GNE_ATTR_POISSON) {
282  disableAttrs.push_back(myPerHourAttr);
283  disableAttrs.push_back(SUMO_ATTR_PERIOD);
284  enableAttrs.push_back(GNE_ATTR_POISSON);
285  disableAttrs.push_back(SUMO_ATTR_PROB);
286  // reset color
287  mySpacingComboBox->setTextColor(FXRGB(0, 0, 0));
288  mySpacingComboBox->killFocus();
289  } else if (spacingAttribute == SUMO_ATTR_PROB) {
290  disableAttrs.push_back(myPerHourAttr);
291  disableAttrs.push_back(SUMO_ATTR_PERIOD);
292  disableAttrs.push_back(GNE_ATTR_POISSON);
293  enableAttrs.push_back(SUMO_ATTR_PROB);
294  // reset color
295  mySpacingComboBox->setTextColor(FXRGB(0, 0, 0));
296  mySpacingComboBox->killFocus();
297  } else {
298  // disable all
299  disableAttrs.push_back(myPerHourAttr);
300  disableAttrs.push_back(SUMO_ATTR_PERIOD);
301  disableAttrs.push_back(GNE_ATTR_POISSON);
302  disableAttrs.push_back(SUMO_ATTR_PROB);
303  // set invalid color
304  mySpacingComboBox->setTextColor(FXRGB(255, 0, 0));
305  }
306  } else if ((obj == myTerminateTextField) && (terminateAttribute != SUMO_ATTR_NOTHING)) {
307  if (myEditedFlows.front()->isValid(terminateAttribute, myTerminateTextField->getText().text())) {
308  // continue depending of flow
309  if (myEditedFlows.front()->isTemplate()) {
310  // change attribute directly
311  myEditedFlows.front()->setAttribute(terminateAttribute, myTerminateTextField->getText().text());
312  } else if (myEditedFlows.size() == 1) {
313  // change using undoList
314  myEditedFlows.front()->setAttribute(terminateAttribute, myTerminateTextField->getText().text(), myViewNet->getUndoList());
315  } else {
316  // change all flows using undoList
317  myViewNet->getUndoList()->begin(myEditedFlows.front(), "change multiple flow attributes");
318  for (const auto& flow : myEditedFlows) {
319  flow->setAttribute(terminateAttribute, myTerminateTextField->getText().text(), myViewNet->getUndoList());
320  }
321  myViewNet->getUndoList()->end();
322  }
323  // reset color
324  myTerminateTextField->setTextColor(FXRGB(0, 0, 0));
325  myTerminateTextField->killFocus();
326  } else {
327  // set invalid color
328  myTerminateTextField->setTextColor(FXRGB(255, 0, 0));
329  // stop
330  return 1;
331  }
332  } else if ((obj == mySpacingTextField) && (spacingAttribute != SUMO_ATTR_NOTHING)) {
333  if (myEditedFlows.front()->isValid(spacingAttribute, mySpacingTextField->getText().text())) {
334  // continue depending of flow
335  if (myEditedFlows.front()->isTemplate()) {
336  // change attribute directly
337  myEditedFlows.front()->setAttribute(spacingAttribute, mySpacingTextField->getText().text());
338  } else if (myEditedFlows.size() == 1) {
339  // change using undoList
340  myEditedFlows.front()->setAttribute(spacingAttribute, mySpacingTextField->getText().text(), myViewNet->getUndoList());
341  } else {
342  // change all flows using undoList
343  myViewNet->getUndoList()->begin(myEditedFlows.front(), TL("change multiple flow attributes"));
344  for (const auto& flow : myEditedFlows) {
345  flow->setAttribute(spacingAttribute, mySpacingTextField->getText().text(), myViewNet->getUndoList());
346  }
347  myViewNet->getUndoList()->end();
348  }
349  // reset color
350  mySpacingTextField->setTextColor(FXRGB(0, 0, 0));
351  mySpacingTextField->killFocus();
352  } else {
353  // set invalid color
354  mySpacingTextField->setTextColor(FXRGB(255, 0, 0));
355  // stop
356  return 1;
357  }
358  }
359  // enable and disable attributes
360  for (const auto& attr : enableAttrs) {
361  if (myEditedFlows.front()->isTemplate()) {
362  // enable directly
363  myEditedFlows.front()->toggleAttribute(attr, true);
364  } else if (myEditedFlows.size() == 1) {
365  // enable using undoList
366  myEditedFlows.front()->enableAttribute(attr, myViewNet->getUndoList());
367  } else {
368  // enable in all flow using undoList
369  myViewNet->getUndoList()->begin(myEditedFlows.front(), TL("enable multiple flow attributes"));
370  for (const auto& flow : myEditedFlows) {
371  flow->enableAttribute(attr, myViewNet->getUndoList());
372  }
373  myViewNet->getUndoList()->end();
374  }
375  }
376  for (const auto& attr : disableAttrs) {
377  if (myEditedFlows.front()->isTemplate()) {
378  // disable directly
379  myEditedFlows.front()->toggleAttribute(attr, false);
380  } else if (myEditedFlows.size() == 1) {
381  // disable using undoList
382  myEditedFlows.front()->disableAttribute(attr, myViewNet->getUndoList());
383  } else {
384  // disable in all flow using undoList
385  myViewNet->getUndoList()->begin(myEditedFlows.front(), TL("disable multiple flow attributes"));
386  for (const auto& flow : myEditedFlows) {
387  flow->disableAttribute(attr, myViewNet->getUndoList());
388  }
389  myViewNet->getUndoList()->end();
390  }
391  }
392  // refresh flow editor
394  }
395  return 1;
396 }
397 
398 
399 void
401  // get flow (only for code legibly)
402  const auto flow = myEditedFlows.front();
403  // continue depending of combinations
404  if (flow->isAttributeEnabled(SUMO_ATTR_END) && flow->isAttributeEnabled(SUMO_ATTR_NUMBER)) {
405  // set first comboBox
407  // hide second comboBox
408  mySpacingFrameComboBox->hide();
409  // set label
410  myTerminateLabel->setText(toString(SUMO_ATTR_END).c_str());
411  myTerminateLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_END).getDefinition().c_str());
412  mySpacingLabel->setText(toString(SUMO_ATTR_NUMBER).c_str());
413  mySpacingLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_NUMBER).getDefinition().c_str());
414  // set text fields
417  } else {
418  // show second comboBox
419  mySpacingFrameComboBox->show();
420  // set first attribute
421  if (myTerminateComboBox->getTextColor() == FXRGB(255, 0, 0)) {
422  // invalid combination, disable text field
424  } else if (flow->isAttributeEnabled(SUMO_ATTR_END)) {
425  // set first comboBox
427  // set label
428  myTerminateLabel->setText(toString(SUMO_ATTR_END).c_str());
429  // set definition
430  myTerminateLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_END).getDefinition().c_str());
431  // set text fields
433  } else if (flow->isAttributeEnabled(SUMO_ATTR_NUMBER)) {
434  // set first comboBox
436  // set label
437  myTerminateLabel->setText(toString(SUMO_ATTR_NUMBER).c_str());
438  // set definition
439  myTerminateLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_NUMBER).getDefinition().c_str());
440  // set text fields
442  }
443  // set second attribute
444  if (mySpacingComboBox->getTextColor() == FXRGB(255, 0, 0)) {
445  // invalid combination, disable text field
446  mySpacingFrameTextField->hide();
447  } else if (flow->isAttributeEnabled(myPerHourAttr)) {
448  // set first comboBox
450  // set label
451  mySpacingLabel->setText(toString(myPerHourAttr).c_str());
452  // set tip text
453  mySpacingLabel->setTipText(flow->getTagProperty().getAttributeProperties(myPerHourAttr).getDefinition().c_str());
454  // set text fields
456  } else if (flow->isAttributeEnabled(SUMO_ATTR_PERIOD)) {
457  // set first comboBox
459  // set label
460  mySpacingLabel->setText(toString(SUMO_ATTR_PERIOD).c_str());
461  // set tip text
462  mySpacingLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_PERIOD).getDefinition().c_str());
463  // set text fields
465  } else if (flow->isAttributeEnabled(GNE_ATTR_POISSON)) {
466  // set first comboBox
468  // set label
469  mySpacingLabel->setText(TL("rate"));
470  // set definition
471  mySpacingLabel->setTipText(flow->getTagProperty().getAttributeProperties(GNE_ATTR_POISSON).getDefinition().c_str());
472  // set text fields
474  } else if (flow->isAttributeEnabled(SUMO_ATTR_PROB)) {
475  // set first comboBox
477  // set label
478  mySpacingLabel->setText(toString(SUMO_ATTR_PROB).c_str());
479  // set tip text
480  mySpacingLabel->setTipText(flow->getTagProperty().getAttributeProperties(SUMO_ATTR_PROB).getDefinition().c_str());
481  // set text fields
483  }
484  }
485 }
486 
487 
488 void
490  // get first flow (only for code legibly)
491  const auto editedFlow = myEditedFlows.front();
492  // get values of first flow
493  const bool end = editedFlow->isAttributeEnabled(SUMO_ATTR_END);
494  const bool number = editedFlow->isAttributeEnabled(SUMO_ATTR_NUMBER);
495  const bool perhour = editedFlow->isAttributeEnabled(myPerHourAttr);
496  const bool period = editedFlow->isAttributeEnabled(SUMO_ATTR_PERIOD);
497  const bool poisson = editedFlow->isAttributeEnabled(GNE_ATTR_POISSON);
498  const bool probability = editedFlow->isAttributeEnabled(SUMO_ATTR_PROB);
499  // we need to check if attributes are defined differents in flows
500  std::vector<std::string> terminateDifferent;
501  std::vector<std::string> spacingDifferent;
502  // iterate over all flows
503  for (const auto& flow : myEditedFlows) {
504  if (flow->isAttributeEnabled(SUMO_ATTR_END) != end) {
505  terminateDifferent.push_back(toString(SUMO_ATTR_END));
506  }
507  if (flow->isAttributeEnabled(SUMO_ATTR_NUMBER) != number) {
508  terminateDifferent.push_back(toString(SUMO_ATTR_NUMBER));
509  }
510  if (flow->isAttributeEnabled(myPerHourAttr) != perhour) {
511  spacingDifferent.push_back(toString(myPerHourAttr));
512  }
513  if (flow->isAttributeEnabled(SUMO_ATTR_PERIOD) != period) {
514  spacingDifferent.push_back(toString(SUMO_ATTR_PERIOD));
515  }
516  if (flow->isAttributeEnabled(GNE_ATTR_POISSON) != poisson) {
517  spacingDifferent.push_back(toString(GNE_ATTR_POISSON));
518  }
519  if (flow->isAttributeEnabled(SUMO_ATTR_PROB) != probability) {
520  spacingDifferent.push_back(toString(SUMO_ATTR_PROB));
521  }
522  }
523  // special case for end and number
524  if (end && number && terminateDifferent.empty() && spacingDifferent.empty()) {
525  // set first comboBox
527  // hide second comboBox
528  mySpacingFrameComboBox->hide();
529  // set label
530  myTerminateLabel->setText(toString(SUMO_ATTR_END).c_str());
531  mySpacingLabel->setText(toString(SUMO_ATTR_NUMBER).c_str());
532  // set text fields
535  } else {
536  // show second comboBox
537  mySpacingFrameComboBox->show();
538  // check terminateDifferent
539  if (terminateDifferent.size() > 0) {
540  myTerminateComboBox->setText((TL("different: ") + terminateDifferent.front() + " " + terminateDifferent.back()).c_str());
541  // hide textField
543  } else {
544  // show textField
546  // set first attribute
547  if (myTerminateComboBox->getTextColor() == FXRGB(255, 0, 0)) {
548  // invalid combination, disable text field
550  } else if (end) {
551  // set first comboBox
553  // set label
554  myTerminateLabel->setText(toString(SUMO_ATTR_END).c_str());
555  // set text fields
557  } else if (number) {
558  // set first comboBox
560  // set label
561  myTerminateLabel->setText(toString(SUMO_ATTR_NUMBER).c_str());
562  // set text fields
564  }
565  }
566  // check terminateDifferent
567  if (spacingDifferent.size() > 0) {
568  mySpacingComboBox->setText((TL("different: ") + spacingDifferent.front() + " " + spacingDifferent.back()).c_str());
569  // hide textField
570  mySpacingFrameTextField->hide();
571  } else {
572  // show textField
573  mySpacingFrameTextField->show();
574  // set second attribute
575  if (mySpacingComboBox->getTextColor() == FXRGB(255, 0, 0)) {
576  // invalid combination, disable text field
577  mySpacingFrameTextField->hide();
578  } else if (perhour) {
579  // set first comboBox
581  // set label
582  mySpacingLabel->setText(toString(myPerHourAttr).c_str());
583  // set text fields
585  } else if (period) {
586  // set first comboBox
588  // set label
589  mySpacingLabel->setText(toString(SUMO_ATTR_PERIOD).c_str());
590  // set text fields
592  } else if (poisson) {
593  // set first comboBox
595  // set label
596  mySpacingLabel->setText(TL("rate"));
597  // set text fields
599  } else if (probability) {
600  // set first comboBox
602  // set label
603  mySpacingLabel->setText(toString(SUMO_ATTR_PROB).c_str());
604  // set text fields
606  }
607  }
608  }
609 }
610 
611 
612 const std::string
614  if (myEditedFlows.size() == 1) {
615  return myEditedFlows.front()->getAttribute(attr);
616  } else {
617  std::string solution;
618  std::set<std::string> values;
619  // extract all values (avoiding duplicated)
620  for (const auto& flow : myEditedFlows) {
621  values.insert(flow->getAttribute(attr));
622  }
623  // insert value and space
624  for (const auto& value : values) {
625  solution.append(value + " ");
626  }
627  // remove last space
628  if (solution.size() > 0) {
629  solution.pop_back();
630  }
631  return solution;
632  }
633 }
634 
635 
636 /****************************************************************************/
FXDEFMAP(GNEFlowEditor) FlowEditorMap[]
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition: GUIAppEnum.h:930
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:308
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:317
#define GUIDesignTextField
Definition: GUIDesigns.h:65
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:405
#define GUIDesignComboBoxVisibleItemsMedium
combo box medium small
Definition: GUIDesigns.h:53
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:80
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition: GUIDesigns.h:258
#define TL(string)
Definition: MsgHandler.h:315
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_VEHSPERHOUR
@ GNE_ATTR_POISSON
poisson definition (used in flow)
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_PROB
@ SUMO_ATTR_NOTHING
invalid attribute
@ SUMO_ATTR_PERSONSPERHOUR
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void addIntAttribute(const SumoXMLAttr attr, const int value)
add int attribute into current SumoBaseObject node
void addTimeAttribute(const SumoXMLAttr attr, const SUMOTime value)
add time attribute into current SumoBaseObject node
void addDoubleAttribute(const SumoXMLAttr attr, const double value)
add double attribute into current SumoBaseObject node
void getFlowAttributes(CommonXMLStructure::SumoBaseObject *baseObject)
get flow attributes
long onCmdSetFlowAttribute(FXObject *, FXSelector, void *)
void refreshSingleFlow()
refresh single flow
MFXLabelTooltip * mySpacingLabel
Label for spacing.
FXTextField * myTerminateTextField
textField for terminate attribute
Definition: GNEFlowEditor.h:99
MFXComboBoxIcon * myTerminateComboBox
ComboBox for terminate options (end, number, end/number)
Definition: GNEFlowEditor.h:90
SumoXMLAttr myPerHourAttr
per hours attr (vehicles/person/container)
MFXComboBoxIcon * mySpacingComboBox
ComboBox for spacing comboBox (perHour, period, probability)
GNEViewNet * myViewNet
pointer to viewNet
Definition: GNEFlowEditor.h:87
const std::string getFlowAttribute(SumoXMLAttr attr)
get flow attribute (of the current edited flows)
void refreshFlowEditor()
refresh GNEFlowEditor
FXHorizontalFrame * mySpacingFrameTextField
horizontal frame for spacing textField
MFXLabelTooltip * myTerminateLabel
Label for terminate definition.
Definition: GNEFlowEditor.h:96
~GNEFlowEditor()
destructor
void hideFlowEditor()
hide group box
FXTextField * mySpacingTextField
textField for spacing attribute
std::vector< GNEAttributeCarrier * > myEditedFlows
edited flows
void showFlowEditor(const std::vector< GNEAttributeCarrier * > editedFlows)
show GNEFlowEditor modul
void refreshMultipleFlows()
refresh multiple flows
bool shownFlowEditor() const
shown GNEFlowEditor modul
FXHorizontalFrame * mySpacingFrameComboBox
horizontal frame for terminate options
FXHorizontalFrame * myTerminateFrameTextField
horizontal frame for terminate definition
Definition: GNEFlowEditor.h:93
bool areFlowValuesValid() const
check if parameters of attributes are valid
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
GNEUndoList * getUndoList() const
get the undoList object
ComboBox with icon.
long setCurrentItem(const FXint index, FXbool notify=FALSE)
Set the current item (index is zero-based)
FXString getText() const
Get the text.
void setTextColor(FXColor clr)
Change text color.
void clearItems()
Remove all items from the list.
void setText(const FXString &text)
Set the text in the textField.
FXColor getTextColor() const
Return text color.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
MFXGroupBoxModule (based on FXGroupBox)