SUMO - Simulation of Urban MObility
GNECalibratorDialog.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Dialog for edit calibrators
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <iostream>
30 #include <netedit/GNEViewNet.h>
31 #include <netedit/GNEUndoList.h>
36 
37 #include <netedit/GNENet.h>
38 #include "GNECalibratorDialog.h"
42 
43 // ===========================================================================
44 // FOX callback mapping
45 // ===========================================================================
46 
47 FXDEFMAP(GNECalibratorDialog) GNECalibratorDialogMap[] = {
54 };
55 
56 // Object implementation
57 FXIMPLEMENT(GNECalibratorDialog, GNEAdditionalDialog, GNECalibratorDialogMap, ARRAYNUMBER(GNECalibratorDialogMap))
58 
59 // ===========================================================================
60 // member method definitions
61 // ===========================================================================
62 
64  GNEAdditionalDialog(editedCalibrator, false, 640, 480) {
65 
66  // Create two columns, one for Routes and VehicleTypes, and other for Flows
67  FXHorizontalFrame* columns = new FXHorizontalFrame(myContentFrame, GUIDesignUniformHorizontalFrame);
68  FXVerticalFrame* columnLeft = new FXVerticalFrame(columns, GUIDesignAuxiliarFrame);
69  FXVerticalFrame* columnRight = new FXVerticalFrame(columns, GUIDesignAuxiliarFrame);
70 
71  // create add buton and label for routes
72  FXHorizontalFrame* buttonAndLabelRoute = new FXHorizontalFrame(columnLeft, GUIDesignAuxiliarHorizontalFrame);
73  myAddRoute = new FXButton(buttonAndLabelRoute, "", GUIIconSubSys::getIcon(ICON_ADD), this, MID_GNE_CALIBRATORDIALOG_ADD_ROUTE, GUIDesignButtonIcon);
74  new FXLabel(buttonAndLabelRoute, ("Add new " + toString(SUMO_TAG_ROUTE) + "s").c_str(), nullptr, GUIDesignLabelThick);
75 
76  // Create table in left frame
77  myRouteList = new FXTable(columnLeft, this, MID_GNE_CALIBRATORDIALOG_TABLE_ROUTE, GUIDesignTableAdditionals);
78  myRouteList->setSelBackColor(FXRGBA(255, 255, 255, 255));
79  myRouteList->setSelTextColor(FXRGBA(0, 0, 0, 255));
80  myRouteList->setEditable(false);
81 
82  // create add buton and label for vehicle types
83  FXHorizontalFrame* buttonAndLabelVehicleType = new FXHorizontalFrame(columnLeft, GUIDesignAuxiliarHorizontalFrame);
84  myAddVehicleType = new FXButton(buttonAndLabelVehicleType, "", GUIIconSubSys::getIcon(ICON_ADD), this, MID_GNE_CALIBRATORDIALOG_ADD_VEHICLETYPE, GUIDesignButtonIcon);
85  new FXLabel(buttonAndLabelVehicleType, ("Add new " + toString(SUMO_TAG_VTYPE) + "s").c_str(), nullptr, GUIDesignLabelThick);
86 
87  // Create table in left frame
88  myVehicleTypeList = new FXTable(columnLeft, this, MID_GNE_CALIBRATORDIALOG_TABLE_VEHICLETYPE, GUIDesignTableAdditionals);
89  myVehicleTypeList->setSelBackColor(FXRGBA(255, 255, 255, 255));
90  myVehicleTypeList->setSelTextColor(FXRGBA(0, 0, 0, 255));
91  myVehicleTypeList->setEditable(false);
92 
93  // create add buton and label for flows in right frame
94  FXHorizontalFrame* buttonAndLabelFlow = new FXHorizontalFrame(columnRight, GUIDesignAuxiliarHorizontalFrame);
95  myAddFlow = new FXButton(buttonAndLabelFlow, "", GUIIconSubSys::getIcon(ICON_ADD), this, MID_GNE_CALIBRATORDIALOG_ADD_FLOW, GUIDesignButtonIcon);
96  myLabelFlow = new FXLabel(buttonAndLabelFlow, ("Add new " + toString(SUMO_TAG_FLOW) + "s").c_str(), nullptr, GUIDesignLabelThick);
97 
98  // Create table in right frame
99  myFlowList = new FXTable(columnRight, this, MID_GNE_CALIBRATORDIALOG_TABLE_FLOW, GUIDesignTableAdditionals);
100  myFlowList->setSelBackColor(FXRGBA(255, 255, 255, 255));
101  myFlowList->setSelTextColor(FXRGBA(0, 0, 0, 255));
102  myFlowList->setEditable(false);
103 
104  // update tables
105  updateRouteTable();
106  updateVehicleTypeTable();
107  updateFlowTable();
108 
109  // start a undo list for editing local to this additional
110  initChanges();
111 
112  // Open dialog as modal
113  openAsModalDialog();
114 }
115 
116 
118 
119 
120 long
121 GNECalibratorDialog::onCmdAccept(FXObject*, FXSelector, void*) {
122  // accept changes before closing dialog
123  acceptChanges();
124  // Stop Modal
125  getApp()->stopModal(this, TRUE);
126  return 1;
127 }
128 
129 
130 long
131 GNECalibratorDialog::onCmdCancel(FXObject*, FXSelector, void*) {
132  // cancel changes
133  cancelChanges();
134  // Stop Modal
135  getApp()->stopModal(this, FALSE);
136  return 1;
137 }
138 
139 
140 long
141 GNECalibratorDialog::onCmdReset(FXObject*, FXSelector, void*) {
142  // reset changes
143  resetChanges();
144  // update tables
147  updateFlowTable();
148  return 1;
149 }
150 
151 
152 long
153 GNECalibratorDialog::onCmdAddRoute(FXObject*, FXSelector, void*) {
154  // create nes calibrator route and configure it with GNECalibratorRouteDialog
156  // update routes table
158  return 1;
159 }
160 
161 
162 long
163 GNECalibratorDialog::onCmdClickedRoute(FXObject*, FXSelector, void*) {
164  // check if some delete button was pressed
165  for (int i = 0; i < (int)myEditedAdditional->getViewNet()->getNet()->getAdditionalByType(SUMO_TAG_ROUTE).size(); i++) {
166  // obtain rerouter
167  GNEAdditional* routeToEdit = myEditedAdditional->getViewNet()->getNet()->retrieveAdditional(SUMO_TAG_ROUTE, myRouteList->getItem(i, 0)->getText().text());
168  if (myRouteList->getItem(i, 2)->hasFocus()) {
169  // find all flows that contains route to delete as "route" parameter
170  std::vector<GNEAdditional*> calibratorFlowsToErase;
171  for (auto j : myEditedAdditional->getAdditionalChilds()) {
172  if (j->getAttribute(SUMO_ATTR_ROUTE) == myRouteList->getItem(i, 0)->getText().text()) {
173  calibratorFlowsToErase.push_back(j);
174  }
175  }
176  // if there are flows that has route to remove as "route" parameter
177  if (calibratorFlowsToErase.size() > 0) {
178  // write warning if netedit is running in testing mode
179  WRITE_DEBUG("Opening FXMessageBox of type 'question'");
180  // open question dialog box
181  std::string message = ("Deletio n of " + toString(SUMO_TAG_ROUTE) + " '" + myRouteList->getItem(i, 0)->getText().text() + "' will remove " +
182  toString(calibratorFlowsToErase.size()) + " " + toString(SUMO_TAG_FLOW) + (calibratorFlowsToErase.size() > 1 ? ("s") : ("")) + ". Continue?");
183  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO, ("Remove " + toString(SUMO_TAG_FLOW) + "s").c_str(), "%s", message.c_str());
184  if (answer != 1) { //1:yes, 2:no, 4:esc
185  // write warning if netedit is running in testing mode
186  if (answer == 2) {
187  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'No'");
188  } else if (answer == 4) {
189  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'ESC'");
190  }
191  // abort deletion of route
192  return 0;
193  } else {
194  // write warning if netedit is running in testing mode
195  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'Yes'");
196  // remove affected flows of calibrator flows
197  for (auto j : calibratorFlowsToErase) {
198  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(j, false), true);
199  }
200  // remove route of calibrator routes
201  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeToEdit, false), true);
202  // update flows and route table
203  updateFlowTable();
205  return 1;
206  }
207  } else {
208  // remove route
209  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeToEdit, false), true);
210  // update routes table
212  return 1;
213  }
214  } else if (myRouteList->getItem(i, 0)->hasFocus() || myRouteList->getItem(i, 1)->hasFocus()) {
215  // modify route of calibrator routes
216  GNECalibratorRouteDialog(routeToEdit, true);
217  // update routes table
219  // update Flows routes also because Route ID could be changed
220  updateFlowTable();
221  return 1;
222  }
223  }
224  // nothing to do
225  return 0;
226 }
227 
228 
229 long
230 GNECalibratorDialog::onCmdAddFlow(FXObject*, FXSelector, void*) {
231  // only add flow if there is CalibratorRoutes and Calibrator vehicle types
233  // create new calibrator and configure it with GNECalibratorFlowDialog
235  // update flows table
236  updateFlowTable();
237  return 1;
238  } else {
239  throw ProcessError("myEditedAdditional->getViewNet()->getNet()->getAdditionalByType(SUMO_TAG_ROUTE) cannot be empty");
240  }
241 }
242 
243 
244 long
245 GNECalibratorDialog::onCmdClickedFlow(FXObject*, FXSelector, void*) {
246  // check if some delete button was pressed
247  for (int i = 0; i < (int)myEditedAdditional->getAdditionalChilds().size(); i++) {
248  if (myFlowList->getItem(i, 2)->hasFocus()) {
249  // remove flow of calibrator flows
251  // update flows table
252  updateFlowTable();
253  return 1;
254  } else if (myFlowList->getItem(i, 0)->hasFocus() || myFlowList->getItem(i, 1)->hasFocus()) {
255  // modify flow of calibrator flows (temporal)
257  // update flows table
258  updateFlowTable();
259  return 1;
260  }
261  }
262  // nothing to do
263  return 0;
264 }
265 
266 
267 long
268 GNECalibratorDialog::onCmdAddVehicleType(FXObject*, FXSelector, void*) {
269  // create new calibrator flow and configure it with GNECalibratorVehicleTypeDialog
271  // update vehicle types table
273  return 1;
274 }
275 
276 
277 long
278 GNECalibratorDialog::onCmdClickedVehicleType(FXObject*, FXSelector, void*) {
279  // check if some delete button was pressed
280  for (int i = 0; i < (int)myEditedAdditional->getViewNet()->getNet()->getAdditionalByType(SUMO_TAG_VTYPE).size(); i++) {
281  // obtain vehicle type
282  GNEAdditional* vType = myEditedAdditional->getViewNet()->getNet()->retrieveAdditional(SUMO_TAG_VTYPE, myVehicleTypeList->getItem(i, 0)->getText().text());
283  // Make sure that default vehicle isn't edited
284  if ((i == 0) && (myVehicleTypeList->getItem(i, 0)->hasFocus() || myVehicleTypeList->getItem(i, 1)->hasFocus() || myVehicleTypeList->getItem(i, 2)->hasFocus())) {
285  FXMessageBox::warning(getApp(), MBOX_OK,
286  ("Error editing default " + toString(SUMO_TAG_VTYPE)).c_str(), "%s",
287  ("Default " + toString(SUMO_TAG_VTYPE) + " cannot be either edited or deleted.").c_str());
288  } else if (myVehicleTypeList->getItem(i, 2)->hasFocus()) {
289  // find all flows that contains vehicle type to delete as "vehicle type" parameter
290  std::vector<GNEAdditional*> calibratorFlowsToErase;
291  for (auto j : myEditedAdditional->getAdditionalChilds()) {
292  if (j->getAttribute(SUMO_ATTR_TYPE) == myVehicleTypeList->getItem(i, 0)->getText().text()) {
293  calibratorFlowsToErase.push_back(j);
294  }
295  }
296  // if there are flows that has vehicle type to remove as "vehicle type" parameter
297  if (calibratorFlowsToErase.size() > 0) {
298  std::string message = ("Deletion of " + toString(SUMO_TAG_VTYPE) + " '" + myVehicleTypeList->getItem(i, 0)->getText().text() + "' will remove " +
299  toString(calibratorFlowsToErase.size()) + " " + toString(SUMO_TAG_FLOW) + (calibratorFlowsToErase.size() > 1 ? ("s") : ("")) + ". Continue?");
300  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO, ("Remove " + toString(SUMO_TAG_FLOW) + "s").c_str(), "%s", message.c_str());
301  if (answer != 1) { //1:yes, 2:no, 4:esc
302  // write warning if netedit is running in testing mode
303  if (answer == 2) {
304  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'No'");
305  } else if (answer == 4) {
306  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'ESC'");
307  }
308  // abort deletion of vehicle type
309  return 0;
310  } else {
311  // write warning if netedit is running in testing mode
312  WRITE_DEBUG("Closed FXMessageBox of type 'question' with 'Yes'");
313  // remove affected flows of calibrator flows
314  for (auto j : calibratorFlowsToErase) {
315  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(j, false), true);
316  }
317  // remove vehicle type of calibrator vehicle types
318  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(vType, false), true);
319  // update flows and vehicle types table
320  updateFlowTable();
322  return 1;
323  }
324  } else {
325  // remove vehicle type of calibrator vehicle types
326  myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(vType, false), true);
327  // update vehicle types table
329  return 1;
330  }
331  } else if (myVehicleTypeList->getItem(i, 0)->hasFocus() || myVehicleTypeList->getItem(i, 1)->hasFocus()) {
332  // modify vehicle type of calibratorVehicleTypes
333  GNECalibratorVehicleTypeDialog(vType, true);
334  // update vehicle types table
336  // update Flows routes also because VType ID could be changed
337  updateFlowTable();
338  return 1;
339  }
340  }
341  // nothing to do
342  return 0;
343 }
344 
345 
346 void
348  // clear table
349  myRouteList->clearItems();
350  // set number of rows
352  // Configure list
353  myRouteList->setVisibleColumns(4);
354  myRouteList->setColumnWidth(0, 136);
355  myRouteList->setColumnWidth(1, 136);
356  myRouteList->setColumnWidth(2, GUIDesignTableIconCellWidth);
357  myRouteList->setColumnText(0, toString(SUMO_ATTR_ID).c_str());
358  myRouteList->setColumnText(1, toString(SUMO_ATTR_EDGES).c_str());
359  myRouteList->setColumnText(2, "");
360  myRouteList->getRowHeader()->setWidth(0);
361  // Declare index for rows and pointer to FXTableItem
362  int indexRow = 0;
363  FXTableItem* item = nullptr;
364  // iterate over routes
366  // Set ID
367  item = new FXTableItem(toString(i.second->getAttribute(SUMO_ATTR_ID)).c_str());
368  myRouteList->setItem(indexRow, 0, item);
369  // Set edges
370  item = new FXTableItem(toString(i.second->getAttribute(SUMO_ATTR_EDGES)).c_str());
371  myRouteList->setItem(indexRow, 1, item);
372  // set remove
373  item = new FXTableItem("", GUIIconSubSys::getIcon(ICON_REMOVE));
374  item->setJustify(FXTableItem::CENTER_X | FXTableItem::CENTER_Y);
375  item->setEnabled(false);
376  myRouteList->setItem(indexRow, 2, item);
377  // Update index
378  indexRow++;
379  }
380  // enable or disable flow and label button
382 }
383 
384 
385 void
387  // clear table
388  myFlowList->clearItems();
389  // set number of rows
390  myFlowList->setTableSize(int(myEditedAdditional->getAdditionalChilds().size()), 3);
391  // Configure list
392  myFlowList->setVisibleColumns(3);
393  myFlowList->setColumnWidth(0, 136);
394  myFlowList->setColumnWidth(1, 136);
395  myFlowList->setColumnWidth(2, GUIDesignTableIconCellWidth);
396  myFlowList->setColumnText(0, toString(SUMO_ATTR_TYPE).c_str());
397  myFlowList->setColumnText(1, toString(SUMO_ATTR_VCLASS).c_str());
398  myFlowList->setColumnText(2, "");
399  myFlowList->getRowHeader()->setWidth(0);
400  // Declare index for rows and pointer to FXTableItem
401  int indexRow = 0;
402  FXTableItem* item = nullptr;
403  // iterate over flows
404  for (auto i : myEditedAdditional->getAdditionalChilds()) {
405  // Set vehicle type
406  item = new FXTableItem(i->getAttribute(SUMO_ATTR_TYPE).c_str());
407  myFlowList->setItem(indexRow, 0, item);
408  // Set route
409  item = new FXTableItem(i->getAttribute(SUMO_ATTR_ROUTE).c_str());
410  myFlowList->setItem(indexRow, 1, item);
411  // set remove
412  item = new FXTableItem("", GUIIconSubSys::getIcon(ICON_REMOVE));
413  item->setJustify(FXTableItem::CENTER_X | FXTableItem::CENTER_Y);
414  item->setEnabled(false);
415  myFlowList->setItem(indexRow, 2, item);
416  // Update index
417  indexRow++;
418  }
419  // enable or disable flow and label button
421 }
422 
423 
424 void
426  // clear table
427  myVehicleTypeList->clearItems();
428  // set number of rows
430  // Configure list
431  myVehicleTypeList->setVisibleColumns(4);
432  myVehicleTypeList->setColumnWidth(0, 136);
433  myVehicleTypeList->setColumnWidth(1, 136);
435  myVehicleTypeList->setColumnText(0, toString(SUMO_ATTR_ID).c_str());
436  myVehicleTypeList->setColumnText(1, toString(SUMO_ATTR_VCLASS).c_str());
437  myVehicleTypeList->setColumnText(2, "");
438  myVehicleTypeList->getRowHeader()->setWidth(0);
439  // Declare index for rows and pointer to FXTableItem
440  int indexRow = 0;
441  FXTableItem* item = nullptr;
442  // iterate over vehicle types
444  // Set id
445  item = new FXTableItem(i.second->getAttribute(SUMO_ATTR_ID).c_str());
446  myVehicleTypeList->setItem(indexRow, 0, item);
447  // Set VClass
448  item = new FXTableItem(i.second->getAttribute(SUMO_ATTR_VCLASS).c_str());
449  myVehicleTypeList->setItem(indexRow, 1, item);
450  // set remove icon except for default vehicle type
451  if (indexRow != 0) {
452  item = new FXTableItem("", GUIIconSubSys::getIcon(ICON_REMOVE));
453  } else {
454  item = new FXTableItem("");
455  }
456  item->setJustify(FXTableItem::CENTER_X | FXTableItem::CENTER_Y);
457  item->setEnabled(false);
458  myVehicleTypeList->setItem(indexRow, 2, item);
459  // Update index
460  indexRow++;
461  }
462  // enable or disable flow and label button
464 }
465 
466 
467 void
469  // disable AddFlow button if no route is defined
471  myAddFlow->disable();
472  myFlowList->disable();
473  myLabelFlow->setText("No routes defined");
474  } else {
475  myAddFlow->enable();
476  myFlowList->enable();
477  myLabelFlow->setText(("Add new " + toString(SUMO_TAG_FLOW) + "s").c_str());
478  }
479 }
480 
481 /****************************************************************************/
void updateFlowTable()
update data table with flows
#define GUIDesignTableIconCellWidth
width of cells that only contains an Icon
Definition: GUIDesigns.h:450
void resetChanges()
reset changes did in this dialog.
description of a vehicle type
FXButton * myAddFlow
button for add new flow
a flow definition (used by router)
long onCmdAddVehicleType(FXObject *, FXSelector, void *)
add new vehicle type
Dialog to edit sequences, parameters, etc.. of Additionals.
long onCmdAddRoute(FXObject *, FXSelector, void *)
add new route
FXTable * myFlowList
list with flows
void updateRouteTable()
update data table with routes
FXLabel * myLabelFlow
label for flows
begin/end of the description of a route
void updateFlowAndLabelButton()
update flow and label button
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:1785
long onCmdReset(FXObject *, FXSelector, void *)
event after press reset button
FXTable * myRouteList
list with routes
GNEUndoList * getUndoList() const
get the undoList object
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frames used to pack another frames extended in all directions ...
Definition: GUIDesigns.h:258
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
#define GUIDesignUniformHorizontalFrame
design for horizontal frame used to pack another frames with a uniform width
Definition: GUIDesigns.h:267
long onCmdClickedRoute(FXObject *, FXSelector, void *)
remove or edit route
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames ...
Definition: GUIDesigns.h:261
FXTable * myVehicleTypeList
list with vehicle types
Dialog for edit rerouter intervals.
long onCmdClickedFlow(FXObject *, FXSelector, void *)
remove or edit flow
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:248
void updateVehicleTypeTable()
update data table with vehicle types
long onCmdAddFlow(FXObject *, FXSelector, void *)
add new flow
#define GUIDesignTableAdditionals
design for tables used in additional dialogs
Definition: GUIDesigns.h:447
#define GUIDesignButtonIcon
button only with icon (23x23)
Definition: GUIDesigns.h:63
GNEAdditional * myEditedAdditional
pointer to edited aditional
Dialog for edit calibrators.
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which additional element is located.
void acceptChanges()
Accept changes did in this dialog.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:48
Dialog for edit Calibrator Routes.
void cancelChanges()
Cancel changes did in this dialog.
#define GUIDesignLabelThick
label extended over frame with thick and with text justify to left and height of 23 ...
Definition: GUIDesigns.h:154
FXDEFMAP(GNECalibratorDialog) GNECalibratorDialogMap[]
GNENet * getNet() const
get the net object
const std::map< std::string, GNEAdditional * > & getAdditionalByType(SumoXMLTag type) const
get map with IDs and pointers to additionals
Definition: GNENet.cpp:1812
Dialog for edit rerouter intervals.
const std::vector< GNEAdditional * > & getAdditionalChilds() const
return vector of additionals that have as Parent this edge (For example, Calibrators) ...
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
long onCmdCancel(FXObject *, FXSelector, void *)
event after press cancel button
long onCmdClickedVehicleType(FXObject *, FXSelector, void *)
remove or edit vehicle type
long onCmdAccept(FXObject *, FXSelector, void *)