1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 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 /****************************************************************************/
10 /// @file    GNERerouterDialog.cpp
11 /// @author  Pablo Alvarez Lopez
12 /// @date    April 2016
13 /// @version $Id$
14 ///
15 // Dialog for edit rerouters
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <iostream>
24 #include <utils/gui/windows/GUIAppEnum.h>
25 #include <utils/gui/images/GUIIconSubSys.h>
26 #include <utils/gui/div/GUIDesigns.h>
27 #include <netedit/changes/GNEChange_Additional.h>
28 #include <netedit/additionals/GNERerouter.h>
29 #include <netedit/additionals/GNERerouterInterval.h>
30 #include <netedit/GNENet.h>
31 #include <netedit/GNEViewNet.h>
32 #include <netedit/GNEUndoList.h>
33 
34 #include "GNERerouterDialog.h"
35 #include "GNERerouterIntervalDialog.h"
36 
37 
38 // ===========================================================================
39 // FOX callback mapping
40 // ===========================================================================
41 
42 FXDEFMAP(GNERerouterDialog) GNERerouterDialogMap[] = {
43     FXMAPFUNC(SEL_COMMAND,          MID_GNE_REROUTEDIALOG_ADD_INTERVAL,     GNERerouterDialog::onCmdAddInterval),
44     FXMAPFUNC(SEL_COMMAND,          MID_GNE_REROUTEDIALOG_SORT_INTERVAL,    GNERerouterDialog::onCmdSortIntervals),
45     FXMAPFUNC(SEL_CLICKED,          MID_GNE_REROUTEDIALOG_TABLE_INTERVAL,   GNERerouterDialog::onCmdClickedInterval),
46     FXMAPFUNC(SEL_DOUBLECLICKED,    MID_GNE_REROUTEDIALOG_TABLE_INTERVAL,   GNERerouterDialog::onCmdClickedInterval),
47     FXMAPFUNC(SEL_TRIPLECLICKED,    MID_GNE_REROUTEDIALOG_TABLE_INTERVAL,   GNERerouterDialog::onCmdClickedInterval),
48 };
49 
50 // Object implementation
FXIMPLEMENT(GNERerouterDialog,GNEAdditionalDialog,GNERerouterDialogMap,ARRAYNUMBER (GNERerouterDialogMap))51 FXIMPLEMENT(GNERerouterDialog, GNEAdditionalDialog, GNERerouterDialogMap, ARRAYNUMBER(GNERerouterDialogMap))
52 
53 // ===========================================================================
54 // member method definitions
55 // ===========================================================================
56 
57 GNERerouterDialog::GNERerouterDialog(GNERerouter* rerouterParent) :
58     GNEAdditionalDialog(rerouterParent, false, 320, 240) {
59 
60     // create Horizontal frame for row elements
61     FXHorizontalFrame* myAddIntervalFrame = new FXHorizontalFrame(myContentFrame, GUIDesignAuxiliarHorizontalFrame);
62     // create Button and Label for adding new Wors
63     myAddInterval = new FXButton(myAddIntervalFrame, "", GUIIconSubSys::getIcon(ICON_ADD), this, MID_GNE_REROUTEDIALOG_ADD_INTERVAL, GUIDesignButtonIcon);
64     new FXLabel(myAddIntervalFrame, ("Add new " + toString(SUMO_TAG_INTERVAL)).c_str(), nullptr, GUIDesignLabelThick);
65     // create Button and Label for sort intervals
66     mySortIntervals = new FXButton(myAddIntervalFrame, "", GUIIconSubSys::getIcon(ICON_RELOAD), this, MID_GNE_REROUTEDIALOG_SORT_INTERVAL, GUIDesignButtonIcon);
67     new FXLabel(myAddIntervalFrame, ("Sort " + toString(SUMO_TAG_INTERVAL) + "s").c_str(), nullptr, GUIDesignLabelThick);
68 
69     // Create table
70     myIntervalTable = new FXTable(myContentFrame, this, MID_GNE_REROUTEDIALOG_TABLE_INTERVAL, GUIDesignTableAdditionals);
71     myIntervalTable->setSelBackColor(FXRGBA(255, 255, 255, 255));
72     myIntervalTable->setSelTextColor(FXRGBA(0, 0, 0, 255));
73     myIntervalTable->setEditable(false);
74 
75     // update intervals
76     updateIntervalTable();
77 
78     // start a undo list for editing local to this additional
79     initChanges();
80 
81     // Open dialog as modal
82     openAsModalDialog();
83 }
84 
85 
~GNERerouterDialog()86 GNERerouterDialog::~GNERerouterDialog() {}
87 
88 
89 long
onCmdAccept(FXObject *,FXSelector,void *)90 GNERerouterDialog::onCmdAccept(FXObject*, FXSelector, void*) {
91     // Check if there is overlapping between Intervals
92     if (!myEditedAdditional->checkAdditionalChildsOverlapping()) {
93         // write warning if netedit is running in testing mode
94         WRITE_DEBUG("Opening FXMessageBox of type 'warning'");
95         // open warning Box
96         FXMessageBox::warning(getApp(), MBOX_OK, "Overlapping detected", "%s", ("Values of '" + myEditedAdditional->getID() + "' cannot be saved. There are intervals overlapped.").c_str());
97         // write warning if netedit is running in testing mode
98         WRITE_DEBUG("Closed FXMessageBox of type 'warning' with 'OK'");
99         return 0;
100     } else {
101         // accept changes before closing dialog
102         acceptChanges();
103         // Stop Modal
104         getApp()->stopModal(this, TRUE);
105         return 1;
106     }
107 }
108 
109 
110 long
onCmdCancel(FXObject *,FXSelector,void *)111 GNERerouterDialog::onCmdCancel(FXObject*, FXSelector, void*) {
112     // cancel changes
113     cancelChanges();
114     // Stop Modal
115     getApp()->stopModal(this, FALSE);
116     return 1;
117 }
118 
119 
120 long
onCmdReset(FXObject *,FXSelector,void *)121 GNERerouterDialog::onCmdReset(FXObject*, FXSelector, void*) {
122     // reset changes
123     resetChanges();
124     // update interval table
125     updateIntervalTable();
126     return 1;
127 }
128 
129 
130 long
onCmdAddInterval(FXObject *,FXSelector,void *)131 GNERerouterDialog::onCmdAddInterval(FXObject*, FXSelector, void*) {
132     // create empty rerouter interval and configure it with GNERerouterIntervalDialog
133     GNERerouterIntervalDialog(new GNERerouterInterval(this), false);
134     // update interval table
135     updateIntervalTable();
136     return 1;
137 }
138 
139 
140 long
onCmdSortIntervals(FXObject *,FXSelector,void *)141 GNERerouterDialog::onCmdSortIntervals(FXObject*, FXSelector, void*) {
142     // Sort variable speed sign steps
143     myEditedAdditional->sortAdditionalChilds();
144     // update table
145     updateIntervalTable();
146     return 1;
147 }
148 
149 
150 long
onCmdClickedInterval(FXObject *,FXSelector,void *)151 GNERerouterDialog::onCmdClickedInterval(FXObject*, FXSelector, void*) {
152     // check if some delete button was pressed
153     for (int i = 0; i < (int)myEditedAdditional->getAdditionalChilds().size(); i++) {
154         if (myIntervalTable->getItem(i, 2)->hasFocus()) {
155             // remove interval
156             myEditedAdditional->getViewNet()->getUndoList()->add(new GNEChange_Additional(myEditedAdditional->getAdditionalChilds().at(i), false), true);
157             // update interval table after removing
158             updateIntervalTable();
159             return 1;
160         }
161     }
162     // check if some begin or o end  button was pressed
163     for (int i = 0; i < (int)myEditedAdditional->getAdditionalChilds().size(); i++) {
164         if (myIntervalTable->getItem(i, 0)->hasFocus() || myIntervalTable->getItem(i, 1)->hasFocus()) {
165             // edit interval
166             GNERerouterIntervalDialog(myEditedAdditional->getAdditionalChilds().at(i), true);
167             // update interval table after editing
168             updateIntervalTable();
169             return 1;
170         }
171     }
172     // nothing to do
173     return 0;
174 }
175 
176 
177 void
updateIntervalTable()178 GNERerouterDialog::updateIntervalTable() {
179     // clear table
180     myIntervalTable->clearItems();
181     // set number of rows
182     myIntervalTable->setTableSize(int(myEditedAdditional->getAdditionalChilds().size()), 3);
183     // Configure list
184     myIntervalTable->setVisibleColumns(4);
185     myIntervalTable->setColumnWidth(0, 137);
186     myIntervalTable->setColumnWidth(1, 136);
187     myIntervalTable->setColumnWidth(2, GUIDesignTableIconCellWidth);
188     myIntervalTable->setColumnText(0, toString(SUMO_ATTR_BEGIN).c_str());
189     myIntervalTable->setColumnText(1, toString(SUMO_ATTR_END).c_str());
190     myIntervalTable->setColumnText(2, "");
191     myIntervalTable->getRowHeader()->setWidth(0);
192     // Declare index for rows and pointer to FXTableItem
193     int indexRow = 0;
194     FXTableItem* item = nullptr;
195     // iterate over values
196     for (auto i : myEditedAdditional->getAdditionalChilds()) {
197         // Set time
198         item = new FXTableItem(i->getAttribute(SUMO_ATTR_BEGIN).c_str());
199         myIntervalTable->setItem(indexRow, 0, item);
200         // Set speed
201         item = new FXTableItem(i->getAttribute(SUMO_ATTR_END).c_str());
202         myIntervalTable->setItem(indexRow, 1, item);
203         // set remove
204         item = new FXTableItem("", GUIIconSubSys::getIcon(ICON_REMOVE));
205         item->setJustify(FXTableItem::CENTER_X | FXTableItem::CENTER_Y);
206         item->setEnabled(false);
207         myIntervalTable->setItem(indexRow, 2, item);
208         // Update index
209         indexRow++;
210     }
211 }
212 
213 /****************************************************************************/
214