2015-11-28 23:06:14 +01:00
|
|
|
/*
|
|
|
|
|
The MIT License (MIT)
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
2021-12-10 00:30:59 +01:00
|
|
|
Copyright (c) 2015-2021 javafx.ninja <info@javafx.ninja>
|
2015-11-28 23:06:14 +01:00
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package ninja.javafx.smartcsv.fx;
|
|
|
|
|
|
2019-10-23 00:10:19 +02:00
|
|
|
import javafx.beans.InvalidationListener;
|
2016-08-10 23:41:47 +02:00
|
|
|
import javafx.beans.binding.Bindings;
|
2016-02-05 08:00:32 +01:00
|
|
|
import javafx.collections.ListChangeListener;
|
|
|
|
|
import javafx.collections.WeakListChangeListener;
|
2016-02-02 03:20:14 +01:00
|
|
|
import javafx.concurrent.WorkerStateEvent;
|
2015-11-28 23:06:14 +01:00
|
|
|
import javafx.event.ActionEvent;
|
|
|
|
|
import javafx.event.EventHandler;
|
|
|
|
|
import javafx.fxml.FXML;
|
2016-01-12 22:42:24 +01:00
|
|
|
import javafx.scene.Node;
|
2015-12-07 22:41:59 +01:00
|
|
|
import javafx.scene.control.*;
|
2022-10-19 12:34:55 +02:00
|
|
|
import javafx.scene.input.Dragboard;
|
|
|
|
|
import javafx.scene.input.TransferMode;
|
2015-12-07 22:41:59 +01:00
|
|
|
import javafx.scene.layout.AnchorPane;
|
2015-11-28 23:06:14 +01:00
|
|
|
import javafx.scene.layout.BorderPane;
|
|
|
|
|
import javafx.stage.FileChooser;
|
|
|
|
|
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
|
|
|
|
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
2016-08-10 23:41:47 +02:00
|
|
|
import ninja.javafx.smartcsv.export.ErrorExport;
|
2016-07-22 20:45:26 +02:00
|
|
|
import ninja.javafx.smartcsv.files.FileStorage;
|
2015-12-30 14:22:52 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.about.AboutController;
|
2016-01-27 04:39:53 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.list.ErrorSideBar;
|
2016-08-05 23:09:22 +02:00
|
|
|
import ninja.javafx.smartcsv.fx.list.GotoLineDialog;
|
2016-01-11 09:03:22 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.preferences.PreferencesController;
|
2015-11-28 23:06:14 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.table.ObservableMapValueFactory;
|
|
|
|
|
import ninja.javafx.smartcsv.fx.table.ValidationCellFactory;
|
|
|
|
|
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
|
|
|
|
import ninja.javafx.smartcsv.fx.table.model.CSVRow;
|
2015-12-17 19:56:14 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.table.model.CSVValue;
|
2021-10-29 05:05:13 -07:00
|
|
|
import ninja.javafx.smartcsv.fx.util.JavaFxUtils;
|
2016-01-12 21:52:08 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.util.LoadFileService;
|
|
|
|
|
import ninja.javafx.smartcsv.fx.util.SaveFileService;
|
2016-02-05 08:00:32 +01:00
|
|
|
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
|
2019-10-18 16:30:29 +09:00
|
|
|
import ninja.javafx.smartcsv.preferences.*;
|
2015-12-07 22:41:59 +01:00
|
|
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
2015-11-28 23:06:14 +01:00
|
|
|
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
2016-02-05 08:00:32 +01:00
|
|
|
import ninja.javafx.smartcsv.validation.ValidationFileWriter;
|
2019-10-23 00:10:19 +02:00
|
|
|
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
|
2015-11-28 23:06:14 +01:00
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
2016-01-11 09:03:22 +01:00
|
|
|
import java.io.IOException;
|
2015-11-28 23:06:14 +01:00
|
|
|
import java.net.URL;
|
2019-10-18 16:30:29 +09:00
|
|
|
import java.nio.charset.Charset;
|
2015-12-18 12:19:19 +01:00
|
|
|
import java.util.Optional;
|
2015-11-28 23:06:14 +01:00
|
|
|
import java.util.ResourceBundle;
|
|
|
|
|
|
2015-12-17 22:57:26 +01:00
|
|
|
import static java.lang.Math.max;
|
2016-02-05 08:00:32 +01:00
|
|
|
import static java.text.MessageFormat.format;
|
2015-12-30 09:52:00 +01:00
|
|
|
import static javafx.application.Platform.exit;
|
2015-11-28 23:06:14 +01:00
|
|
|
import static javafx.application.Platform.runLater;
|
2016-01-13 23:07:29 +01:00
|
|
|
import static javafx.beans.binding.Bindings.*;
|
2016-01-12 21:52:08 +01:00
|
|
|
import static javafx.scene.layout.AnchorPane.*;
|
2021-12-10 00:30:59 +01:00
|
|
|
import static ninja.javafx.smartcsv.preferences.Preferences.defaultPreferences;
|
2015-11-28 23:06:14 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* main controller of the application
|
|
|
|
|
*/
|
|
|
|
|
@Component
|
|
|
|
|
public class SmartCSVController extends FXMLController {
|
|
|
|
|
|
2021-10-29 05:05:13 -07:00
|
|
|
|
2016-01-11 11:14:25 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// constants
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
private static final File PREFERENCES_FILE = new File(System.getProperty("user.home") +
|
|
|
|
|
File.separator +
|
|
|
|
|
".SmartCSV.fx" +
|
|
|
|
|
File.separator + "" +
|
|
|
|
|
"preferences.json");
|
2019-10-18 16:30:29 +09:00
|
|
|
|
|
|
|
|
private static final File ENCODING_FILE = new File(System.getProperty("user.home") +
|
|
|
|
|
File.separator +
|
|
|
|
|
".SmartCSV.fx" +
|
|
|
|
|
File.separator +
|
|
|
|
|
"encoding.json");
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
public static final String CSV_FILTER_TEXT = "CSV files (*.csv)";
|
|
|
|
|
public static final String CSV_FILTER_EXTENSION = "*.csv";
|
|
|
|
|
public static final String JSON_FILTER_TEXT = "JSON files (*.json)";
|
|
|
|
|
public static final String JSON_FILTER_EXTENSION = "*.json";
|
2016-08-10 23:41:47 +02:00
|
|
|
public static final String EXPORT_LOG_FILTER_TEXT = "Error log files (*.log)";
|
|
|
|
|
public static final String EXPORT_LOG_FILTER_EXTENSION = "*.log";
|
|
|
|
|
|
2016-01-11 11:14:25 +01:00
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// injections
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2015-12-30 14:22:52 +01:00
|
|
|
@Autowired
|
|
|
|
|
private AboutController aboutController;
|
|
|
|
|
|
2016-01-11 09:03:22 +01:00
|
|
|
@Autowired
|
|
|
|
|
private PreferencesController preferencesController;
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
@Autowired
|
|
|
|
|
private ValidationEditorController validationEditorController;
|
|
|
|
|
|
2016-01-12 21:52:08 +01:00
|
|
|
@Autowired
|
|
|
|
|
private LoadFileService loadFileService;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
2016-07-22 20:45:26 +02:00
|
|
|
private SaveFileService saveFileService;
|
2016-01-12 21:52:08 +01:00
|
|
|
|
2016-08-10 23:41:47 +02:00
|
|
|
@Autowired
|
|
|
|
|
private ErrorExport errorExport;
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
@FXML
|
|
|
|
|
private BorderPane applicationPane;
|
|
|
|
|
|
|
|
|
|
@FXML
|
2015-12-18 12:19:19 +01:00
|
|
|
private Label csvName;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Label configurationName;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Label stateName;
|
2015-11-28 23:06:14 +01:00
|
|
|
|
2015-12-07 22:41:59 +01:00
|
|
|
@FXML
|
|
|
|
|
private AnchorPane tableWrapper;
|
|
|
|
|
|
2016-01-12 21:58:27 +01:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem saveMenuItem;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private MenuItem saveAsMenuItem;
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem createConfigMenuItem;
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem loadConfigMenuItem;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private MenuItem saveConfigMenuItem;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private MenuItem saveAsConfigMenuItem;
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem deleteRowMenuItem;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private MenuItem addRowMenuItem;
|
|
|
|
|
|
2016-08-05 23:09:22 +02:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem gotoLineMenuItem;
|
|
|
|
|
|
2016-08-10 23:41:47 +02:00
|
|
|
@FXML
|
|
|
|
|
private MenuItem exportMenuItem;
|
|
|
|
|
|
2016-01-13 11:50:54 +01:00
|
|
|
@FXML
|
|
|
|
|
private Button saveButton;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Button saveAsButton;
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
@FXML
|
|
|
|
|
private Button createConfigButton;
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
@FXML
|
|
|
|
|
private Button loadConfigButton;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Button saveConfigButton;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Button saveAsConfigButton;
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
@FXML
|
|
|
|
|
private Button deleteRowButton;
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private Button addRowButton;
|
2015-11-28 23:06:14 +01:00
|
|
|
|
2016-08-10 23:41:47 +02:00
|
|
|
@FXML
|
|
|
|
|
private Button exportButton;
|
|
|
|
|
|
2016-08-05 23:09:22 +02:00
|
|
|
@FXML
|
|
|
|
|
private Label currentLineNumber;
|
|
|
|
|
|
2022-10-15 13:41:31 +02:00
|
|
|
@FXML
|
|
|
|
|
private Label totalNumberOfLines;
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-12-17 20:44:07 +01:00
|
|
|
// members
|
2015-11-28 23:06:14 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2015-12-17 20:44:07 +01:00
|
|
|
private ValidationCellFactory cellFactory;
|
2016-01-12 21:52:08 +01:00
|
|
|
|
2015-12-07 22:41:59 +01:00
|
|
|
private TableView<CSVRow> tableView;
|
2016-02-05 08:00:32 +01:00
|
|
|
private ErrorSideBar errorSideBar;
|
2015-12-18 12:19:19 +01:00
|
|
|
private ResourceBundle resourceBundle;
|
2016-09-14 19:23:36 +02:00
|
|
|
private CSVFileReader csvFileReader = new CSVFileReader();
|
|
|
|
|
private CSVFileWriter csvFileWriter = new CSVFileWriter();
|
2016-07-22 20:45:26 +02:00
|
|
|
|
2016-09-14 19:23:36 +02:00
|
|
|
private FileStorage<CSVModel> currentCsvFile = new FileStorage<>(csvFileReader, csvFileWriter);
|
2016-07-22 20:45:26 +02:00
|
|
|
private FileStorage<ValidationConfiguration> currentConfigFile = new FileStorage<>(new ValidationFileReader(), new ValidationFileWriter());
|
2021-12-10 00:30:59 +01:00
|
|
|
private FileStorage<Preferences> csvPreferenceFile = new FileStorage<>(new PreferencesFileReader(), new PreferencesFileWriter());
|
2019-10-18 16:30:29 +09:00
|
|
|
private FileStorage<String> fileEncodingFile = new FileStorage<>(new EncodingFileReader(), new EncodingFileWriter());
|
2015-11-28 23:06:14 +01:00
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
private ListChangeListener<ValidationError> errorListListener = c -> tableView.refresh();
|
|
|
|
|
private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener);
|
2015-11-28 23:06:14 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// init
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
@Override
|
2015-12-17 20:44:07 +01:00
|
|
|
public void initialize(URL location, ResourceBundle resourceBundle) {
|
2015-12-18 12:19:19 +01:00
|
|
|
this.resourceBundle = resourceBundle;
|
2016-01-13 23:07:29 +01:00
|
|
|
|
|
|
|
|
setupTableCellFactory();
|
2016-02-05 08:00:32 +01:00
|
|
|
setupErrorSideBar(resourceBundle);
|
2016-01-27 04:39:53 +01:00
|
|
|
|
2016-08-05 23:09:22 +02:00
|
|
|
bindMenuItemsToContentExistence(currentCsvFile, saveMenuItem, saveAsMenuItem, addRowMenuItem, gotoLineMenuItem, createConfigMenuItem, loadConfigMenuItem);
|
2016-07-22 23:51:08 +02:00
|
|
|
bindButtonsToContentExistence(currentCsvFile, saveButton, saveAsButton, addRowButton, createConfigButton, loadConfigButton);
|
2016-01-27 04:39:53 +01:00
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
bindMenuItemsToContentExistence(currentConfigFile, saveConfigMenuItem, saveAsConfigMenuItem);
|
|
|
|
|
bindButtonsToContentExistence(currentConfigFile, saveAsConfigButton, saveConfigButton);
|
2016-01-13 23:07:29 +01:00
|
|
|
|
|
|
|
|
bindCsvFileName();
|
|
|
|
|
bindConfigFileName();
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
csvPreferenceFile.setFile(PREFERENCES_FILE);
|
2019-10-18 16:30:29 +09:00
|
|
|
fileEncodingFile.setFile(ENCODING_FILE);
|
2016-07-22 20:45:26 +02:00
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
loadCsvPreferencesFromFile();
|
2022-10-19 12:34:55 +02:00
|
|
|
|
|
|
|
|
initDragAndDrop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initDragAndDrop() {
|
|
|
|
|
tableWrapper.setOnDragOver(event -> {
|
|
|
|
|
Dragboard db = event.getDragboard();
|
|
|
|
|
if (event.getGestureSource() != tableWrapper
|
|
|
|
|
&& db.hasFiles()
|
|
|
|
|
&& db.getFiles().size() == 1
|
|
|
|
|
&& db.getFiles().get(0).getName().endsWith(".csv")) {
|
|
|
|
|
event.acceptTransferModes(TransferMode.COPY);
|
|
|
|
|
}
|
|
|
|
|
event.consume();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tableWrapper.setOnDragDropped(event -> {
|
|
|
|
|
Dragboard db = event.getDragboard();
|
|
|
|
|
boolean success = false;
|
|
|
|
|
if (db.hasFiles() && db.getFiles().size() == 1) {
|
|
|
|
|
File file = db.getFiles().get(0);
|
|
|
|
|
openFile(currentCsvFile, file);
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
/* let the source know whether the string was successfully
|
|
|
|
|
* transferred and used */
|
|
|
|
|
event.setDropCompleted(success);
|
|
|
|
|
});
|
2016-01-13 23:07:29 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-18 16:30:29 +09:00
|
|
|
private void loadEncodingFromFile() {
|
|
|
|
|
if (fileEncodingFile.getFile().exists()) {
|
|
|
|
|
useLoadFileService(fileEncodingFile, event -> setFileEncoding(fileEncodingFile.getContent()));
|
|
|
|
|
} else {
|
|
|
|
|
setFileEncoding(Charset.defaultCharset().name());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setFileEncoding(String content) {
|
|
|
|
|
preferencesController.setFileEncoding(content);
|
|
|
|
|
csvFileReader.setFileEncoding(content);
|
|
|
|
|
csvFileWriter.setFileEncoding(content);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
private void setupErrorSideBar(ResourceBundle resourceBundle) {
|
|
|
|
|
errorSideBar = new ErrorSideBar(resourceBundle);
|
|
|
|
|
errorSideBar.selectedValidationErrorProperty().addListener((observable, oldValue, newValue) -> {
|
|
|
|
|
scrollToError(newValue);
|
|
|
|
|
});
|
|
|
|
|
applicationPane.setRight(errorSideBar);
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
private void setupTableCellFactory() {
|
|
|
|
|
cellFactory = new ValidationCellFactory(resourceBundle);
|
|
|
|
|
}
|
2016-01-11 09:03:22 +01:00
|
|
|
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// setter
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
@Value("${fxml.smartcvs.view}")
|
|
|
|
|
@Override
|
|
|
|
|
public void setFxmlFilePath(String filePath) {
|
|
|
|
|
this.fxmlFilePath = filePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// actions
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
public void openCsv(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
loadFile(CSV_FILTER_TEXT, CSV_FILTER_EXTENSION, "Open CSV", currentCsvFile);
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
public void openConfig(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
loadFile(JSON_FILTER_TEXT, JSON_FILTER_EXTENSION, "Open Validation Configuration", currentConfigFile);
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
@FXML
|
|
|
|
|
public void createConfig(ActionEvent actionEvent) {
|
|
|
|
|
currentConfigFile.setContent(currentCsvFile.getContent().createValidationConfiguration());
|
|
|
|
|
currentConfigFile.setFile(null);
|
|
|
|
|
currentConfigFile.setFileChanged(true);
|
2016-07-23 00:40:41 +02:00
|
|
|
resetContent();
|
2016-07-22 23:51:08 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
@FXML
|
|
|
|
|
public void saveCsv(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
useSaveFileService(currentCsvFile);
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
public void saveAsCsv(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
saveFile(CSV_FILTER_TEXT, CSV_FILTER_EXTENSION, currentCsvFile);
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
@FXML
|
|
|
|
|
public void saveConfig(ActionEvent actionEvent) {
|
2016-07-22 23:51:08 +02:00
|
|
|
if (currentConfigFile.getFile() == null) {
|
|
|
|
|
saveAsConfig(actionEvent);
|
|
|
|
|
} else {
|
|
|
|
|
useSaveFileService(currentConfigFile);
|
|
|
|
|
}
|
2016-02-05 08:00:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
public void saveAsConfig(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
saveFile(JSON_FILTER_TEXT, JSON_FILTER_EXTENSION, currentConfigFile);
|
2016-02-05 08:00:32 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
@FXML
|
|
|
|
|
public void close(ActionEvent actionEvent) {
|
2015-12-18 12:19:19 +01:00
|
|
|
if (canExit()) {
|
2015-12-30 09:52:00 +01:00
|
|
|
exit();
|
2015-12-18 12:19:19 +01:00
|
|
|
}
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
2015-12-02 13:53:20 +01:00
|
|
|
@FXML
|
|
|
|
|
public void about(ActionEvent actionEvent) {
|
|
|
|
|
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
|
|
|
|
alert.setTitle("About");
|
|
|
|
|
alert.setHeaderText("SmartCSV.fx");
|
2015-12-30 14:22:52 +01:00
|
|
|
alert.getDialogPane().setContent(aboutController.getView());
|
2015-12-02 13:53:20 +01:00
|
|
|
alert.showAndWait();
|
2015-12-18 12:19:19 +01:00
|
|
|
}
|
2015-11-28 23:06:14 +01:00
|
|
|
|
2016-01-11 09:03:22 +01:00
|
|
|
@FXML
|
|
|
|
|
public void preferences(ActionEvent actionEvent) {
|
|
|
|
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
2016-01-12 22:03:20 +01:00
|
|
|
alert.setGraphic(null);
|
|
|
|
|
alert.setTitle(resourceBundle.getString("dialog.preferences.title"));
|
|
|
|
|
alert.setHeaderText(resourceBundle.getString("dialog.preferences.header.text"));
|
2016-01-11 09:03:22 +01:00
|
|
|
alert.getDialogPane().setContent(preferencesController.getView());
|
2016-01-12 22:42:24 +01:00
|
|
|
|
|
|
|
|
Node okButton = alert.getDialogPane().lookupButton(ButtonType.OK);
|
|
|
|
|
okButton.disableProperty().bind(preferencesController.validProperty().not());
|
|
|
|
|
|
2016-01-11 09:03:22 +01:00
|
|
|
Optional<ButtonType> result = alert.showAndWait();
|
|
|
|
|
|
|
|
|
|
if (result.get() == ButtonType.OK){
|
2021-12-10 00:30:59 +01:00
|
|
|
Preferences csvPreference = preferencesController.getCsvPreference();
|
2016-01-11 11:14:25 +01:00
|
|
|
setCsvPreference(csvPreference);
|
|
|
|
|
saveCsvPreferences(csvPreference);
|
2019-10-18 16:30:29 +09:00
|
|
|
String fileEncoding = CharsetHelper.getCharsetName(preferencesController.getFileEncoding());
|
|
|
|
|
setFileEncoding(fileEncoding);
|
|
|
|
|
saveFileEncoding(fileEncoding);
|
2016-01-12 22:42:24 +01:00
|
|
|
} else {
|
2016-07-22 20:45:26 +02:00
|
|
|
preferencesController.setCsvPreference(csvPreferenceFile.getContent());
|
2019-10-18 16:30:29 +09:00
|
|
|
preferencesController.setFileEncoding(fileEncodingFile.getContent());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveFileEncoding(String fileEncoding) {
|
|
|
|
|
try {
|
|
|
|
|
createFileEncodingFile();
|
|
|
|
|
fileEncodingFile.setContent(fileEncoding);
|
|
|
|
|
useSaveFileService(fileEncodingFile);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createFileEncodingFile() throws IOException {
|
|
|
|
|
if (!fileEncodingFile.getFile().exists()) {
|
|
|
|
|
createPreferencesFileFolder();
|
|
|
|
|
fileEncodingFile.getFile().createNewFile();
|
2016-01-11 09:03:22 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
@FXML
|
|
|
|
|
public void deleteRow(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
currentCsvFile.getContent().getRows().removeAll(tableView.getSelectionModel().getSelectedItems());
|
|
|
|
|
currentCsvFile.setFileChanged(true);
|
2016-01-13 23:07:29 +01:00
|
|
|
resetContent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
public void addRow(ActionEvent actionEvent) {
|
2016-07-22 20:45:26 +02:00
|
|
|
CSVRow row = currentCsvFile.getContent().addRow();
|
|
|
|
|
for (String column : currentCsvFile.getContent().getHeader()) {
|
2016-08-07 23:13:02 +02:00
|
|
|
currentCsvFile.getContent().addValue(row, column, "");
|
2016-01-13 23:07:29 +01:00
|
|
|
}
|
2016-07-22 20:45:26 +02:00
|
|
|
currentCsvFile.setFileChanged(true);
|
2016-01-13 23:07:29 +01:00
|
|
|
resetContent();
|
|
|
|
|
|
|
|
|
|
selectNewRow();
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-05 23:09:22 +02:00
|
|
|
@FXML
|
|
|
|
|
public void gotoLine(ActionEvent actionEvent) {
|
|
|
|
|
int maxLineNumber = currentCsvFile.getContent().getRows().size();
|
|
|
|
|
GotoLineDialog dialog = new GotoLineDialog(maxLineNumber);
|
|
|
|
|
dialog.setTitle(resourceBundle.getString("dialog.goto.line.title"));
|
|
|
|
|
dialog.setHeaderText(format(resourceBundle.getString("dialog.goto.line.header.text"), maxLineNumber));
|
|
|
|
|
dialog.setContentText(resourceBundle.getString("dialog.goto.line.label"));
|
|
|
|
|
Optional<Integer> result = dialog.showAndWait();
|
|
|
|
|
if (result.isPresent()){
|
|
|
|
|
Integer lineNumber = result.get();
|
|
|
|
|
if (lineNumber != null) {
|
|
|
|
|
tableView.scrollTo(max(0, lineNumber - 2));
|
|
|
|
|
tableView.getSelectionModel().select(lineNumber - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-10 23:41:47 +02:00
|
|
|
@FXML
|
|
|
|
|
public void export(ActionEvent actionEvent) {
|
|
|
|
|
final FileChooser fileChooser = new FileChooser();
|
|
|
|
|
|
|
|
|
|
//Set extension filter
|
|
|
|
|
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(EXPORT_LOG_FILTER_TEXT, EXPORT_LOG_FILTER_EXTENSION);
|
|
|
|
|
fileChooser.getExtensionFilters().add(extFilter);
|
|
|
|
|
fileChooser.setTitle("Save");
|
|
|
|
|
|
|
|
|
|
//Show open file dialog
|
|
|
|
|
File file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow());
|
|
|
|
|
if (file != null) {
|
|
|
|
|
errorExport.setCsvFilename(currentCsvFile.getFile().getName());
|
|
|
|
|
errorExport.setModel(currentCsvFile.getContent());
|
|
|
|
|
errorExport.setFile(file);
|
|
|
|
|
errorExport.setResourceBundle(resourceBundle);
|
|
|
|
|
errorExport.restart();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-18 12:19:19 +01:00
|
|
|
public boolean canExit() {
|
|
|
|
|
boolean canExit = true;
|
2016-07-22 20:45:26 +02:00
|
|
|
if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) {
|
2015-12-18 12:19:19 +01:00
|
|
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
|
|
|
alert.setTitle(resourceBundle.getString("dialog.exit.title"));
|
|
|
|
|
alert.setHeaderText(resourceBundle.getString("dialog.exit.header.text"));
|
|
|
|
|
alert.setContentText(resourceBundle.getString("dialog.exit.text"));
|
|
|
|
|
|
|
|
|
|
Optional<ButtonType> result = alert.showAndWait();
|
|
|
|
|
if (result.get() != ButtonType.OK){
|
|
|
|
|
canExit = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return canExit;
|
2015-12-02 13:53:20 +01:00
|
|
|
}
|
2015-12-18 12:19:19 +01:00
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
public void showValidationEditor(String column) {
|
|
|
|
|
validationEditorController.setSelectedColumn(column);
|
2016-09-12 04:48:22 +02:00
|
|
|
validationEditorController.updateForm();
|
2016-02-05 08:00:32 +01:00
|
|
|
|
|
|
|
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
|
|
|
alert.setGraphic(null);
|
|
|
|
|
alert.setTitle(resourceBundle.getString("dialog.validation.rules.title"));
|
|
|
|
|
alert.setHeaderText(format(resourceBundle.getString("dialog.validation.rules.header"), column));
|
|
|
|
|
alert.getDialogPane().setContent(validationEditorController.getView());
|
|
|
|
|
Optional<ButtonType> result = alert.showAndWait();
|
|
|
|
|
|
|
|
|
|
if (result.get() == ButtonType.OK){
|
|
|
|
|
runLater(() -> {
|
|
|
|
|
validationEditorController.updateConfiguration();
|
2016-07-22 20:45:26 +02:00
|
|
|
currentCsvFile.setFileChanged(true);
|
2016-08-07 23:13:02 +02:00
|
|
|
currentCsvFile.getContent().revalidate(column);
|
2016-02-05 08:00:32 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// private methods
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
private void selectNewRow() {
|
|
|
|
|
int lastRow = tableView.getItems().size()-1;
|
|
|
|
|
tableView.scrollTo(lastRow);
|
|
|
|
|
tableView.requestFocus();
|
|
|
|
|
tableView.getSelectionModel().select(lastRow);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
private void bindMenuItemsToContentExistence(FileStorage file, MenuItem... items) {
|
2016-01-13 23:07:29 +01:00
|
|
|
for (MenuItem item: items) {
|
2016-07-22 23:51:08 +02:00
|
|
|
item.disableProperty().bind(isNull(file.contentProperty()));
|
2016-01-12 21:58:27 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
private void bindButtonsToContentExistence(FileStorage file, Button... items) {
|
2016-01-13 23:07:29 +01:00
|
|
|
for (Button item: items) {
|
2016-07-22 23:51:08 +02:00
|
|
|
item.disableProperty().bind(isNull(file.contentProperty()));
|
2016-01-12 21:52:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
private void bindMenuItemsToTableSelection(MenuItem... items) {
|
|
|
|
|
for (MenuItem item: items) {
|
|
|
|
|
item.disableProperty().bind(lessThan(tableView.getSelectionModel().selectedIndexProperty(), 0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void bindButtonsToTableSelection(Button... items) {
|
|
|
|
|
for (Button item: items) {
|
|
|
|
|
item.disableProperty().bind(lessThan(tableView.getSelectionModel().selectedIndexProperty(), 0));
|
2016-01-12 21:52:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
private void bindCsvFileName() {
|
2016-07-22 20:45:26 +02:00
|
|
|
csvName.textProperty().bind(selectString(currentCsvFile.fileProperty(), "name"));
|
2016-01-13 23:07:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void bindConfigFileName() {
|
2016-07-22 20:45:26 +02:00
|
|
|
configurationName.textProperty().bind(selectString(currentConfigFile.fileProperty(), "name"));
|
2016-01-13 23:07:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-05 23:09:22 +02:00
|
|
|
private void bindLineNumber() {
|
|
|
|
|
currentLineNumber.textProperty().bind(tableView.getSelectionModel().selectedIndexProperty().add(1).asString());
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
private void loadCsvPreferencesFromFile() {
|
2016-07-22 20:45:26 +02:00
|
|
|
if (csvPreferenceFile.getFile().exists()) {
|
2019-10-18 16:30:29 +09:00
|
|
|
useLoadFileService(csvPreferenceFile, event -> {
|
|
|
|
|
setCsvPreference(csvPreferenceFile.getContent());
|
|
|
|
|
loadEncodingFromFile();
|
|
|
|
|
});
|
2016-02-16 17:18:37 +01:00
|
|
|
} else {
|
2021-12-10 00:30:59 +01:00
|
|
|
setCsvPreference(defaultPreferences());
|
2019-10-18 16:30:29 +09:00
|
|
|
loadEncodingFromFile();
|
2016-01-11 11:14:25 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 00:30:59 +01:00
|
|
|
private void saveCsvPreferences(Preferences csvPreference) {
|
2016-01-11 11:14:25 +01:00
|
|
|
try {
|
|
|
|
|
createPreferenceFile();
|
2016-07-22 20:45:26 +02:00
|
|
|
csvPreferenceFile.setContent(csvPreference);
|
|
|
|
|
useSaveFileService(csvPreferenceFile);
|
2016-01-11 11:14:25 +01:00
|
|
|
} catch (IOException e) {
|
2016-01-11 09:03:22 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-11 11:14:25 +01:00
|
|
|
private void createPreferenceFile() throws IOException {
|
2016-07-22 20:45:26 +02:00
|
|
|
if (!csvPreferenceFile.getFile().exists()) {
|
2016-01-11 11:14:25 +01:00
|
|
|
createPreferencesFileFolder();
|
2016-07-22 20:45:26 +02:00
|
|
|
csvPreferenceFile.getFile().createNewFile();
|
2016-01-11 11:14:25 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createPreferencesFileFolder() {
|
2016-07-22 20:45:26 +02:00
|
|
|
if (!csvPreferenceFile.getFile().getParentFile().exists()) {
|
|
|
|
|
csvPreferenceFile.getFile().getParentFile().mkdir();
|
2016-01-11 11:14:25 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 00:30:59 +01:00
|
|
|
private void setCsvPreference(Preferences csvPreference) {
|
2016-01-11 09:03:22 +01:00
|
|
|
preferencesController.setCsvPreference(csvPreference);
|
2016-09-14 19:23:36 +02:00
|
|
|
csvFileReader.setCsvPreference(csvPreference);
|
|
|
|
|
csvFileWriter.setCsvPreference(csvPreference);
|
|
|
|
|
|
2016-01-11 09:03:22 +01:00
|
|
|
}
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
private void loadFile(String filterText,
|
2016-01-12 21:52:08 +01:00
|
|
|
String filter,
|
|
|
|
|
String title,
|
2016-07-22 20:45:26 +02:00
|
|
|
FileStorage storageFile) {
|
2015-11-28 23:06:14 +01:00
|
|
|
final FileChooser fileChooser = new FileChooser();
|
|
|
|
|
|
|
|
|
|
//Set extension filter
|
|
|
|
|
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(filterText, filter);
|
|
|
|
|
fileChooser.getExtensionFilters().add(extFilter);
|
|
|
|
|
fileChooser.setTitle(title);
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
if (storageFile.getFile() != null) {
|
|
|
|
|
fileChooser.setInitialDirectory(storageFile.getFile().getParentFile());
|
2015-12-18 01:00:58 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
//Show open file dialog
|
2016-01-12 21:52:08 +01:00
|
|
|
File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow());
|
2022-10-19 12:34:55 +02:00
|
|
|
openFile(storageFile, file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void openFile(FileStorage storageFile, File file) {
|
2015-11-28 23:06:14 +01:00
|
|
|
if (file != null) {
|
2021-10-29 05:05:13 -07:00
|
|
|
File previousFile = storageFile.getFile();
|
2016-07-22 20:45:26 +02:00
|
|
|
storageFile.setFile(file);
|
2021-10-29 05:05:13 -07:00
|
|
|
useLoadFileService(storageFile, t -> resetContent(), () -> storageFile.setFile(previousFile));
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
private File saveFile(String filterText, String filter, FileStorage fileStorage) {
|
|
|
|
|
File file = fileStorage.getFile();
|
|
|
|
|
if (fileStorage.getContent() != null) {
|
2015-11-28 23:06:14 +01:00
|
|
|
final FileChooser fileChooser = new FileChooser();
|
|
|
|
|
|
|
|
|
|
//Set extension filter
|
|
|
|
|
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(filterText, filter);
|
|
|
|
|
fileChooser.getExtensionFilters().add(extFilter);
|
|
|
|
|
|
2016-07-22 23:51:08 +02:00
|
|
|
if (fileStorage.getFile() != null) {
|
|
|
|
|
fileChooser.setInitialDirectory(fileStorage.getFile().getParentFile());
|
|
|
|
|
fileChooser.setInitialFileName(fileStorage.getFile().getName());
|
2016-01-12 21:52:08 +01:00
|
|
|
}
|
2015-11-28 23:06:14 +01:00
|
|
|
fileChooser.setTitle("Save File");
|
|
|
|
|
|
|
|
|
|
//Show open file dialog
|
2016-01-12 21:52:08 +01:00
|
|
|
file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow());
|
2015-11-28 23:06:14 +01:00
|
|
|
if (file != null) {
|
2016-07-22 23:51:08 +02:00
|
|
|
fileStorage.setFile(file);
|
|
|
|
|
useSaveFileService(fileStorage);
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
}
|
2016-01-12 21:52:08 +01:00
|
|
|
return file;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 05:05:13 -07:00
|
|
|
private void useLoadFileService(FileStorage<?> fileStorage, EventHandler<WorkerStateEvent> onSucceededHandler) {
|
|
|
|
|
useLoadFileService(fileStorage, onSucceededHandler, () -> {
|
|
|
|
|
// nothing to rollback
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void useLoadFileService(FileStorage<?> fileStorage, EventHandler<WorkerStateEvent> onSucceededHandler, Runnable rollbackAction) {
|
2016-07-22 20:45:26 +02:00
|
|
|
loadFileService.setFileStorage(fileStorage);
|
2016-01-12 21:52:08 +01:00
|
|
|
loadFileService.restart();
|
2016-07-22 23:51:08 +02:00
|
|
|
loadFileService.setOnSucceeded(onSucceededHandler);
|
2021-10-29 05:05:13 -07:00
|
|
|
loadFileService.setOnFailed(event -> JavaFxUtils.onServiceError(event, "LoadFileService Error", "Failed to load the file.", rollbackAction));
|
2016-01-12 21:52:08 +01:00
|
|
|
}
|
|
|
|
|
|
2021-10-29 05:05:13 -07:00
|
|
|
private void useSaveFileService(FileStorage<?> fileStorage) {
|
2016-07-22 20:45:26 +02:00
|
|
|
saveFileService.setFileStorage(fileStorage);
|
2016-01-12 21:52:08 +01:00
|
|
|
saveFileService.restart();
|
2016-07-22 23:51:08 +02:00
|
|
|
saveFileService.setOnSucceeded(t -> resetContent());
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates new table view and add the new content
|
|
|
|
|
*/
|
|
|
|
|
private void resetContent() {
|
2016-08-10 23:41:47 +02:00
|
|
|
resetExportButtons();
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
if (currentCsvFile.getContent() != null) {
|
|
|
|
|
currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener);
|
|
|
|
|
currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent());
|
|
|
|
|
validationEditorController.setValidationConfiguration(currentConfigFile.getContent());
|
2015-12-18 01:00:58 +01:00
|
|
|
tableView = new TableView<>();
|
2016-08-05 23:09:22 +02:00
|
|
|
bindLineNumber();
|
2015-11-28 23:06:14 +01:00
|
|
|
|
2016-01-13 23:07:29 +01:00
|
|
|
bindMenuItemsToTableSelection(deleteRowMenuItem);
|
|
|
|
|
bindButtonsToTableSelection(deleteRowButton);
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
for (String column : currentCsvFile.getContent().getHeader()) {
|
2015-12-18 01:00:58 +01:00
|
|
|
addColumn(column, tableView);
|
|
|
|
|
}
|
2016-01-13 23:07:29 +01:00
|
|
|
|
2019-10-23 00:10:19 +02:00
|
|
|
tableView.getColumns().addListener(
|
|
|
|
|
(InvalidationListener) observable -> currentCsvFile.getContent().setHeader(
|
|
|
|
|
tableView.getColumns().stream().map((x) -> x.getText()).toArray(String[]::new)));
|
|
|
|
|
|
2016-07-22 20:45:26 +02:00
|
|
|
tableView.getItems().setAll(currentCsvFile.getContent().getRows());
|
2015-12-18 01:00:58 +01:00
|
|
|
tableView.setEditable(true);
|
2015-12-07 22:41:59 +01:00
|
|
|
|
2022-10-15 13:41:31 +02:00
|
|
|
totalNumberOfLines.textProperty().setValue("" + currentCsvFile.getContent().getRows().size());
|
|
|
|
|
|
2016-01-12 21:52:08 +01:00
|
|
|
setBottomAnchor(tableView, 0.0);
|
|
|
|
|
setTopAnchor(tableView, 0.0);
|
|
|
|
|
setLeftAnchor(tableView, 0.0);
|
|
|
|
|
setRightAnchor(tableView, 0.0);
|
2015-12-18 01:00:58 +01:00
|
|
|
tableWrapper.getChildren().setAll(tableView);
|
2016-07-22 20:45:26 +02:00
|
|
|
errorSideBar.setModel(currentCsvFile.getContent());
|
2016-08-10 23:41:47 +02:00
|
|
|
binExportButtons();
|
2015-12-18 01:00:58 +01:00
|
|
|
}
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-10 23:41:47 +02:00
|
|
|
private void binExportButtons() {
|
|
|
|
|
exportButton.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError()));
|
|
|
|
|
exportMenuItem.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void resetExportButtons() {
|
|
|
|
|
exportButton.disableProperty().unbind();
|
|
|
|
|
exportMenuItem.disableProperty().unbind();
|
|
|
|
|
exportButton.disableProperty().setValue(true);
|
|
|
|
|
exportMenuItem.disableProperty().setValue(true);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
/**
|
|
|
|
|
* Adds a column with the given name to the tableview
|
|
|
|
|
* @param header name of the column header
|
|
|
|
|
* @param tableView the tableview
|
|
|
|
|
*/
|
2016-08-07 23:13:02 +02:00
|
|
|
private void addColumn(final String header, TableView tableView) {
|
2015-11-28 23:06:14 +01:00
|
|
|
TableColumn column = new TableColumn(header);
|
|
|
|
|
column.setCellValueFactory(new ObservableMapValueFactory(header));
|
|
|
|
|
column.setCellFactory(cellFactory);
|
|
|
|
|
column.setEditable(true);
|
2016-02-05 08:00:32 +01:00
|
|
|
column.setSortable(false);
|
|
|
|
|
|
|
|
|
|
ContextMenu contextMenu = contextMenuForColumn(header);
|
|
|
|
|
column.setContextMenu(contextMenu);
|
|
|
|
|
|
2015-11-28 23:06:14 +01:00
|
|
|
column.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CSVRow, CSVValue>>() {
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(TableColumn.CellEditEvent<CSVRow, CSVValue> event) {
|
|
|
|
|
event.getTableView().getItems().get(event.getTablePosition().getRow()).
|
2015-12-18 01:47:38 +01:00
|
|
|
getColumns().get(header).setValue(event.getNewValue());
|
2015-12-18 12:19:19 +01:00
|
|
|
runLater(() -> {
|
2016-07-22 20:45:26 +02:00
|
|
|
currentCsvFile.setFileChanged(true);
|
2015-12-18 12:19:19 +01:00
|
|
|
});
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tableView.getColumns().add(column);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 08:00:32 +01:00
|
|
|
private ContextMenu contextMenuForColumn(String header) {
|
|
|
|
|
ContextMenu contextMenu = new ContextMenu();
|
|
|
|
|
MenuItem editColumnRulesMenuItem = new MenuItem(resourceBundle.getString("context.menu.edit.column.rules"));
|
2016-07-22 23:51:08 +02:00
|
|
|
bindMenuItemsToContentExistence(currentConfigFile, editColumnRulesMenuItem);
|
2016-02-05 08:00:32 +01:00
|
|
|
editColumnRulesMenuItem.setOnAction(e -> showValidationEditor(header));
|
|
|
|
|
contextMenu.getItems().addAll(editColumnRulesMenuItem);
|
|
|
|
|
return contextMenu;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-27 04:39:53 +01:00
|
|
|
private void scrollToError(ValidationError entry) {
|
2015-12-07 22:41:59 +01:00
|
|
|
if (entry != null) {
|
|
|
|
|
if (entry.getLineNumber() != null) {
|
2015-12-17 22:57:26 +01:00
|
|
|
tableView.scrollTo(max(0, entry.getLineNumber() - 1));
|
2015-12-07 22:41:59 +01:00
|
|
|
tableView.getSelectionModel().select(entry.getLineNumber());
|
|
|
|
|
} else {
|
|
|
|
|
tableView.scrollTo(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-11-28 23:06:14 +01:00
|
|
|
}
|