1 /****************************************************************************/
2 // Eclipse SUMO, Simulation 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.options;
18 
19 import de.dlr.ts.commons.javafx.buttons.tools.FileChooserCombo;
20 import de.dlr.ts.commons.javafx.buttonspanels.OkCancelButtonsPanel;
21 import de.dlr.ts.commons.javafx.messages.ConfirmationMessage;
22 import de.dlr.ts.commons.logger.LogLevel;
23 import de.dlr.ts.lisum.Constants;
24 import de.dlr.ts.lisum.gui.GlobalConfig;
25 import de.dlr.ts.lisum.gui.Actions;
26 import de.dlr.ts.lisum.gui.MainProgram;
27 import de.dlr.ts.lisum.gui.SystemProperties;
28 import java.io.File;
29 import javafx.beans.value.ChangeListener;
30 import javafx.beans.value.ObservableValue;
31 import javafx.event.ActionEvent;
32 import javafx.scene.Node;
33 import javafx.scene.Scene;
34 import javafx.scene.control.Button;
35 import javafx.scene.control.ButtonType;
36 import javafx.scene.control.ComboBox;
37 import javafx.scene.control.Label;
38 import javafx.scene.control.Tab;
39 import javafx.scene.control.TabPane;
40 import javafx.scene.control.Tooltip;
41 import javafx.scene.input.KeyCode;
42 import javafx.scene.input.KeyEvent;
43 import javafx.scene.layout.AnchorPane;
44 import javafx.scene.paint.Color;
45 import javafx.scene.text.Font;
46 import javafx.stage.Modality;
47 import javafx.stage.Stage;
48 import javafx.stage.StageStyle;
49 
50 /**
51  *
52  * @author @author <a href="mailto:maximiliano.bottazzi@dlr.de">Maximiliano Bottazzi</a>
53  */
54 public class SystemPreferencesWindow
55 {
56     private final AnchorPane root = new AnchorPane();
57     private final OkCancelButtonsPanel okCancelButtons = new OkCancelButtonsPanel();
58     private final Button okButton = okCancelButtons.getOkButton();
59     private final ChangeListener<String> activateOkButton = (ObservableValue<? extends String> observable, String oldValue, String newValue) ->
60     {
61         okButton.setDisable(false);
62     };
63 
64     private final Scene scene;
65     private Stage stage;
66 
67     private final TabPane mainTabPane = new TabPane();
68     private FileChooserCombo sumoExecFileChooser;
69     private FileChooserCombo lisaServerFileChooser;
70     private FileChooserCombo textEditorFileChooserCombo;
71     private FileChooserCombo filesExplorerFileChooserCombo;
72     private FileChooserCombo workspaceFileChooserCombo;
73 
74     private final Tab sumoTab = new Tab("Sumo");
75     private final Tab lisaTab = new Tab("Lisa+");
76     private final Tab generalTab = new Tab("General");
77     //private FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Exe files (*.exe)", "*.exe");
78 
79 
80     /**
81      *
82      */
SystemPreferencesWindow()83     public SystemPreferencesWindow()
84     {
85         okCancelButtons.getOkButton().setOnAction((ActionEvent event) -> saveAndClose());
86         okCancelButtons.getCancelButton().setOnAction((ActionEvent event) -> stage.close());
87         okButton.setDisable(true);
88 
89         scene = new Scene(root, 600, 450);
90 
91         /**
92          *
93          */
94         stage = new Stage();
95         stage.initStyle(StageStyle.UTILITY);
96         stage.setTitle("System Preferencies");
97         stage.setScene(scene);
98         stage.initModality(Modality.WINDOW_MODAL);
99         stage.initOwner(MainProgram.getInstance().getScene().getWindow());
100         stage.getIcons().add(SystemProperties.getInstance().getMainIcon());
101         stage.setResizable(false);
102 
103         stage.addEventHandler(KeyEvent.KEY_PRESSED, (KeyEvent event) ->
104         {
105             if(event.getCode() == KeyCode.ESCAPE)
106                 stage.close();
107         });
108 
109         /**
110          *
111          */
112         AnchorPane.setTopAnchor(mainTabPane, 5.);
113         AnchorPane.setLeftAnchor(mainTabPane, 5.);
114         AnchorPane.setRightAnchor(mainTabPane, 5.);
115         AnchorPane.setBottomAnchor(mainTabPane, okCancelButtons.getHeight() + 10.);
116 
117         generalTab();
118         sumoTab();
119         lisaTab();
120     }
121 
122     /**
123      *
124      */
save()125     private void save()
126     {
127         GlobalConfig.getInstance().setTextEditor(textEditorFileChooserCombo.getTextField().getText());
128         GlobalConfig.getInstance().setSumoExec(sumoExecFileChooser.getTextField().getText());
129         GlobalConfig.getInstance().setLoggingLevel(logLevelComboBox.getValue());
130         GlobalConfig.getInstance().setLisaRestFulServerDir(lisaServerFileChooser.getTextField().getText());
131         GlobalConfig.getInstance().setWorkspace(workspaceFileChooserCombo.getTextField().getText());
132         GlobalConfig.getInstance().setFilesExplorer(filesExplorerFileChooserCombo.getTextField().getText());
133         GlobalConfig.getInstance().saveProps();
134 
135         okButton.setDisable(true);
136     }
137 
138     /**
139      *
140      */
saveAndClose()141     private void saveAndClose()
142     {
143         save();
144         stage.close();
145     }
146 
147     /**
148      *
149      */
generalTab()150     private void generalTab()
151     {
152         AnchorPane generalAnchorPane = new AnchorPane();
153         generalTab.setContent(generalAnchorPane);
154         generalTab.setClosable(false);
155 
156 
157         Label logLevelLabel = new Label("Default log level:");
158         AnchorPane.setTopAnchor(logLevelLabel, 24.);
159         AnchorPane.setLeftAnchor(logLevelLabel, 5.);
160         logLevelLabel.setFont(Font.font(10));
161 
162         AnchorPane.setTopAnchor(logLevelComboBox, 20.);
163         AnchorPane.setLeftAnchor(logLevelComboBox, 105.);
164         logLevelComboBox.setValue(GlobalConfig.getInstance().getLoggingLevel());
165         logLevelComboBox.valueProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) ->
166         {
167             okButton.setDisable(false);
168         });
169 
170         /**
171          *
172          */
173         textEditorFileChooserCombo = new FileChooserCombo("Text Editor:", new File("."), stage.getOwner());
174         Node textEditorNode = textEditorFileChooserCombo.getNode();
175         AnchorPane.setTopAnchor(textEditorNode, 55.);
176         AnchorPane.setLeftAnchor(textEditorNode, 5.);
177         textEditorFileChooserCombo.setDefaultValue(GlobalConfig.getInstance().getDefaultTextEditor());
178         textEditorFileChooserCombo.getTextField().setText(GlobalConfig.getInstance().getTextEditor());
179         textEditorFileChooserCombo.getTextField().textProperty().addListener(activateOkButton);
180         //textEditorFileChooserCombo.getFileChooser().setSelectedExtensionFilter(filter);
181         textEditorFileChooserCombo.setTextFieldWidth(330.);
182         textEditorFileChooserCombo.setFontSize(10);
183 
184 
185         /**
186          *
187          */
188         filesExplorerFileChooserCombo = new FileChooserCombo("Files explorer: ", new File("."), stage.getOwner());
189         Node filesExplorerNode = filesExplorerFileChooserCombo.getNode();
190         AnchorPane.setTopAnchor(filesExplorerNode, 88.);
191         AnchorPane.setLeftAnchor(filesExplorerNode, 5.);
192         filesExplorerFileChooserCombo.setDefaultValue(GlobalConfig.getInstance().getDefaultFilesExplorer());
193         filesExplorerFileChooserCombo.getTextField().setText(GlobalConfig.getInstance().getFilesExplorer());
194         filesExplorerFileChooserCombo.getTextField().textProperty().addListener(activateOkButton);
195         filesExplorerFileChooserCombo.setTextFieldWidth(330.);
196         filesExplorerFileChooserCombo.setFontSize(10);
197 
198 
199         /**
200          *
201          */
202         workspaceFileChooserCombo = new FileChooserCombo("Workspace:",
203                 new File(GlobalConfig.getInstance().getWorkspace()), stage.getOwner());
204         Node simuNode = workspaceFileChooserCombo.getNode();
205         AnchorPane.setTopAnchor(simuNode, 121.);
206         AnchorPane.setLeftAnchor(simuNode, 5.);
207         workspaceFileChooserCombo.getTextField().setText(WorkspaceWindow.getWorkspace().getAbsolutePath());
208         workspaceFileChooserCombo.getTextField().setDisable(true);
209         workspaceFileChooserCombo.getTextField().setStyle("-fx-opacity: 0.8;");
210         workspaceFileChooserCombo.setTextFieldWidth(330.);
211         workspaceFileChooserCombo.enableDefaultButton(false);
212         workspaceFileChooserCombo.getBrowseButton().setText("Switch");
213         workspaceFileChooserCombo.setFontSize(10);
214         workspaceFileChooserCombo.getBrowseButton().setOnAction((ActionEvent event) ->
215         {
216             if(!okButton.isDisabled())
217             {
218                 ConfirmationMessage cm = new ConfirmationMessage("");
219                 cm.setHeader("Save changes before proceeding?");
220                 if(cm.showAndWait().get() == ButtonType.OK)
221                     save();
222             }
223 
224             boolean switchWorkspace = Actions.getInstance().switchWorkspace();
225 
226             if(switchWorkspace)
227                 stage.close();
228         });
229 
230 
231         /**
232          *
233          */
234         Button switchWorkspaceButton = new Button("Switch workspace");
235         AnchorPane.setBottomAnchor(switchWorkspaceButton, 5.);
236         AnchorPane.setRightAnchor(switchWorkspaceButton, 5.);
237 
238         switchWorkspaceButton.setOnAction((ActionEvent event) ->
239         {
240             boolean switchWorkspace = Actions.getInstance().switchWorkspace();
241 
242             if(switchWorkspace)
243                 stage.close();
244         });
245 
246         generalAnchorPane.getChildren().addAll(/*logLevelLabel, logLevelComboBox,*/ textEditorNode,
247                 filesExplorerNode, simuNode);
248         mainTabPane.getTabs().addAll(generalTab);
249     }
250 
251     /**
252      *
253      */
sumoTab()254     private void sumoTab()
255     {
256         AnchorPane sumoAnchorPane = new AnchorPane();
257         sumoTab.setContent(sumoAnchorPane);
258         sumoTab.setClosable(false);
259 
260         /**
261          *
262          */
263         sumoExecFileChooser = new FileChooserCombo("SumoGUI exec:", new File("."), stage.getOwner());
264         Node sumoExecNode = sumoExecFileChooser.getNode();
265         AnchorPane.setTopAnchor(sumoExecNode, 20.);
266         AnchorPane.setLeftAnchor(sumoExecNode, 5.);
267         sumoExecFileChooser.setFontSize(10);
268 
269         sumoAnchorPane.getChildren().add(sumoExecNode);
270         sumoExecFileChooser.setDefaultValue("");
271         sumoExecFileChooser.getTextField().setText(GlobalConfig.getInstance().getSumoExec());
272         sumoExecFileChooser.getTextField().textProperty().addListener(activateOkButton);
273         //sumoExecFileChooser.getFileChooser().setSelectedExtensionFilter(filter);
274         sumoExecFileChooser.enableDefaultButton(false);
275         sumoExecFileChooser.setTextFieldWidth(330.);
276 
277         mainTabPane.getTabs().addAll(sumoTab);
278     }
279 
280 /**
281      *
282      */
lisaTab()283     private void lisaTab()
284     {
285         AnchorPane lisaAnchorPane = new AnchorPane();
286         lisaTab.setContent(lisaAnchorPane);
287         lisaTab.setClosable(false);
288 
289         lisaServerFileChooser = new FileChooserCombo("LISA+ RestFUL Server folder:", new File("."), stage.getOwner());
290         Node node = lisaServerFileChooser.getNode();
291         AnchorPane.setTopAnchor(node, 20.);
292         AnchorPane.setLeftAnchor(node, 5.);
293         lisaServerFileChooser.setDefaultValue(GlobalConfig.getInstance().getDefaultLisaRestFulServerDir());
294         lisaServerFileChooser.getTextField().setText(GlobalConfig.getInstance().getLisaRESTfulServerPath());
295         lisaServerFileChooser.getTextField().textProperty().addListener(activateOkButton);
296         lisaServerFileChooser.setLabelWidth(165);
297         lisaServerFileChooser.setDirectoryChooser(true);
298         lisaServerFileChooser.setFontSize(10);
299 
300         Label warningLabel = new Label("System restart required!");
301         warningLabel.setTextFill(Color.RED);
302         AnchorPane.setTopAnchor(warningLabel, 50.);
303         AnchorPane.setLeftAnchor(warningLabel, 180.);
304         warningLabel.setVisible(false);
305 
306         lisaServerFileChooser.getTextField().textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) ->
307         {
308             String lisaRestFulServerDir = GlobalConfig.getInstance().getLisaRESTfulServerPath();
309             if(!lisaServerFileChooser.getTextField().getText().equals(lisaRestFulServerDir))
310                 warningLabel.setVisible(true);
311             else
312                 warningLabel.setVisible(false);
313         });
314 
315         lisaAnchorPane.getChildren().addAll(node, warningLabel);
316 
317         mainTabPane.getTabs().addAll(lisaTab);
318     }
319 
320     /**
321      *
322      * @param tabIndex
323      */
show(int tabIndex)324     public void show(int tabIndex)
325     {
326         Node okCancelNode = okCancelButtons.getNode();
327         AnchorPane.setBottomAnchor(okCancelNode, 0.);
328         AnchorPane.setLeftAnchor(okCancelNode, 0.);
329         AnchorPane.setRightAnchor(okCancelNode, 0.);
330 
331         root.getChildren().addAll(okCancelNode, mainTabPane);
332 
333         mainTabPane.getSelectionModel().select(tabIndex);
334 
335         stage.show();
336     }
337 
338     /**
339      *
340      */
341     private final ComboBox<String> logLevelComboBox = new ComboBox<>();
342     {
343         for (LogLevel value : LogLevel.values())
344             logLevelComboBox.getItems().add(value.name());
345 
346         logLevelComboBox.setEditable(false);
347         logLevelComboBox.setValue(Constants.DEFAULT_LOG_LEVEL);
348 
logLevelComboBox.setTooltip(new Tooltip(R))349         logLevelComboBox.setTooltip(new Tooltip("Log level"));
350     }
351 }
352