// gekürzt, weil immer noch zu lang :-P
public class ConfigTabController implements Initializable {
@FXML
private Label cmdPathLabel;
@FXML
private TextField cmdPathText;
@FXML
private Button cmdPathButton;
@FXML
private Label licenseLabel;
@FXML
private Button licenseButton;
@FXML
private Label updownPathLabel;
@FXML
private TextField updownPathText;
@FXML
private Button updownPathButton;
@FXML
private Label labelUploadURL;
@FXML
private TextField textFieldUploadURL;
@FXML
private Label labelUploadKey;
@FXML
private TextField textFieldUploadKey;
@FXML
private Label labelAGPSUrl;
@FXML
private TextField textFieldAGPSUrl;
@FXML
private Label labelAGPSUser;
@FXML
private TextField textFieldAGPSUser;
@FXML
private Label labelAGPSPasswd;
@FXML
private TextField textFieldAGPSPasswd;
@FXML
private Label labelDeviceTable;
@FXML
private ScrollPane scrollPaneDevices;
@FXML
private TableView<Device> deviceTable;
@FXML
private TableColumn<Device, Device> tableColumnDetected;
@FXML
private TableColumn<Device, String> tableColumnMac;
@FXML
private TableColumn<Device, Device> tableColumnName;
@FXML
private TableColumn<Device, Device> tableColumnInterval;
@FXML
private TableColumn<Device, Device> tableColumnDataUsage;
@FXML
private Button buttonConfigure;
@FXML
private Button buttonAdd;
@FXML
private Button buttonRemove;
@Inject
private IEclipseContext context;
@Inject
private IEventBroker broker;
// @Inject private UIComponent parent;
private ResourceBundle bundle = null;
@Override
public void initialize(URL location, ResourceBundle resources) {
this.bundle = resources;
cmdPathLabel.setText(bundle.getString("configuration.path.cmd.label"));
cmdPathText.setPromptText(bundle.getString("configuration.path.cmd.tooltip"));
cmdPathButton.setText(bundle.getString("configuration.path.cmd.button"));
cmdPathText.textProperty().bind(UIComponentImpl.getPreferences().getPreferenceProperty(String.class, UIComponentImpl.PREF_EXEC_DIR));
licenseLabel.setText(StringResource.getString("configuration.license.label"));
licenseButton.setText(StringResource.getString("configuration.license.button"));
BooleanBinding cmdPathBinding = new BooleanBinding() {
{
super.bind(deviceTable.getSelectionModel().getSelectedItems());
}
@Override
protected boolean computeValue() {
String path = UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_EXEC_DIR);
return path == null || path.isEmpty();
}
};
licenseButton.disableProperty().bind(cmdPathBinding);
updownPathLabel.setText(bundle.getString("configuration.path.updown.label"));
updownPathText.setPromptText(bundle.getString("configuration.path.updown.tooltip"));
updownPathButton.setText(bundle.getString("configuration.path.updown.button"));
updownPathText.textProperty().bind(UIComponentImpl.getPreferences().getPreferenceProperty(String.class, UIComponentImpl.PREF_DATA_DIR));
if (buttonConfigure.getGraphic() == null) {
ImageView iv = ImageResource.getImageView("fugue/gear--pencil.png");
if (iv != null)
buttonConfigure.setGraphic(iv);
}
if (buttonAdd.getGraphic() == null) {
ImageView iv = ImageResource.getImageView("fugue/plus.png");
if (iv != null)
buttonAdd.setGraphic(iv);
}
if (buttonRemove.getGraphic() == null) {
ImageView iv = ImageResource.getImageView("fugue/minus.png");
if (iv != null)
buttonRemove.setGraphic(iv);
}
BooleanBinding selectionBinding = new BooleanBinding() {
{
super.bind(deviceTable.getSelectionModel().getSelectedItems());
}
@Override
protected boolean computeValue() {
return deviceTable.getSelectionModel().getSelectedItems() == null || deviceTable.getSelectionModel().getSelectedItems().isEmpty();
}
};
buttonConfigure.disableProperty().bind(selectionBinding);
buttonRemove.disableProperty().bind(selectionBinding);
// TODO bind to settings
labelUploadURL.setText(bundle.getString("configuration.upload.url.label"));
textFieldUploadURL.setPromptText(bundle.getString("configuration.upload.url.desc"));
textFieldUploadURL.setText(UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_UP_URL));
labelUploadKey.setText(bundle.getString("configuration.upload.key.label"));
textFieldUploadKey.setPromptText(bundle.getString("configuration.upload.key.desc"));
textFieldUploadKey.setText(UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_UP_KEY));
labelAGPSUrl.setText(bundle.getString("configuration.agps.url.label"));
textFieldAGPSUrl.setPromptText(bundle.getString("configuration.agps.url.desc"));
textFieldAGPSUrl.setText(UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_AGPS_URL));
labelAGPSUser.setText(bundle.getString("configuration.agps.user.label"));
textFieldAGPSUser.setPromptText(bundle.getString("configuration.agps.user.desc"));
textFieldAGPSUser.setText(UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_AGPS_USER));
labelAGPSPasswd.setText(bundle.getString("configuration.agps.passwd.label"));
textFieldAGPSPasswd.setPromptText(bundle.getString("configuration.agps.passwd.desc"));
textFieldAGPSPasswd.setText(UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_AGPS_PASSWD));
labelDeviceTable.setText(bundle.getString("configuration.deviceTable.label"));
scrollPaneDevices.viewportBoundsProperty().addListener(new ChangeListener<Bounds>() {
@Override
public void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldBounds, Bounds newBounds) {
scrollPaneDevices.setFitToWidth(newBounds.getWidth() > deviceTable.getPrefWidth());
scrollPaneDevices.setFitToHeight(newBounds.getHeight() > deviceTable.getPrefHeight());
}
});
deviceTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
deviceTable.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
Callback<TableColumn.CellDataFeatures<Device, Device>, ObservableValue<Device>> contentCallback = new Callback<TableColumn.CellDataFeatures<Device, Device>, ObservableValue<Device>>() {
@Override
public ObservableValue<Device> call(CellDataFeatures<Device, Device> param) {
return new SimpleObjectProperty<Device>(param.getValue());
}
};
tableColumnDetected.setCellValueFactory(contentCallback);
tableColumnDetected.setCellFactory(new Callback<TableColumn<Device, Device>, TableCell<Device, Device>>() {
@Override
public TableCell<Device, Device> call(TableColumn<Device, Device> param) {
return new DeviceDetectedTableCell();
}
});
tableColumnName.setEditable(true);
tableColumnName.setCellValueFactory(contentCallback);
tableColumnName.setCellFactory(new Callback<TableColumn<Device, Device>, TableCell<Device, Device>>() {
@Override
public TableCell<Device, Device> call(TableColumn<Device, Device> param) {
return new EditDeviceNameTableCell();
}
});
tableColumnName.setEditable(true);
tableColumnInterval.setCellValueFactory(contentCallback);
tableColumnInterval.setCellFactory(new Callback<TableColumn<Device, Device>, TableCell<Device, Device>>() {
@Override
public TableCell<Device, Device> call(TableColumn<Device, Device> param) {
return new EditDeviceIntervalTableCell();
}
});
tableColumnDataUsage.setCellValueFactory(contentCallback);
tableColumnDataUsage.setCellFactory(new Callback<TableColumn<Device, Device>, TableCell<Device, Device>>() {
@Override
public TableCell<Device, Device> call(TableColumn<Device, Device> param) {
return new DeviceDataUsageTableCell();
}
});
deviceTable.setEditable(true);
deviceTable.setItems(UIComponentImpl.getPreferences().getDevices());
}
@FXML
public void handleCmdPath() {
String exec = UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_EXEC_DIR);
FileChooser fileChooser = new FileChooser();
if (exec != null && !exec.isEmpty()) {
File f = new File(exec);
if (f.getParentFile().isDirectory())
fileChooser.setInitialDirectory(f.getParentFile());
}
fileChooser.getExtensionFilters().add(
new ExtensionFilter(bundle.getString("configuration.path.cmd.extension.desc"), bundle.getString("configuration.path.cmd.extension")));
File file = fileChooser.showOpenDialog(context.get(Stage.class));
if (file == null)
return;
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_EXEC_DIR, file.getAbsolutePath());
}
@FXML
public void handleLicenseButton() {
File licenseFile = UIComponentImpl.getLicenseFile();
if (licenseFile == null) {
MessageDialog.showWarning(context.get(Stage.class), StringResource.getString("nav.devices.controller.title"),
StringResource.getString("nav.devices.impossible.license"));
return;
}
LicenseSetUpDialog dialog = new LicenseSetUpDialog(context.get(Stage.class));
String license = dialog.showDialog(true);
if (license != null && !license.isEmpty()) {
String[] split = license.split("[\n]");
if (licenseFile.isFile()) {
int i = 1;
File bakFile = new File(licenseFile.getParentFile(), UIComponentImpl.LICENSE_FILE_NAME + "." + i);
while (bakFile.isFile()) {
i += 1;
bakFile = new File(licenseFile.getParentFile(), UIComponentImpl.LICENSE_FILE_NAME + "." + i);
}
licenseFile.renameTo(bakFile);
}
PrintWriter writer = null;
try {
if (licenseFile.createNewFile()) {
writer = new PrintWriter(licenseFile);
for (String line : split) {
writer.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
writer.flush();
writer.close();
}
}
}
}
@FXML
public void handleUpdownPath() {
String dataDir = UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_DATA_DIR);
DirectoryChooser dirChooser = new DirectoryChooser();
if (dataDir != null && !dataDir.isEmpty()) {
File f = new File(dataDir);
if (f.isDirectory())
dirChooser.setInitialDirectory(f);
}
File file = dirChooser.showDialog(context.get(Stage.class));
if (file == null)
return;
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_DATA_DIR, file.getAbsolutePath());
}
@FXML
public void handleUploadUrl() {
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_UP_URL, textFieldUploadURL.getText());
}
@FXML
public void handleUploadKey() {
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_UP_KEY, textFieldUploadKey.getText());
}
@FXML
public void handleAGPSUrl() {
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_AGPS_URL, textFieldAGPSUrl.getText());
}
@FXML
public void handleAGPSUser() {
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_AGPS_USER, textFieldAGPSUser.getText());
}
@FXML
public void handleAGPSPasswd() {
UIComponentImpl.getPreferences().setPreferenceValue(UIComponentImpl.PREF_AGPS_PASSWD, textFieldAGPSPasswd.getText());
}
@FXML
public void handleButtonConfigure() {
try {
ConfigureDevicesDialog2 dialog = new ConfigureDevicesDialog2(context.get(Stage.class), deviceTable.getSelectionModel().getSelectedItems());
ContextInjectionFactory.inject(dialog, context);
dialog.showDialog();
} catch (MalformedURLException e) {}
}
@FXML
public void handleButtonAdd() {
String exec = UIComponentImpl.getPreferences().getPreferenceValue(String.class, UIComponentImpl.PREF_DATA_DIR);
FileChooser fileChooser = new FileChooser();
if (exec != null && !exec.isEmpty()) {
File f = new File(exec);
if (f.isDirectory())
fileChooser.setInitialDirectory(f);
}
File file = fileChooser.showOpenDialog(context.get(Stage.class));
if (file == null)
return;
Map<String, Device> deviceMap = new HashMap<>();
ObservableList<Device> devices = UIComponentImpl.getPreferences().getDevices();
if (devices != null && !devices.isEmpty()) {
for (Device d : UIComponentImpl.getPreferences().getDevices()) {
deviceMap.put(d.getAddress(), d);
}
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line = "";
while ((line = reader.readLine()) != null) {
String[] split = line.split("[;]");
if (split.length != 2)
continue;
String deviceId = split[0].trim();
String deviceName = split[1].trim();
if (deviceMap.containsKey(deviceId)) {
deviceMap.get(deviceId).setName(deviceName);
} else {
Device d = new Device();
d.setAddress(deviceId);
d.setName(deviceName);
UIComponentImpl.getPreferences().getDevices().add(d);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {}
}
}
@FXML
public void handleButtonRemove() {
ObservableList<Device> selection = deviceTable.getSelectionModel().getSelectedItems();
if (selection == null || selection.isEmpty())
return;
boolean res = MessageDialog.showQuestion(context.get(Stage.class), bundle.getString("tab.device.confirm.removal"),
bundle.getString("tab.device.confirm.removal.msg"));
if (res) {
ObservableList<Device> devices = UIComponentImpl.getPreferences().getDevices();
if (devices != null && !devices.isEmpty()) {
for (Device d : selection) {
devices.remove(d);
}
}
}
}
public class DeviceDetectedTableCell extends TableCell<Device, Device> {
public DeviceDetectedTableCell() {}
@Override
protected void updateItem(Device item, boolean empty) {
super.updateItem(item, empty);
// getTableRow().getStyleClass().remove("highlight");
if (empty) {
textProperty().unbind();
setText(null);
graphicProperty().unbind();
setGraphic(null);
} else {
setTextOverrun(OverrunStyle.ELLIPSIS);
textProperty().bind(new DeviceDetectedStringBinding(item));
graphicProperty().bind(new DeviceDetectedBinding(item));
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}
private final class DeviceDetectedBinding extends ObjectBinding<Node> {
private final Device device;
// private final TableCell<Device, Device> cell;
public DeviceDetectedBinding(final Device device) {
this.device = device;
// this.cell = cell;
super.bind(device.detected());
super.bind(device.licensed());
}
@Override
protected Node computeValue() {
Label label = new Label();
label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
ImageView iv = null;
if (device.isDetected()) {
if (device.isLicensed()) {
iv = ImageResource.getImageView("fugue/tick-circle.png");
label.setTooltip(new Tooltip(StringResource.getString("license.deviceStatus.ok", device.getAddress()
+ (device.getName() != null && !device.getName().isEmpty() ? " '" + device.getName() + "'" : ""), device.getPort())));
} else {
iv = ImageResource.getImageView("fugue/fugue_exclamation.png");
label.setTooltip(new Tooltip(StringResource.getString("license.deviceStatus.problem", device.getAddress()
+ (device.getName() != null && !device.getName().isEmpty() ? " '" + device.getName() + "'" : ""), device.getPort())));
}
// cell.getTableRow().getStyleClass().add("highlight");
} else {
iv = ImageResource.getImageView("fugue/cross-circle.png");
label.setTooltip(new Tooltip(StringResource.getString("license.deviceStatus.unknown", device.getAddress()
+ (device.getName() != null && !device.getName().isEmpty() ? " '" + device.getName() + "'" : ""))));
// cell.getTableRow().getStyleClass().remove("highlight");
}
if (iv != null) {
label.setGraphic(iv);
}
return label;
}
}
private final class DeviceDetectedStringBinding extends StringBinding {
private final Device device;
public DeviceDetectedStringBinding(Device device) {
this.device = device;
super.bind(device.detected());
}
@Override
protected String computeValue() {
if (device.isDetected()) {
return bundle.getString("configuration.deviceTable.header.detected.true");
} else {
return bundle.getString("configuration.deviceTable.header.detected.false");
}
}
}
public class EditDeviceNameTableCell extends TableCell<Device, Device> {
private TextField textField;
public EditDeviceNameTableCell() {}
@Override
public void startEdit() {
super.startEdit();
if (isEmpty())
return;
if (textField == null) {
createTextBox();
} else {
textField.setText(getItem().getName());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.requestFocus();
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(Device item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
if (textField != null) {
textField.setText(item.getName());
}
// setText(item.getName());
textProperty().bind(item.name());
} else {
textProperty().unbind();
setText(null);
graphicProperty().unbind();
setGraphic(null);
}
}
private void createTextBox() {
textField = new TextField(getItem().getName());
// textField.setId(TABLE_EDIT_ID);
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
if (textField.getText().isEmpty() || textField.getText().equals(getItem().getName())) {
cancelEdit();
} else if (textField.getText().contains(";")) {
UIEvent event = new UIEvent(UIBaseEvents.STATUS_UPDATE, bundle.getString("configuration.deviceTable.header.name.impossible"));
broker.send(event.getName(), event);
} else {
getItem().setName(textField.getText());
cancelEdit();
}
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
}
public class EditDeviceIntervalTableCell extends TableCell<Device, Device> {
private final ObservableMap<String, Long> comboBoxContent;
private HBox hBox;
private ComboBox<String> comboBox;
private Button button;
public EditDeviceIntervalTableCell() {
Map<String, Long> content = new TreeMap<>();
content.put(bundle.getString("configuration.confiurationUpdate.oneHz"), 1000L);
content.put(bundle.getString("configuration.confiurationUpdate.fiveHz"), 200L);
comboBoxContent = FXCollections.observableMap(content);
}
@Override
public void startEdit() {
super.startEdit();
// if (isEmpty())
if (isEmpty() || !getItem().isDetected())
return;
if (hBox == null) {
createHBox();
}
comboBox.getSelectionModel().select(getText());
button.setDisable(true);
setGraphic(hBox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
comboBox.requestFocus();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(Device item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
textProperty().bind(new DeviceIntervalBinding(item, comboBoxContent));
if (hBox != null) {
comboBox.getSelectionModel().select(getText());
button.setDisable(true);
}
} else {
textProperty().unbind();
setText(null);
setGraphic(null);
}
}
private void createHBox() {
hBox = new HBox(5.0);
comboBox = new ComboBox<>(FXCollections.observableArrayList(comboBoxContent.keySet()));
button = new Button(bundle.getString("configuration.confiurationUpdate.button.ok"));
button.setDisable(true);
comboBox.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(comboBox, Priority.ALWAYS);
HBox.setHgrow(button, Priority.NEVER);
hBox.getChildren().add(comboBox);
hBox.getChildren().add(button);
comboBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (!comboBox.getSelectionModel().getSelectedItem().equals(getText())) {
button.setDisable(false);
}
}
});
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (!getItem().isLicensed()) {
comboBox.getSelectionModel().select(getText());
button.setDisable(true);
cancelEdit();
DeviceLicenseProblemDialog dialog = new DeviceLicenseProblemDialog(context.get(Stage.class), FXCollections.observableArrayList(getItem()));
dialog.showDialog();
return;
}
getItem().setInterval(comboBoxContent.get(comboBox.getSelectionModel().getSelectedItem()));
ConfigureGPSDeviceTask task = new ConfigureGPSDeviceTask(broker, context.get(Stage.class), bundle, getItem());
task.setCancelable(false);
task.setTitleAsInitialStatus(true);
UIEvent uiEvent = new UIEvent(UIBaseEvents.PROGRESS_ADD_TASK, task);
broker.send(uiEvent.getName(), uiEvent);
cancelEdit();
}
});
}
}
private final class DeviceIntervalBinding extends StringBinding {
private final ObservableMap<String, Long> comboBoxContent;
private final Device device;
public DeviceIntervalBinding(Device device, ObservableMap<String, Long> comboBoxContent) {
super.bind(device.detected());
super.bind(device.interval());
this.device = device;
this.comboBoxContent = comboBoxContent;
}
@Override
protected String computeValue() {
String interval = "";
for (String key : comboBoxContent.keySet()) {
if (comboBoxContent.get(key) == device.getInterval()) {
interval = key;
break;
}
}
return device.isDetected() ? interval : "";
}
}
public class DeviceDataUsageTableCell extends TableCell<Device, Device> {
public DeviceDataUsageTableCell() {}
@Override
protected void updateItem(Device item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
textProperty().unbind();
setText(null);
} else {
setTextOverrun(OverrunStyle.ELLIPSIS);
textProperty().bind(new DeviceDataUsageStringBinding(item));
}
}
}
private final class DeviceDataUsageStringBinding extends StringBinding {
private final Device device;
public DeviceDataUsageStringBinding(Device device) {
super.bind(device.detected());
super.bind(device.dataBytes());
this.device = device;
}
@Override
protected String computeValue() {
return device.isDetected() && device.getDataBytes() > 0 ? (device.getDataBytes() / InternalPreferences.DEVICE_SIZE_MIB) * 100 + "%" : "";
}
}
}