1 /** ************************************************************************* */
2 // Eclipse SUMO, LisumSimulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2016-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 /** ************************************************************************* */
10 /// @file    Constants.java
11 /// @author  Maximiliano Bottazzi
12 /// @date    2016
13 /// @version $Id$
14 ///
15 //
16 /** ************************************************************************* */
17 package de.dlr.ts.lisum.gui;
18 
19 import de.dlr.ts.commons.javafx.messages.ConfirmationMessage;
20 import de.dlr.ts.commons.javafx.messages.ExceptionMessage;
21 import de.dlr.ts.commons.javafx.messages.InformationMessage;
22 import de.dlr.ts.commons.logger.DLRLogger;
23 import de.dlr.ts.lisum.simulation.LisumSimulation;
24 import de.dlr.ts.lisum.exceptions.LisumException;
25 import de.dlr.ts.lisum.gui.options.LisaControlUnitPreferences;
26 import de.dlr.ts.lisum.gui.options.SystemPreferencesWindow;
27 import de.dlr.ts.lisum.gui.options.WorkspaceWindow;
28 import java.io.File;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Optional;
32 import javafx.event.EventHandler;
33 import javafx.scene.control.Alert;
34 import javafx.scene.control.Button;
35 import javafx.scene.control.ButtonType;
36 import javafx.scene.control.MenuItem;
37 import javafx.stage.FileChooser;
38 import javafx.stage.Modality;
39 import javafx.stage.Stage;
40 import javafx.stage.WindowEvent;
41 
42 /**
43  *
44  * @author @author <a href="mailto:maximiliano.bottazzi@dlr.de">Maximiliano
45  * Bottazzi</a>
46  */
47 public class Actions {
48 
49     private static final Actions INSTANCE = new Actions();
50     private final List<EventHandler> onCloseListeners = new ArrayList<>();
51 
52     /**
53      *
54      * @return
55      */
getInstance()56     public static Actions getInstance() {
57         return INSTANCE;
58     }
59 
60     /**
61      *
62      * @param eventHandler
63      */
addOnCloseListener(EventHandler eventHandler)64     public void addOnCloseListener(EventHandler eventHandler) {
65         onCloseListeners.add(eventHandler);
66     }
67 
68     /**
69      *
70      */
openLastSimulation()71     public void openLastSimulation() {
72         SystemProperties.getInstance().setCurrentSimulation(null);
73 
74         MenuItem[] lastOpenFiles = MainProgram.getInstance().getMenuAdmin().getMainMenuBar().getFileMenu().getLastOpenFiles();
75 
76         if (lastOpenFiles != null && lastOpenFiles.length > 0) {
77             File selectedFile = new File(lastOpenFiles[0].getText());
78             openSimulation(selectedFile);
79         } else {
80             InformationMessage im = new InformationMessage("List of recent opened files is empty.");
81             im.show();
82         }
83     }
84 
85     /**
86      *
87      * @return
88      */
openSimulationSelectingFile()89     public File openSimulationSelectingFile() {
90         SystemProperties.getInstance().setCurrentSimulation(null);
91 
92         //DirectoryChooser dch = new DirectoryChooser();
93         FileChooser fch = new FileChooser();
94         fch.setTitle("Select simulation file");
95         FileChooser.ExtensionFilter extf = new FileChooser.ExtensionFilter("LiSuM Config File", "lisum.xml");
96         fch.getExtensionFilters().add(extf);
97 
98         File file = new File(GlobalConfig.getInstance().getWorkspace());
99         if (!file.exists()) {
100             file.mkdirs();
101         }
102 
103         fch.setInitialDirectory(file);
104 
105         File selectedFile = fch.showOpenDialog(MainProgram.getInstance().getScene().getWindow());
106         openSimulation(selectedFile);
107 
108         return selectedFile;
109     }
110 
111     /**
112      *
113      * @param selectedFile
114      */
openSimulation(File selectedFile)115     public void openSimulation(File selectedFile) {
116         if (selectedFile != null && selectedFile.exists()) {
117             try {
118                 DLRLogger.info(this, "Opening simulation " + selectedFile.getAbsolutePath());
119 
120                 GlobalConfig g = GlobalConfig.getInstance();
121 
122                 LisumSimulation simulation = new LisumSimulation(g.getSumoExec(), g.getSumoPort(),
123                         g.getLisaServerAddress(), g.getLisaServerPort());
124                 simulation.load(selectedFile);
125 
126                 SystemProperties.getInstance().setCurrentSimulation(simulation);
127             } catch (LisumException ex) {
128                 ExceptionMessage em = new ExceptionMessage(null, "Error reading configuration file", ex);
129                 em.show();
130                 //DLRLogger.severe(this, ex);
131             } catch (Exception ex) {
132                 DLRLogger.severe(this, ex);
133                 //Actions.getInstance().lisaServerNotFoundMessage();
134             }
135         }
136     }
137 
138     /**
139      *
140      */
openControlUnitPreferences()141     public void openControlUnitPreferences() {
142         LisaControlUnitPreferences.justDoIt();
143     }
144 
145     /**
146      *
147      */
closeCurrentproject()148     public void closeCurrentproject() {
149         LisumSimulation cs = SystemProperties.getInstance().getCurrentSimulation();
150         if (cs != null) {
151             DLRLogger.info("Actions", "Closing simulation " + cs.getSimulationFiles().getSimulationDirectory());
152         }
153 
154         SystemProperties.getInstance().setCurrentSimulation(null);
155     }
156 
157     /**
158      *
159      */
lisaServerNotFoundMessage()160     private void lisaServerNotFoundMessage() {
161         GlobalConfig g = GlobalConfig.getInstance();
162         String dd = g.getLisaServerAddress() + ":" + g.getLisaServerPort();
163 
164         ConfirmationMessage cm = new ConfirmationMessage("Do you want to start a new instance?");
165         cm.setHeader("No Lisa+ RESTful Server could be found in " + dd);
166         Optional<ButtonType> result = cm.showAndWait();
167 
168         if (result.get() == ButtonType.OK) {
169             Tools.startLisaRESTfulServer(g.getLisaRESTfulServerPath(), g.getLisaServerPort());
170         }
171     }
172 
173     /**
174      *
175      */
noSumoExecMessage()176     private void noSumoExecMessage() {
177         ConfirmationMessage cm = new ConfirmationMessage("Do you want to fix this now?");
178         cm.setHeader("No SumoGUI executable could be found.");
179         Optional<ButtonType> result = cm.showAndWait();
180 
181         if (result.get() == ButtonType.OK) {
182             new SystemPreferencesWindow().show(1);
183         }
184     }
185 
186     /**
187      *
188      */
execCurrentSimulation()189     public void execCurrentSimulation() {
190 
191         String sumoExec = GlobalConfig.getInstance().getSumoExec();
192 
193         if (sumoExec.isEmpty()) {
194             noSumoExecMessage();
195             return;
196         }
197 
198         /**
199          * Init before play
200          */
201         LisumSimulation.InitBeforePlayResponse initBeforePlay = SystemProperties.getInstance().getCurrentSimulation().initBeforePlay();
202 
203         if (initBeforePlay == LisumSimulation.InitBeforePlayResponse.LisaRESTfulServerNotFound) {
204             Actions.getInstance().lisaServerNotFoundMessage();
205         } else {
206             Runnable r = SystemProperties.getInstance().getCurrentSimulation().getRunnable();
207             Thread worker = new Thread(r);
208             worker.start();
209 
210             Thread thread = new Thread(()
211                     -> {
212                 try {
213                     worker.join();
214 
215                     SystemProperties.getInstance().simulationStartedProperty().set(false);
216                 } catch (InterruptedException ex) {
217                     ex.printStackTrace(System.out);
218                 }
219             });
220             thread.start();
221 
222             SystemProperties.getInstance().simulationStartedProperty().set(true);
223         }
224     }
225 
226     /**
227      *
228      * @return True if workspace changed
229      */
switchWorkspace()230     public boolean switchWorkspace() {
231         File workspace = WorkspaceWindow.getWorkspace();
232         new WorkspaceWindow().show(MainProgram.getInstance().getScene().getWindow());
233 
234         boolean aa = WorkspaceWindow.getWorkspace().compareTo(workspace) != 0;
235 
236         if (aa) {
237             GlobalConfig.getInstance().setWorkspace(WorkspaceWindow.getWorkspace().getAbsolutePath());
238         }
239 
240         return aa;
241     }
242 
243     /**
244      *
245      * @param event
246      * @param stage
247      */
exitSystem(WindowEvent event, Stage stage)248     public void exitSystem(WindowEvent event, Stage stage) {
249         if (SystemProperties.getInstance().simulationStartedProperty().get()) {
250             StringBuilder sb = new StringBuilder("A simulation is currently running.").append("\n");
251             sb.append("Do you really want to exit?");
252 
253             ConfirmationMessage cm = new ConfirmationMessage(sb.toString());
254 
255             Optional<ButtonType> showAndWait = cm.showAndWait();
256 
257             if (event == null) {
258                 if (showAndWait.get() == ButtonType.OK) {
259                     for (EventHandler onCloseListener : onCloseListeners) {
260                         onCloseListener.handle(null);
261                     }
262 
263                     closeCurrentproject();
264                     GlobalConfig.getInstance().saveProps();
265                     event.consume();
266                 }
267             } else {
268                 if (showAndWait.get() == ButtonType.CANCEL) {
269                     event.consume();
270                 } else {
271                     closeCurrentproject();
272                     GlobalConfig.getInstance().saveProps();
273                 }
274             }
275         } else {
276             Alert closeConfirmation = new Alert(Alert.AlertType.CONFIRMATION, "");
277             closeConfirmation.setTitle(SystemProperties.getInstance().getSystemName());
278 
279             Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(ButtonType.OK);
280             exitButton.setText("Exit");
281 
282             Button cancelButton = (Button) closeConfirmation.getDialogPane().lookupButton(ButtonType.CANCEL);
283             cancelButton.setText("Cancel");
284 
285             closeConfirmation.setHeaderText("Are you sure you want to exit?");
286             closeConfirmation.initModality(Modality.APPLICATION_MODAL);
287             closeConfirmation.initOwner(stage);
288 
289             Optional<ButtonType> closeResponse = closeConfirmation.showAndWait();
290             if (!ButtonType.OK.equals(closeResponse.get())) {
291                 event.consume();
292             } else {
293                 closeCurrentproject();
294                 GlobalConfig.getInstance().saveProps();
295             }
296         }
297     }
298 }
299