mirror of
https://github.com/frosch95/SmartCSV.fx.git
synced 2026-04-11 13:38:23 +02:00
Merge remote-tracking branch 'remotes/origin/create_validation_config_based_on_csv'
This commit is contained in:
@@ -9,6 +9,11 @@ even in a "normal" CSV editor. So I decided to write this simple JavaFX applicat
|
|||||||
##Video
|
##Video
|
||||||
[](https://youtu.be/SH0UAtPG6Eg)
|
[](https://youtu.be/SH0UAtPG6Eg)
|
||||||
|
|
||||||
|
##Links
|
||||||
|
[GitHub Page](http://frosch95.github.io/SmartCSV.fx/)
|
||||||
|
[Wiki & Documentation](https://github.com/frosch95/SmartCSV.fx/wiki)
|
||||||
|
binary distribution of the [latest release (0.4)](https://drive.google.com/open?id=0BwY9gBUvn5qmREdCc0FvNDNEQTA)
|
||||||
|
|
||||||
##License
|
##License
|
||||||
###The MIT License (MIT)
|
###The MIT License (MIT)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
group 'ninja.javafx'
|
group 'ninja.javafx'
|
||||||
version '0.3-SNAPSHOT'
|
version '0.4-SNAPSHOT'
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'groovy'
|
apply plugin: 'groovy'
|
||||||
@@ -22,7 +22,12 @@ dependencies {
|
|||||||
compile group: 'org.springframework', name:'spring-context', version: '4.3.1.RELEASE'
|
compile group: 'org.springframework', name:'spring-context', version: '4.3.1.RELEASE'
|
||||||
compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0'
|
compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0'
|
||||||
compile group: 'commons-validator', name: 'commons-validator', version: '1.5.1'
|
compile group: 'commons-validator', name: 'commons-validator', version: '1.5.1'
|
||||||
compile group: 'de.jensd', name: 'fontawesomefx', version: '8.9'
|
compile group: 'de.jensd', name: 'fontawesomefx-commons', version: '8.12'
|
||||||
|
compile group: 'de.jensd', name: 'fontawesomefx-fontawesome', version: '4.6.3'
|
||||||
|
compile group: 'de.jensd', name: 'fontawesomefx-materialdesignfont', version: '1.6.50'
|
||||||
|
compile group: 'de.jensd', name: 'fontawesomefx-materialicons', version: '2.2.0'
|
||||||
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.11'
|
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.11'
|
||||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
|
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
|
||||||
|
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.6.2'
|
||||||
|
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* read some file
|
* read some file
|
||||||
*/
|
*/
|
||||||
public interface FileReader {
|
public interface FileReader<E> {
|
||||||
|
E getContent();
|
||||||
void read(File filename) throws IOException;
|
void read(File filename) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* write some file
|
* write some file
|
||||||
*/
|
*/
|
||||||
public interface FileWriter {
|
public interface FileWriter<E> {
|
||||||
|
void setContent(E content);
|
||||||
void write(File filename) throws IOException;
|
void write(File filename) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* reads the csv file and stores the values in csv model
|
* reads the csv file and stores the values in csv model
|
||||||
*/
|
*/
|
||||||
@Service
|
public class CSVFileReader extends CSVConfigurable implements FileReader<CSVModel> {
|
||||||
public class CSVFileReader extends CSVConfigurable implements FileReader {
|
|
||||||
|
|
||||||
private CSVModel model;
|
private CSVModel model;
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ public class CSVFileReader extends CSVConfigurable implements FileReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CSVModel getData() {
|
public CSVModel getContent() {
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,12 +42,11 @@ import static java.util.stream.Collectors.toMap;
|
|||||||
/**
|
/**
|
||||||
* filewriter for the csv
|
* filewriter for the csv
|
||||||
*/
|
*/
|
||||||
@Service
|
public class CSVFileWriter extends CSVConfigurable implements ninja.javafx.smartcsv.FileWriter<CSVModel> {
|
||||||
public class CSVFileWriter extends CSVConfigurable implements ninja.javafx.smartcsv.FileWriter {
|
|
||||||
|
|
||||||
private CSVModel model;
|
private CSVModel model;
|
||||||
|
|
||||||
public void setModel(CSVModel model) {
|
public void setContent(CSVModel model) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
78
src/main/java/ninja/javafx/smartcsv/files/FileStorage.java
Normal file
78
src/main/java/ninja/javafx/smartcsv/files/FileStorage.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package ninja.javafx.smartcsv.files;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import ninja.javafx.smartcsv.FileReader;
|
||||||
|
import ninja.javafx.smartcsv.FileWriter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class stores files and there state
|
||||||
|
* @author abi
|
||||||
|
*/
|
||||||
|
public class FileStorage<E> {
|
||||||
|
|
||||||
|
private FileReader<E> reader;
|
||||||
|
private FileWriter<E> writer;
|
||||||
|
|
||||||
|
public FileStorage(FileReader<E> reader, FileWriter<E> writer) {
|
||||||
|
this.reader = reader;
|
||||||
|
this.writer = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BooleanProperty fileChanged = new SimpleBooleanProperty(true);
|
||||||
|
private ObjectProperty<File> file = new SimpleObjectProperty<>();
|
||||||
|
private ObjectProperty<E> content = new SimpleObjectProperty<E>();
|
||||||
|
|
||||||
|
public boolean isFileChanged() {
|
||||||
|
return fileChanged.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty fileChangedProperty() {
|
||||||
|
return fileChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileChanged(boolean fileChanged) {
|
||||||
|
this.fileChanged.set(fileChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<File> fileProperty() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile(File file) {
|
||||||
|
this.file.set(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getContent() {
|
||||||
|
return content.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<E> contentProperty() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(E content) {
|
||||||
|
this.content.set(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() throws IOException {
|
||||||
|
reader.read(file.get());
|
||||||
|
setContent(reader.getContent());
|
||||||
|
setFileChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() throws IOException {
|
||||||
|
writer.setContent(content.get());
|
||||||
|
writer.write(file.get());
|
||||||
|
setFileChanged(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,10 +26,6 @@
|
|||||||
|
|
||||||
package ninja.javafx.smartcsv.fx;
|
package ninja.javafx.smartcsv.fx;
|
||||||
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.WeakListChangeListener;
|
import javafx.collections.WeakListChangeListener;
|
||||||
import javafx.concurrent.WorkerStateEvent;
|
import javafx.concurrent.WorkerStateEvent;
|
||||||
@@ -41,10 +37,9 @@ import javafx.scene.control.*;
|
|||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import ninja.javafx.smartcsv.FileReader;
|
|
||||||
import ninja.javafx.smartcsv.FileWriter;
|
|
||||||
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
||||||
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
||||||
|
import ninja.javafx.smartcsv.files.FileStorage;
|
||||||
import ninja.javafx.smartcsv.fx.about.AboutController;
|
import ninja.javafx.smartcsv.fx.about.AboutController;
|
||||||
import ninja.javafx.smartcsv.fx.list.ErrorSideBar;
|
import ninja.javafx.smartcsv.fx.list.ErrorSideBar;
|
||||||
import ninja.javafx.smartcsv.fx.preferences.PreferencesController;
|
import ninja.javafx.smartcsv.fx.preferences.PreferencesController;
|
||||||
@@ -58,6 +53,7 @@ import ninja.javafx.smartcsv.fx.util.SaveFileService;
|
|||||||
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
|
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
|
||||||
import ninja.javafx.smartcsv.preferences.PreferencesFileReader;
|
import ninja.javafx.smartcsv.preferences.PreferencesFileReader;
|
||||||
import ninja.javafx.smartcsv.preferences.PreferencesFileWriter;
|
import ninja.javafx.smartcsv.preferences.PreferencesFileWriter;
|
||||||
|
import ninja.javafx.smartcsv.validation.ValidationConfiguration;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationFileWriter;
|
import ninja.javafx.smartcsv.validation.ValidationFileWriter;
|
||||||
@@ -103,24 +99,6 @@ public class SmartCSVController extends FXMLController {
|
|||||||
// injections
|
// injections
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PreferencesFileReader preferencesLoader;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PreferencesFileWriter preferencesWriter;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CSVFileReader csvLoader;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ValidationFileReader validationLoader;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CSVFileWriter csvFileWriter;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ValidationFileWriter validationFileWriter;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AboutController aboutController;
|
private AboutController aboutController;
|
||||||
|
|
||||||
@@ -134,7 +112,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
private LoadFileService loadFileService;
|
private LoadFileService loadFileService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SaveFileService saveFileService;;
|
private SaveFileService saveFileService;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private BorderPane applicationPane;
|
private BorderPane applicationPane;
|
||||||
@@ -157,6 +135,9 @@ public class SmartCSVController extends FXMLController {
|
|||||||
@FXML
|
@FXML
|
||||||
private MenuItem saveAsMenuItem;
|
private MenuItem saveAsMenuItem;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private MenuItem createConfigMenuItem;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private MenuItem loadConfigMenuItem;
|
private MenuItem loadConfigMenuItem;
|
||||||
|
|
||||||
@@ -178,6 +159,9 @@ public class SmartCSVController extends FXMLController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button saveAsButton;
|
private Button saveAsButton;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button createConfigButton;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button loadConfigButton;
|
private Button loadConfigButton;
|
||||||
|
|
||||||
@@ -199,13 +183,13 @@ public class SmartCSVController extends FXMLController {
|
|||||||
|
|
||||||
private ValidationCellFactory cellFactory;
|
private ValidationCellFactory cellFactory;
|
||||||
|
|
||||||
private CSVModel model;
|
|
||||||
private TableView<CSVRow> tableView;
|
private TableView<CSVRow> tableView;
|
||||||
private ErrorSideBar errorSideBar;
|
private ErrorSideBar errorSideBar;
|
||||||
private BooleanProperty fileChanged = new SimpleBooleanProperty(true);
|
|
||||||
private ResourceBundle resourceBundle;
|
private ResourceBundle resourceBundle;
|
||||||
private ObjectProperty<File> currentCsvFile = new SimpleObjectProperty<>();
|
|
||||||
private ObjectProperty<File> currentConfigFile= new SimpleObjectProperty<>();
|
private FileStorage<CSVModel> currentCsvFile = new FileStorage<>(new CSVFileReader(), new CSVFileWriter());
|
||||||
|
private FileStorage<ValidationConfiguration> currentConfigFile = new FileStorage<>(new ValidationFileReader(), new ValidationFileWriter());
|
||||||
|
private FileStorage<CsvPreference> csvPreferenceFile = new FileStorage<>(new PreferencesFileReader(), new PreferencesFileWriter());
|
||||||
|
|
||||||
private ListChangeListener<ValidationError> errorListListener = c -> tableView.refresh();
|
private ListChangeListener<ValidationError> errorListListener = c -> tableView.refresh();
|
||||||
private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener);
|
private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener);
|
||||||
@@ -221,15 +205,17 @@ public class SmartCSVController extends FXMLController {
|
|||||||
setupTableCellFactory();
|
setupTableCellFactory();
|
||||||
setupErrorSideBar(resourceBundle);
|
setupErrorSideBar(resourceBundle);
|
||||||
|
|
||||||
bindMenuItemsToFileExistence(currentCsvFile, saveMenuItem, saveAsMenuItem, addRowMenuItem, loadConfigMenuItem);
|
bindMenuItemsToContentExistence(currentCsvFile, saveMenuItem, saveAsMenuItem, addRowMenuItem, createConfigMenuItem, loadConfigMenuItem);
|
||||||
bindButtonsToFileExistence(currentCsvFile, saveButton, saveAsButton, addRowButton, loadConfigButton);
|
bindButtonsToContentExistence(currentCsvFile, saveButton, saveAsButton, addRowButton, createConfigButton, loadConfigButton);
|
||||||
|
|
||||||
bindMenuItemsToFileExistence(currentConfigFile, saveConfigMenuItem, saveAsConfigMenuItem);
|
bindMenuItemsToContentExistence(currentConfigFile, saveConfigMenuItem, saveAsConfigMenuItem);
|
||||||
bindButtonsToFileExistence(currentConfigFile, saveAsConfigButton, saveConfigButton);
|
bindButtonsToContentExistence(currentConfigFile, saveAsConfigButton, saveConfigButton);
|
||||||
|
|
||||||
bindCsvFileName();
|
bindCsvFileName();
|
||||||
bindConfigFileName();
|
bindConfigFileName();
|
||||||
|
|
||||||
|
csvPreferenceFile.setFile(PREFERENCES_FILE);
|
||||||
|
|
||||||
loadCsvPreferencesFromFile();
|
loadCsvPreferencesFromFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,58 +249,43 @@ public class SmartCSVController extends FXMLController {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void openCsv(ActionEvent actionEvent) {
|
public void openCsv(ActionEvent actionEvent) {
|
||||||
currentCsvFile.setValue(
|
loadFile(CSV_FILTER_TEXT, CSV_FILTER_EXTENSION, "Open CSV", currentCsvFile);
|
||||||
loadFile(
|
|
||||||
csvLoader,
|
|
||||||
CSV_FILTER_TEXT,
|
|
||||||
CSV_FILTER_EXTENSION,
|
|
||||||
"Open CSV",
|
|
||||||
currentCsvFile.getValue()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void openConfig(ActionEvent actionEvent) {
|
public void openConfig(ActionEvent actionEvent) {
|
||||||
currentConfigFile.setValue(
|
loadFile(JSON_FILTER_TEXT, JSON_FILTER_EXTENSION, "Open Validation Configuration", currentConfigFile);
|
||||||
loadFile(
|
}
|
||||||
validationLoader,
|
|
||||||
JSON_FILTER_TEXT,
|
@FXML
|
||||||
JSON_FILTER_EXTENSION,
|
public void createConfig(ActionEvent actionEvent) {
|
||||||
"Open Validation Configuration",
|
currentConfigFile.setContent(currentCsvFile.getContent().createValidationConfiguration());
|
||||||
currentConfigFile.getValue()));
|
currentConfigFile.setFile(null);
|
||||||
|
currentConfigFile.setFileChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void saveCsv(ActionEvent actionEvent) {
|
public void saveCsv(ActionEvent actionEvent) {
|
||||||
csvFileWriter.setModel(model);
|
useSaveFileService(currentCsvFile);
|
||||||
useSaveFileService(csvFileWriter, currentCsvFile.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void saveAsCsv(ActionEvent actionEvent) {
|
public void saveAsCsv(ActionEvent actionEvent) {
|
||||||
csvFileWriter.setModel(model);
|
saveFile(CSV_FILTER_TEXT, CSV_FILTER_EXTENSION, currentCsvFile);
|
||||||
currentCsvFile.setValue(
|
|
||||||
saveFile(
|
|
||||||
csvFileWriter,
|
|
||||||
CSV_FILTER_TEXT,
|
|
||||||
CSV_FILTER_EXTENSION,
|
|
||||||
currentCsvFile.getValue()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void saveConfig(ActionEvent actionEvent) {
|
public void saveConfig(ActionEvent actionEvent) {
|
||||||
validationFileWriter.setValidationConfiguration(validationLoader.getValidationConfiguration());
|
if (currentConfigFile.getFile() == null) {
|
||||||
useSaveFileService(validationFileWriter, currentConfigFile.getValue());
|
saveAsConfig(actionEvent);
|
||||||
|
} else {
|
||||||
|
useSaveFileService(currentConfigFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void saveAsConfig(ActionEvent actionEvent) {
|
public void saveAsConfig(ActionEvent actionEvent) {
|
||||||
validationFileWriter.setValidationConfiguration(validationLoader.getValidationConfiguration());
|
saveFile(JSON_FILTER_TEXT, JSON_FILTER_EXTENSION, currentConfigFile);
|
||||||
currentConfigFile.setValue(
|
|
||||||
saveFile(
|
|
||||||
validationFileWriter,
|
|
||||||
JSON_FILTER_TEXT,
|
|
||||||
JSON_FILTER_EXTENSION,
|
|
||||||
currentConfigFile.getValue()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -351,24 +322,24 @@ public class SmartCSVController extends FXMLController {
|
|||||||
setCsvPreference(csvPreference);
|
setCsvPreference(csvPreference);
|
||||||
saveCsvPreferences(csvPreference);
|
saveCsvPreferences(csvPreference);
|
||||||
} else {
|
} else {
|
||||||
preferencesController.setCsvPreference(preferencesLoader.getCSVpreference());
|
preferencesController.setCsvPreference(csvPreferenceFile.getContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void deleteRow(ActionEvent actionEvent) {
|
public void deleteRow(ActionEvent actionEvent) {
|
||||||
model.getRows().removeAll(tableView.getSelectionModel().getSelectedItems());
|
currentCsvFile.getContent().getRows().removeAll(tableView.getSelectionModel().getSelectedItems());
|
||||||
fileChanged.setValue(true);
|
currentCsvFile.setFileChanged(true);
|
||||||
resetContent();
|
resetContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void addRow(ActionEvent actionEvent) {
|
public void addRow(ActionEvent actionEvent) {
|
||||||
CSVRow row = model.addRow();
|
CSVRow row = currentCsvFile.getContent().addRow();
|
||||||
for (String column : model.getHeader()) {
|
for (String column : currentCsvFile.getContent().getHeader()) {
|
||||||
row.addValue(column, "");
|
row.addValue(column, "");
|
||||||
}
|
}
|
||||||
fileChanged.setValue(true);
|
currentCsvFile.setFileChanged(true);
|
||||||
resetContent();
|
resetContent();
|
||||||
|
|
||||||
selectNewRow();
|
selectNewRow();
|
||||||
@@ -376,7 +347,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
|
|
||||||
public boolean canExit() {
|
public boolean canExit() {
|
||||||
boolean canExit = true;
|
boolean canExit = true;
|
||||||
if (model != null && fileChanged.get()) {
|
if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) {
|
||||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
alert.setTitle(resourceBundle.getString("dialog.exit.title"));
|
alert.setTitle(resourceBundle.getString("dialog.exit.title"));
|
||||||
alert.setHeaderText(resourceBundle.getString("dialog.exit.header.text"));
|
alert.setHeaderText(resourceBundle.getString("dialog.exit.header.text"));
|
||||||
@@ -404,8 +375,8 @@ public class SmartCSVController extends FXMLController {
|
|||||||
if (result.get() == ButtonType.OK){
|
if (result.get() == ButtonType.OK){
|
||||||
runLater(() -> {
|
runLater(() -> {
|
||||||
validationEditorController.updateConfiguration();
|
validationEditorController.updateConfiguration();
|
||||||
fileChanged.setValue(true);
|
currentCsvFile.setFileChanged(true);
|
||||||
model.revalidate();
|
currentCsvFile.getContent().revalidate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,15 +392,15 @@ public class SmartCSVController extends FXMLController {
|
|||||||
tableView.getSelectionModel().select(lastRow);
|
tableView.getSelectionModel().select(lastRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindMenuItemsToFileExistence(ObjectProperty<File> file, MenuItem... items) {
|
private void bindMenuItemsToContentExistence(FileStorage file, MenuItem... items) {
|
||||||
for (MenuItem item: items) {
|
for (MenuItem item: items) {
|
||||||
item.disableProperty().bind(isNull(file));
|
item.disableProperty().bind(isNull(file.contentProperty()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindButtonsToFileExistence(ObjectProperty<File> file, Button... items) {
|
private void bindButtonsToContentExistence(FileStorage file, Button... items) {
|
||||||
for (Button item: items) {
|
for (Button item: items) {
|
||||||
item.disableProperty().bind(isNull(file));
|
item.disableProperty().bind(isNull(file.contentProperty()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,17 +417,16 @@ public class SmartCSVController extends FXMLController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void bindCsvFileName() {
|
private void bindCsvFileName() {
|
||||||
csvName.textProperty().bind(selectString(currentCsvFile, "name"));
|
csvName.textProperty().bind(selectString(currentCsvFile.fileProperty(), "name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindConfigFileName() {
|
private void bindConfigFileName() {
|
||||||
configurationName.textProperty().bind(selectString(currentConfigFile, "name"));
|
configurationName.textProperty().bind(selectString(currentConfigFile.fileProperty(), "name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCsvPreferencesFromFile() {
|
private void loadCsvPreferencesFromFile() {
|
||||||
if (PREFERENCES_FILE.exists()) {
|
if (csvPreferenceFile.getFile().exists()) {
|
||||||
useLoadFileService(preferencesLoader, PREFERENCES_FILE,
|
useLoadFileService(csvPreferenceFile, event -> setCsvPreference(csvPreferenceFile.getContent()));
|
||||||
event -> setCsvPreference(preferencesLoader.getCSVpreference()));
|
|
||||||
} else {
|
} else {
|
||||||
setCsvPreference(CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
|
setCsvPreference(CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
|
||||||
}
|
}
|
||||||
@@ -465,37 +435,34 @@ public class SmartCSVController extends FXMLController {
|
|||||||
private void saveCsvPreferences(CsvPreference csvPreference) {
|
private void saveCsvPreferences(CsvPreference csvPreference) {
|
||||||
try {
|
try {
|
||||||
createPreferenceFile();
|
createPreferenceFile();
|
||||||
preferencesWriter.setCsvPreference(csvPreference);
|
csvPreferenceFile.setContent(csvPreference);
|
||||||
useSaveFileService(preferencesWriter, PREFERENCES_FILE);
|
useSaveFileService(csvPreferenceFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPreferenceFile() throws IOException {
|
private void createPreferenceFile() throws IOException {
|
||||||
if (!PREFERENCES_FILE.exists()) {
|
if (!csvPreferenceFile.getFile().exists()) {
|
||||||
createPreferencesFileFolder();
|
createPreferencesFileFolder();
|
||||||
PREFERENCES_FILE.createNewFile();
|
csvPreferenceFile.getFile().createNewFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPreferencesFileFolder() {
|
private void createPreferencesFileFolder() {
|
||||||
if (!PREFERENCES_FILE.getParentFile().exists()) {
|
if (!csvPreferenceFile.getFile().getParentFile().exists()) {
|
||||||
PREFERENCES_FILE.getParentFile().mkdir();
|
csvPreferenceFile.getFile().getParentFile().mkdir();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCsvPreference(CsvPreference csvPreference) {
|
private void setCsvPreference(CsvPreference csvPreference) {
|
||||||
csvLoader.setCsvPreference(csvPreference);
|
|
||||||
csvFileWriter.setCsvPreference(csvPreference);
|
|
||||||
preferencesController.setCsvPreference(csvPreference);
|
preferencesController.setCsvPreference(csvPreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
private File loadFile(FileReader fileReader,
|
private void loadFile(String filterText,
|
||||||
String filterText,
|
|
||||||
String filter,
|
String filter,
|
||||||
String title,
|
String title,
|
||||||
File initChildFile) {
|
FileStorage storageFile) {
|
||||||
final FileChooser fileChooser = new FileChooser();
|
final FileChooser fileChooser = new FileChooser();
|
||||||
|
|
||||||
//Set extension filter
|
//Set extension filter
|
||||||
@@ -503,83 +470,73 @@ public class SmartCSVController extends FXMLController {
|
|||||||
fileChooser.getExtensionFilters().add(extFilter);
|
fileChooser.getExtensionFilters().add(extFilter);
|
||||||
fileChooser.setTitle(title);
|
fileChooser.setTitle(title);
|
||||||
|
|
||||||
if (initChildFile != null) {
|
if (storageFile.getFile() != null) {
|
||||||
fileChooser.setInitialDirectory(initChildFile.getParentFile());
|
fileChooser.setInitialDirectory(storageFile.getFile().getParentFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Show open file dialog
|
//Show open file dialog
|
||||||
File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow());
|
File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow());
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
useLoadFileService(fileReader, file, event -> runLater(() -> {
|
storageFile.setFile(file);
|
||||||
resetContent();
|
useLoadFileService(storageFile, t -> resetContent());
|
||||||
fileChanged.setValue(false);
|
|
||||||
}));
|
|
||||||
return file;
|
|
||||||
} else {
|
|
||||||
return initChildFile;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private File saveFile(FileWriter writer, String filterText, String filter, File initFile) {
|
private File saveFile(String filterText, String filter, FileStorage fileStorage) {
|
||||||
File file = initFile;
|
File file = fileStorage.getFile();
|
||||||
if (model != null) {
|
if (fileStorage.getContent() != null) {
|
||||||
final FileChooser fileChooser = new FileChooser();
|
final FileChooser fileChooser = new FileChooser();
|
||||||
|
|
||||||
//Set extension filter
|
//Set extension filter
|
||||||
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(filterText, filter);
|
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(filterText, filter);
|
||||||
fileChooser.getExtensionFilters().add(extFilter);
|
fileChooser.getExtensionFilters().add(extFilter);
|
||||||
|
|
||||||
if (initFile != null) {
|
if (fileStorage.getFile() != null) {
|
||||||
fileChooser.setInitialDirectory(initFile.getParentFile());
|
fileChooser.setInitialDirectory(fileStorage.getFile().getParentFile());
|
||||||
fileChooser.setInitialFileName(initFile.getName());
|
fileChooser.setInitialFileName(fileStorage.getFile().getName());
|
||||||
}
|
}
|
||||||
fileChooser.setTitle("Save File");
|
fileChooser.setTitle("Save File");
|
||||||
|
|
||||||
//Show open file dialog
|
//Show open file dialog
|
||||||
file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow());
|
file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow());
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
useSaveFileService(writer, file);
|
fileStorage.setFile(file);
|
||||||
|
useSaveFileService(fileStorage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void useLoadFileService(FileReader fileReader, File file, EventHandler<WorkerStateEvent> value) {
|
private void useLoadFileService(FileStorage fileStorage, EventHandler<WorkerStateEvent> onSucceededHandler) {
|
||||||
loadFileService.setFile(file);
|
loadFileService.setFileStorage(fileStorage);
|
||||||
loadFileService.setFileReader(fileReader);
|
|
||||||
loadFileService.restart();
|
loadFileService.restart();
|
||||||
loadFileService.setOnSucceeded(value);
|
loadFileService.setOnSucceeded(onSucceededHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void useSaveFileService(FileWriter writer, File file) {
|
private void useSaveFileService(FileStorage fileStorage) {
|
||||||
saveFileService.setFile(file);
|
saveFileService.setFileStorage(fileStorage);
|
||||||
saveFileService.setWriter(writer);
|
|
||||||
saveFileService.restart();
|
saveFileService.restart();
|
||||||
saveFileService.setOnSucceeded(event -> runLater(() -> {
|
saveFileService.setOnSucceeded(t -> resetContent());
|
||||||
resetContent();
|
|
||||||
fileChanged.setValue(false);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new table view and add the new content
|
* Creates new table view and add the new content
|
||||||
*/
|
*/
|
||||||
private void resetContent() {
|
private void resetContent() {
|
||||||
model = csvLoader.getData();
|
if (currentCsvFile.getContent() != null) {
|
||||||
if (model != null) {
|
currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener);
|
||||||
model.getValidationError().addListener(weakErrorListListener);
|
currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent());
|
||||||
model.setValidationConfiguration(validationLoader.getValidationConfiguration());
|
validationEditorController.setValidationConfiguration(currentConfigFile.getContent());
|
||||||
validationEditorController.setValidationConfiguration(validationLoader.getValidationConfiguration());
|
|
||||||
tableView = new TableView<>();
|
tableView = new TableView<>();
|
||||||
|
|
||||||
bindMenuItemsToTableSelection(deleteRowMenuItem);
|
bindMenuItemsToTableSelection(deleteRowMenuItem);
|
||||||
bindButtonsToTableSelection(deleteRowButton);
|
bindButtonsToTableSelection(deleteRowButton);
|
||||||
|
|
||||||
for (String column : model.getHeader()) {
|
for (String column : currentCsvFile.getContent().getHeader()) {
|
||||||
addColumn(column, tableView);
|
addColumn(column, tableView);
|
||||||
}
|
}
|
||||||
|
|
||||||
tableView.getItems().setAll(model.getRows());
|
tableView.getItems().setAll(currentCsvFile.getContent().getRows());
|
||||||
tableView.setEditable(true);
|
tableView.setEditable(true);
|
||||||
|
|
||||||
setBottomAnchor(tableView, 0.0);
|
setBottomAnchor(tableView, 0.0);
|
||||||
@@ -587,7 +544,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
setLeftAnchor(tableView, 0.0);
|
setLeftAnchor(tableView, 0.0);
|
||||||
setRightAnchor(tableView, 0.0);
|
setRightAnchor(tableView, 0.0);
|
||||||
tableWrapper.getChildren().setAll(tableView);
|
tableWrapper.getChildren().setAll(tableView);
|
||||||
errorSideBar.setModel(model);
|
errorSideBar.setModel(currentCsvFile.getContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,8 +569,8 @@ public class SmartCSVController extends FXMLController {
|
|||||||
event.getTableView().getItems().get(event.getTablePosition().getRow()).
|
event.getTableView().getItems().get(event.getTablePosition().getRow()).
|
||||||
getColumns().get(header).setValue(event.getNewValue());
|
getColumns().get(header).setValue(event.getNewValue());
|
||||||
runLater(() -> {
|
runLater(() -> {
|
||||||
fileChanged.setValue(true);
|
currentCsvFile.setFileChanged(true);
|
||||||
model.revalidate();
|
currentCsvFile.getContent().revalidate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -624,7 +581,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
private ContextMenu contextMenuForColumn(String header) {
|
private ContextMenu contextMenuForColumn(String header) {
|
||||||
ContextMenu contextMenu = new ContextMenu();
|
ContextMenu contextMenu = new ContextMenu();
|
||||||
MenuItem editColumnRulesMenuItem = new MenuItem(resourceBundle.getString("context.menu.edit.column.rules"));
|
MenuItem editColumnRulesMenuItem = new MenuItem(resourceBundle.getString("context.menu.edit.column.rules"));
|
||||||
bindMenuItemsToFileExistence(currentConfigFile, editColumnRulesMenuItem);
|
bindMenuItemsToContentExistence(currentConfigFile, editColumnRulesMenuItem);
|
||||||
editColumnRulesMenuItem.setOnAction(e -> showValidationEditor(header));
|
editColumnRulesMenuItem.setOnAction(e -> showValidationEditor(header));
|
||||||
contextMenu.getItems().addAll(editColumnRulesMenuItem);
|
contextMenu.getItems().addAll(editColumnRulesMenuItem);
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import javafx.scene.text.Text;
|
|||||||
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
||||||
import ninja.javafx.smartcsv.fx.util.ColorConstants;
|
import ninja.javafx.smartcsv.fx.util.ColorConstants;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.controlsfx.control.PopOver;
|
import org.controlsfx.control.PopOver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -54,6 +56,8 @@ import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioM
|
|||||||
*/
|
*/
|
||||||
public class ErrorSideBar extends Region {
|
public class ErrorSideBar extends Region {
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger(ErrorSideBar.class);
|
||||||
|
|
||||||
private static final double WIDTH = 20.0;
|
private static final double WIDTH = 20.0;
|
||||||
private static final int BORDER = 8;
|
private static final int BORDER = 8;
|
||||||
private static final double STATUS_BLOCK_HEIGHT = WIDTH - BORDER;
|
private static final double STATUS_BLOCK_HEIGHT = WIDTH - BORDER;
|
||||||
@@ -133,7 +137,7 @@ public class ErrorSideBar extends Region {
|
|||||||
statusBlock.setStyle("-fx-background-color: " + ERROR_COLOR);
|
statusBlock.setStyle("-fx-background-color: " + ERROR_COLOR);
|
||||||
|
|
||||||
int rows = model.get().getRows().size();
|
int rows = model.get().getRows().size();
|
||||||
double space = heightWithoutStatusBlock() / rows;
|
double space = (double)heightWithoutStatusBlock() / rows;
|
||||||
for (ValidationError error : errorList) {
|
for (ValidationError error : errorList) {
|
||||||
errorMarkerList.add(generateErrorMarker(space, error));
|
errorMarkerList.add(generateErrorMarker(space, error));
|
||||||
}
|
}
|
||||||
@@ -147,6 +151,8 @@ public class ErrorSideBar extends Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Region generateErrorMarker(double space, ValidationError error) {
|
private Region generateErrorMarker(double space, ValidationError error) {
|
||||||
|
logger.info("generate error marker for {} errors in line {}", error.getMessages().size(), error.getLineNumber());
|
||||||
|
logger.info("layout y is set to {}", (space * error.getLineNumber() + STATUS_BLOCK_OFFSET));
|
||||||
Region errorMarker = new Region();
|
Region errorMarker = new Region();
|
||||||
errorMarker.setLayoutY(space * error.getLineNumber() + STATUS_BLOCK_OFFSET);
|
errorMarker.setLayoutY(space * error.getLineNumber() + STATUS_BLOCK_OFFSET);
|
||||||
errorMarker.setPrefSize(WIDTH, 2);
|
errorMarker.setPrefSize(WIDTH, 2);
|
||||||
|
|||||||
@@ -28,9 +28,16 @@ package ninja.javafx.smartcsv.fx.table.model;
|
|||||||
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.concurrent.Service;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationConfiguration;
|
import ninja.javafx.smartcsv.validation.ValidationConfiguration;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
import ninja.javafx.smartcsv.validation.Validator;
|
import ninja.javafx.smartcsv.validation.Validator;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CSVModel is the client representation for the csv filepath.
|
* The CSVModel is the client representation for the csv filepath.
|
||||||
@@ -38,10 +45,13 @@ import ninja.javafx.smartcsv.validation.Validator;
|
|||||||
*/
|
*/
|
||||||
public class CSVModel {
|
public class CSVModel {
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger(CSVModel.class);
|
||||||
|
|
||||||
private Validator validator;
|
private Validator validator;
|
||||||
private ObservableList<CSVRow> rows = FXCollections.observableArrayList();
|
private ObservableList<CSVRow> rows = FXCollections.observableArrayList();
|
||||||
private String[] header;
|
private String[] header;
|
||||||
private ObservableList<ValidationError> validationError = FXCollections.observableArrayList();
|
private ObservableList<ValidationError> validationError = FXCollections.observableArrayList();
|
||||||
|
private RevalidationService revalidationService = new RevalidationService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the validator configuration for the data revalidates
|
* sets the validator configuration for the data revalidates
|
||||||
@@ -100,34 +110,86 @@ public class CSVModel {
|
|||||||
public void revalidate() {
|
public void revalidate() {
|
||||||
validationError.clear();
|
validationError.clear();
|
||||||
|
|
||||||
if (header != null && validator != null) {
|
logger.info("revalidate: hasValidator -> {}", hasValidator());
|
||||||
addValidationError(validator.isHeaderValid(header));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int lineNumber = 0; lineNumber < rows.size(); lineNumber++) {
|
if (!hasValidator()) return;
|
||||||
CSVRow row = rows.get(lineNumber);
|
|
||||||
row.setValidator(validator);
|
revalidationService.setHeader(header);
|
||||||
for (String column: row.getColumns().keySet()) {
|
revalidationService.setRows(rows);
|
||||||
CSVValue value = row.getColumns().get(column).getValue();
|
revalidationService.setValidator(validator);
|
||||||
value.setValidator(validator);
|
revalidationService.setOnSucceeded(t -> validationError.setAll(revalidationService.getValue()));
|
||||||
if (validator != null) {
|
revalidationService.setOnFailed(t -> logger.error("revalidation service failed!"));
|
||||||
ValidationError validationError = validator.isValid(column, value.getValue(), lineNumber);
|
revalidationService.restart();
|
||||||
if (validationError != null) {
|
|
||||||
addValidationError(validationError);
|
|
||||||
value.setValidationError(validationError);
|
|
||||||
} else {
|
|
||||||
value.setValidationError(null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value.setValidationError(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addValidationError(ValidationError validationError) {
|
private boolean hasValidator() {
|
||||||
if (validationError != null) {
|
return validator != null && validator.hasConfig();
|
||||||
this.validationError.add(validationError);
|
}
|
||||||
|
|
||||||
|
public ValidationConfiguration createValidationConfiguration() {
|
||||||
|
ValidationConfiguration newValidationConfiguration = new ValidationConfiguration();
|
||||||
|
newValidationConfiguration.setHeaderNames(this.header);
|
||||||
|
this.validator = new Validator(newValidationConfiguration);
|
||||||
|
this.revalidate();
|
||||||
|
return newValidationConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RevalidationService extends Service<List<ValidationError>> {
|
||||||
|
|
||||||
|
private Validator validator;
|
||||||
|
private List<CSVRow> rows;
|
||||||
|
private String[] header;
|
||||||
|
|
||||||
|
public void setValidator(Validator validator) {
|
||||||
|
this.validator = validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRows(List<CSVRow> rows) {
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(String[] header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Task<List<ValidationError>> createTask() {
|
||||||
|
return new Task<List<ValidationError>>() {
|
||||||
|
@Override
|
||||||
|
protected List<ValidationError> call() throws Exception {
|
||||||
|
List<ValidationError> errors = new ArrayList<>();
|
||||||
|
|
||||||
|
if (header != null) {
|
||||||
|
ValidationError headerError = validator.isHeaderValid(header);
|
||||||
|
if (headerError != null) {
|
||||||
|
logger.info("revalidate: header error found");
|
||||||
|
errors.add(headerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int lineNumber = 0; lineNumber < rows.size(); lineNumber++) {
|
||||||
|
CSVRow row = rows.get(lineNumber);
|
||||||
|
row.setValidator(validator);
|
||||||
|
for (String column: row.getColumns().keySet()) {
|
||||||
|
CSVValue value = row.getColumns().get(column).getValue();
|
||||||
|
value.setValidator(validator);
|
||||||
|
if (validator != null) {
|
||||||
|
ValidationError validationError = validator.isValid(column, value.getValue(), lineNumber);
|
||||||
|
if (validationError != null) {
|
||||||
|
logger.info("revalidate: {} errors found in line {}", validationError.getMessages().size(), lineNumber);
|
||||||
|
errors.add(validationError);
|
||||||
|
value.setValidationError(validationError);
|
||||||
|
} else {
|
||||||
|
value.setValidationError(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value.setValidationError(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ package ninja.javafx.smartcsv.fx.util;
|
|||||||
import javafx.concurrent.Service;
|
import javafx.concurrent.Service;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import ninja.javafx.smartcsv.FileReader;
|
import ninja.javafx.smartcsv.FileReader;
|
||||||
|
import ninja.javafx.smartcsv.files.FileStorage;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -38,14 +39,10 @@ import java.io.File;
|
|||||||
@org.springframework.stereotype.Service
|
@org.springframework.stereotype.Service
|
||||||
public class LoadFileService extends Service {
|
public class LoadFileService extends Service {
|
||||||
|
|
||||||
private File file;
|
private FileStorage file;
|
||||||
private FileReader fileReader;
|
|
||||||
|
|
||||||
public void setFile(File value) {
|
public void setFileStorage(FileStorage file) {
|
||||||
file = value;
|
this.file = file;
|
||||||
}
|
|
||||||
public void setFileReader(FileReader fileReader) {
|
|
||||||
this.fileReader = fileReader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,7 +51,7 @@ public class LoadFileService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
fileReader.read(file);
|
file.load();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import javafx.concurrent.Service;
|
|||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import ninja.javafx.smartcsv.FileWriter;
|
import ninja.javafx.smartcsv.FileWriter;
|
||||||
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
||||||
|
import ninja.javafx.smartcsv.files.FileStorage;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -41,14 +42,9 @@ import static javafx.application.Platform.runLater;
|
|||||||
@org.springframework.stereotype.Service
|
@org.springframework.stereotype.Service
|
||||||
public class SaveFileService extends Service {
|
public class SaveFileService extends Service {
|
||||||
|
|
||||||
private File file;
|
private FileStorage file;
|
||||||
private FileWriter writer;
|
|
||||||
|
|
||||||
public void setWriter(FileWriter writer) {
|
public void setFileStorage(FileStorage value) {
|
||||||
this.writer = writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFile(File value) {
|
|
||||||
file = value;
|
file = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +54,7 @@ public class SaveFileService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
try {
|
try {
|
||||||
writer.write(file);
|
file.save();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ import static ninja.javafx.smartcsv.preferences.QuoteModeHelper.getQuoteMode;
|
|||||||
/**
|
/**
|
||||||
* file reader for the preferences
|
* file reader for the preferences
|
||||||
*/
|
*/
|
||||||
@Service
|
public class PreferencesFileReader implements FileReader<CsvPreference> {
|
||||||
public class PreferencesFileReader implements FileReader {
|
|
||||||
|
|
||||||
private Map config;
|
private Map config;
|
||||||
private CsvPreference csvPreference;
|
private CsvPreference csvPreference;
|
||||||
@@ -74,7 +73,7 @@ public class PreferencesFileReader implements FileReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CsvPreference getCSVpreference() {
|
public CsvPreference getContent() {
|
||||||
return csvPreference;
|
return csvPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,11 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Save preferences to configuration file
|
* Save preferences to configuration file
|
||||||
*/
|
*/
|
||||||
@Service
|
public class PreferencesFileWriter implements FileWriter<CsvPreference> {
|
||||||
public class PreferencesFileWriter implements FileWriter {
|
|
||||||
|
|
||||||
private CsvPreference csvPreference;
|
private CsvPreference csvPreference;
|
||||||
|
|
||||||
public void setCsvPreference(CsvPreference csvPreference) {
|
public void setContent(CsvPreference csvPreference) {
|
||||||
this.csvPreference = csvPreference;
|
this.csvPreference = csvPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,4 +39,8 @@ public class HeaderConfiguration {
|
|||||||
public String[] getNames() {
|
public String[] getNames() {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNames(String[] names) {
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static java.lang.Boolean.FALSE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* validation configuration
|
* validation configuration
|
||||||
*/
|
*/
|
||||||
@@ -50,6 +48,10 @@ public class ValidationConfiguration {
|
|||||||
return headerConfiguration.getNames();
|
return headerConfiguration.getNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHeaderNames(String[] headerNames) {
|
||||||
|
headerConfiguration.setNames(headerNames);
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean getIntegerRuleFor(String column) {
|
public Boolean getIntegerRuleFor(String column) {
|
||||||
return (Boolean)getValue(column, "integer");
|
return (Boolean)getValue(column, "integer");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* This class loads the constraints as json config
|
* This class loads the constraints as json config
|
||||||
*/
|
*/
|
||||||
@Service
|
public class ValidationFileReader implements FileReader<ValidationConfiguration> {
|
||||||
public class ValidationFileReader implements FileReader {
|
|
||||||
|
|
||||||
private ValidationConfiguration config;
|
private ValidationConfiguration config;
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ public class ValidationFileReader implements FileReader {
|
|||||||
config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class);
|
config = new GsonBuilder().create().fromJson(new java.io.FileReader(file), ValidationConfiguration.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationConfiguration getValidationConfiguration() {
|
public ValidationConfiguration getContent() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,11 @@ import java.nio.file.Files;
|
|||||||
/**
|
/**
|
||||||
* file writer for the validation configuration
|
* file writer for the validation configuration
|
||||||
*/
|
*/
|
||||||
@Service
|
public class ValidationFileWriter implements FileWriter<ValidationConfiguration> {
|
||||||
public class ValidationFileWriter implements FileWriter {
|
|
||||||
|
|
||||||
private ValidationConfiguration validationConfiguration;
|
private ValidationConfiguration validationConfiguration;
|
||||||
|
|
||||||
public void setValidationConfiguration(ValidationConfiguration validationConfiguration) {
|
public void setContent(ValidationConfiguration validationConfiguration) {
|
||||||
this.validationConfiguration = validationConfiguration;
|
this.validationConfiguration = validationConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class Validator {
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// oublic methods
|
// public methods
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,7 +78,7 @@ public class Validator {
|
|||||||
*/
|
*/
|
||||||
public ValidationError isValid(String column, String value, Integer lineNumber) {
|
public ValidationError isValid(String column, String value, Integer lineNumber) {
|
||||||
ValidationError result = null;
|
ValidationError result = null;
|
||||||
if (validationConfig != null) {
|
if (hasConfig()) {
|
||||||
|
|
||||||
ValidationError error = ValidationError.withLineNumber(lineNumber);
|
ValidationError error = ValidationError.withLineNumber(lineNumber);
|
||||||
checkBlankOrNull(column, value, error);
|
checkBlankOrNull(column, value, error);
|
||||||
@@ -101,6 +101,9 @@ public class Validator {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasConfig() {
|
||||||
|
return validationConfig != null;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// private methods
|
// private methods
|
||||||
|
|||||||
26
src/main/resources/log4j2.xml
Normal file
26
src/main/resources/log4j2.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="error">
|
||||||
|
|
||||||
|
<Properties>
|
||||||
|
<Property name="filename">smartcsv.log</Property>
|
||||||
|
</Properties>
|
||||||
|
<ThresholdFilter level="trace"/>
|
||||||
|
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
|
||||||
|
<File name="File" fileName="${filename}" bufferedIO="true">
|
||||||
|
<PatternLayout>
|
||||||
|
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
|
||||||
|
</PatternLayout>
|
||||||
|
</File>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="error">
|
||||||
|
<AppenderRef ref="File"/>
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Label text="junit" />
|
<Label text="junit" />
|
||||||
@@ -77,6 +78,8 @@
|
|||||||
<Hyperlink onAction="#openLinkInBrowser" text="https://bitbucket.org/Jerady/fontawesomefx" GridPane.columnIndex="1" GridPane.rowIndex="7" />
|
<Hyperlink onAction="#openLinkInBrowser" text="https://bitbucket.org/Jerady/fontawesomefx" GridPane.columnIndex="1" GridPane.rowIndex="7" />
|
||||||
<Label text="ControlsFX" GridPane.rowIndex="8" />
|
<Label text="ControlsFX" GridPane.rowIndex="8" />
|
||||||
<Hyperlink onAction="#openLinkInBrowser" text="http://fxexperience.com/controlsfx/" GridPane.columnIndex="1" GridPane.rowIndex="8" />
|
<Hyperlink onAction="#openLinkInBrowser" text="http://fxexperience.com/controlsfx/" GridPane.columnIndex="1" GridPane.rowIndex="8" />
|
||||||
|
<Label text="Apache Log4j 2" GridPane.rowIndex="9" />
|
||||||
|
<Hyperlink onAction="#openLinkInBrowser" text="http://logging.apache.org/log4j/2.x/" GridPane.columnIndex="1" GridPane.rowIndex="9" />
|
||||||
|
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
|
|||||||
@@ -15,48 +15,68 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.open-icon {
|
.open-icon {
|
||||||
-glyph-name: "FILE_TEXT_ALT";
|
-glyph-name: "FILE_IMPORT";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-document-icon {
|
||||||
|
-glyph-name: "FILE_DOCUMENT";
|
||||||
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-icon {
|
.config-icon {
|
||||||
-glyph-name: "CHECK";
|
-glyph-name: "CLIPBOARD";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-config-icon {
|
||||||
|
-glyph-name: "STAR";
|
||||||
|
-glyph-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.load-config-icon {
|
||||||
|
-glyph-name: "ARROW_UP_BOLD";
|
||||||
|
-glyph-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-config-icon {
|
||||||
|
-glyph-name: "ARROW_DOWN_BOLD";
|
||||||
|
-glyph-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-icon {
|
.save-icon {
|
||||||
-glyph-name: "FLOPPY_ALT";
|
-glyph-name: "FILE_EXPORT";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exit-icon {
|
.exit-icon {
|
||||||
-glyph-name: "SIGN_OUT";
|
-glyph-name: "EXIT_TO_APP";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-icon {
|
.info-icon {
|
||||||
-glyph-name: "INFO";
|
-glyph-name: "INFORMATION_OUTLINE";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-title-icon {
|
.config-check-icon {
|
||||||
-glyph-name: "EXCLAMATION_TRIANGLE";
|
-glyph-name: "CLIPBOARD_CHECK";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences-icon {
|
.preferences-icon {
|
||||||
-glyph-name: "COG";
|
-glyph-name: "SETTINGS";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.delete-icon {
|
.delete-icon {
|
||||||
-glyph-name: "MINUS";
|
-glyph-name: "TABLE_ROW_REMOVE";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-icon {
|
.add-icon {
|
||||||
-glyph-name: "PLUS";
|
-glyph-name: "TABLE_ROW_PLUS_AFTER";
|
||||||
-glyph-size: 14px;
|
-glyph-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */
|
/* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */
|
||||||
@@ -91,6 +111,13 @@
|
|||||||
-fx-fill: white;
|
-fx-fill: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-item .load-config-icon,
|
||||||
|
.menu-item .save-config-icon,
|
||||||
|
.menu-item .create-config-icon
|
||||||
|
{
|
||||||
|
-fx-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
.tool-bar .save-icon {
|
.tool-bar .save-icon {
|
||||||
-glyph-size: 16px;
|
-glyph-size: 16px;
|
||||||
-fx-fill: white;
|
-fx-fill: white;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import de.jensd.fx.glyphs.GlyphsStack?>
|
<?import de.jensd.fx.glyphs.GlyphsStack?>
|
||||||
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
|
|
||||||
<?import java.net.URL?>
|
<?import java.net.URL?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
@@ -22,6 +21,7 @@
|
|||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
<?import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView?>
|
||||||
<BorderPane fx:id="applicationPane" maxHeight="-Infinity" maxWidth="1000.0" minHeight="700.0" minWidth="-Infinity" prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
|
<BorderPane fx:id="applicationPane" maxHeight="-Infinity" maxWidth="1000.0" minHeight="700.0" minWidth="-Infinity" prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
<top>
|
<top>
|
||||||
<VBox id="background" prefWidth="100.0" BorderPane.alignment="CENTER">
|
<VBox id="background" prefWidth="100.0" BorderPane.alignment="CENTER">
|
||||||
@@ -32,57 +32,72 @@
|
|||||||
<items>
|
<items>
|
||||||
<MenuItem mnemonicParsing="false" onAction="#openCsv" text="%menu.open.csv">
|
<MenuItem mnemonicParsing="false" onAction="#openCsv" text="%menu.open.csv">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="open-icon" />
|
<MaterialDesignIconView styleClass="open-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem fx:id="saveMenuItem" disable="true" mnemonicParsing="false" onAction="#saveCsv" text="%menu.save">
|
<MenuItem fx:id="saveMenuItem" disable="true" mnemonicParsing="false" onAction="#saveCsv" text="%menu.save">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="save-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem fx:id="saveAsMenuItem" disable="true" mnemonicParsing="false" onAction="#saveAsCsv" text="%menu.save.as">
|
<MenuItem fx:id="saveAsMenuItem" disable="true" mnemonicParsing="false" onAction="#saveAsCsv" text="%menu.save.as">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="save-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<SeparatorMenuItem mnemonicParsing="false" />
|
<SeparatorMenuItem mnemonicParsing="false" />
|
||||||
|
<MenuItem fx:id="createConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#createConfig" text="%menu.create.config">
|
||||||
|
<graphic>
|
||||||
|
<GlyphsStack>
|
||||||
|
<children>
|
||||||
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="create-config-icon" />
|
||||||
|
</children>
|
||||||
|
</GlyphsStack>
|
||||||
|
</graphic>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem fx:id="loadConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#openConfig" text="%menu.open.config">
|
<MenuItem fx:id="loadConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#openConfig" text="%menu.open.config">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<GlyphsStack>
|
||||||
|
<children>
|
||||||
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="load-config-icon" />
|
||||||
|
</children>
|
||||||
|
</GlyphsStack>
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem fx:id="saveConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#saveConfig" text="%menu.save.config">
|
<MenuItem fx:id="saveConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#saveConfig" text="%menu.save.config">
|
||||||
<graphic>
|
<graphic>
|
||||||
<GlyphsStack>
|
<GlyphsStack>
|
||||||
<children>
|
<children>
|
||||||
<FontAwesomeIconView style="-fx-opacity: 0.7;" styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="save-config-icon" />
|
||||||
</children>
|
</children>
|
||||||
</GlyphsStack>
|
</GlyphsStack>
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem fx:id="saveAsConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#saveAsConfig" text="%menu.save.as.config">
|
<MenuItem fx:id="saveAsConfigMenuItem" disable="true" mnemonicParsing="false" onAction="#saveAsConfig" text="%menu.save.as.config">
|
||||||
<graphic>
|
<graphic>
|
||||||
<GlyphsStack>
|
<GlyphsStack>
|
||||||
<children>
|
<children>
|
||||||
<FontAwesomeIconView style="-fx-opacity: 0.7;" styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="save-config-icon" />
|
||||||
</children>
|
</children>
|
||||||
</GlyphsStack>
|
</GlyphsStack>
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<SeparatorMenuItem mnemonicParsing="false" />
|
<SeparatorMenuItem mnemonicParsing="false" />
|
||||||
<MenuItem mnemonicParsing="false" onAction="#preferences" text="%menu.preferences">
|
<MenuItem mnemonicParsing="false" onAction="#preferences" text="%menu.preferences">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="preferences-icon" />
|
<MaterialDesignIconView styleClass="preferences-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<SeparatorMenuItem mnemonicParsing="false" />
|
<SeparatorMenuItem mnemonicParsing="false" />
|
||||||
<MenuItem mnemonicParsing="false" onAction="#close" text="%menu.close">
|
<MenuItem mnemonicParsing="false" onAction="#close" text="%menu.close">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="exit-icon" />
|
<MaterialDesignIconView styleClass="exit-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</items>
|
</items>
|
||||||
@@ -91,12 +106,12 @@
|
|||||||
<items>
|
<items>
|
||||||
<MenuItem fx:id="deleteRowMenuItem" disable="true" mnemonicParsing="false" onAction="#deleteRow" text="%menu.delete.row">
|
<MenuItem fx:id="deleteRowMenuItem" disable="true" mnemonicParsing="false" onAction="#deleteRow" text="%menu.delete.row">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="delete-icon" />
|
<MaterialDesignIconView styleClass="delete-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem fx:id="addRowMenuItem" disable="true" mnemonicParsing="false" onAction="#addRow" text="%menu.add.row">
|
<MenuItem fx:id="addRowMenuItem" disable="true" mnemonicParsing="false" onAction="#addRow" text="%menu.add.row">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="add-icon" />
|
<MaterialDesignIconView styleClass="add-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</items>
|
</items>
|
||||||
@@ -105,7 +120,7 @@
|
|||||||
<items>
|
<items>
|
||||||
<MenuItem mnemonicParsing="false" onAction="#about" text="%menu.about">
|
<MenuItem mnemonicParsing="false" onAction="#about" text="%menu.about">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="info-icon" />
|
<MaterialDesignIconView styleClass="info-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</items>
|
</items>
|
||||||
@@ -119,7 +134,7 @@
|
|||||||
<Tooltip text="%menu.open.csv" />
|
<Tooltip text="%menu.open.csv" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="open-icon" />
|
<MaterialDesignIconView styleClass="open-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button fx:id="saveButton" disable="true" mnemonicParsing="false" onAction="#saveCsv">
|
<Button fx:id="saveButton" disable="true" mnemonicParsing="false" onAction="#saveCsv">
|
||||||
@@ -127,7 +142,7 @@
|
|||||||
<Tooltip text="%menu.save" />
|
<Tooltip text="%menu.save" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="save-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button fx:id="saveAsButton" disable="true" mnemonicParsing="false" onAction="#saveAsCsv" styleClass="last" text="...">
|
<Button fx:id="saveAsButton" disable="true" mnemonicParsing="false" onAction="#saveAsCsv" styleClass="last" text="...">
|
||||||
@@ -135,18 +150,36 @@
|
|||||||
<Tooltip text="%menu.save.as" />
|
<Tooltip text="%menu.save.as" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="save-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
</HBox>
|
</HBox>
|
||||||
<Region styleClass="spacer" />
|
<Region styleClass="spacer" />
|
||||||
<HBox styleClass="segmented-button-bar">
|
<HBox styleClass="segmented-button-bar">
|
||||||
|
<Button fx:id="createConfigButton" disable="true" mnemonicParsing="false" onAction="#createConfig">
|
||||||
|
<tooltip>
|
||||||
|
<Tooltip text="%menu.create.config" />
|
||||||
|
</tooltip>
|
||||||
|
<graphic>
|
||||||
|
<GlyphsStack>
|
||||||
|
<children>
|
||||||
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="create-config-icon" />
|
||||||
|
</children>
|
||||||
|
</GlyphsStack>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
<Button fx:id="loadConfigButton" disable="true" mnemonicParsing="false" onAction="#openConfig">
|
<Button fx:id="loadConfigButton" disable="true" mnemonicParsing="false" onAction="#openConfig">
|
||||||
<tooltip>
|
<tooltip>
|
||||||
<Tooltip text="%menu.open.config" />
|
<Tooltip text="%menu.open.config" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<GlyphsStack>
|
||||||
|
<children>
|
||||||
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="load-config-icon" />
|
||||||
|
</children>
|
||||||
|
</GlyphsStack>
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button fx:id="saveConfigButton" disable="true" mnemonicParsing="false" onAction="#saveConfig">
|
<Button fx:id="saveConfigButton" disable="true" mnemonicParsing="false" onAction="#saveConfig">
|
||||||
@@ -156,8 +189,8 @@
|
|||||||
<graphic>
|
<graphic>
|
||||||
<GlyphsStack>
|
<GlyphsStack>
|
||||||
<children>
|
<children>
|
||||||
<FontAwesomeIconView style="-fx-opacity: 0.7;" styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="save-config-icon" />
|
||||||
</children>
|
</children>
|
||||||
</GlyphsStack>
|
</GlyphsStack>
|
||||||
</graphic>
|
</graphic>
|
||||||
@@ -169,8 +202,8 @@
|
|||||||
<graphic>
|
<graphic>
|
||||||
<GlyphsStack>
|
<GlyphsStack>
|
||||||
<children>
|
<children>
|
||||||
<FontAwesomeIconView style="-fx-opacity: 0.7;" styleClass="save-icon" />
|
<MaterialDesignIconView styleClass="config-icon" />
|
||||||
<FontAwesomeIconView styleClass="config-icon" />
|
<MaterialDesignIconView style="-fx-opacity: 0.7;" styleClass="save-config-icon" />
|
||||||
</children>
|
</children>
|
||||||
</GlyphsStack>
|
</GlyphsStack>
|
||||||
|
|
||||||
@@ -184,7 +217,7 @@
|
|||||||
<Tooltip text="%menu.delete.row" />
|
<Tooltip text="%menu.delete.row" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="delete-icon" />
|
<MaterialDesignIconView styleClass="delete-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button fx:id="addRowButton" disable="true" mnemonicParsing="false" onAction="#addRow" styleClass="last">
|
<Button fx:id="addRowButton" disable="true" mnemonicParsing="false" onAction="#addRow" styleClass="last">
|
||||||
@@ -192,7 +225,7 @@
|
|||||||
<Tooltip text="%menu.add.row" />
|
<Tooltip text="%menu.add.row" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="add-icon" />
|
<MaterialDesignIconView styleClass="add-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
</HBox>
|
</HBox>
|
||||||
@@ -203,7 +236,7 @@
|
|||||||
<Tooltip text="%menu.preferences" />
|
<Tooltip text="%menu.preferences" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="preferences-icon" />
|
<MaterialDesignIconView styleClass="preferences-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button mnemonicParsing="false" onAction="#close" styleClass="last">
|
<Button mnemonicParsing="false" onAction="#close" styleClass="last">
|
||||||
@@ -211,7 +244,7 @@
|
|||||||
<Tooltip text="%menu.close" />
|
<Tooltip text="%menu.close" />
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesomeIconView styleClass="exit-icon" />
|
<MaterialDesignIconView styleClass="exit-icon" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
</HBox>
|
</HBox>
|
||||||
@@ -248,10 +281,10 @@
|
|||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<FontAwesomeIconView styleClass="open-icon" GridPane.hgrow="NEVER" />
|
<MaterialDesignIconView styleClass="file-document-icon" GridPane.hgrow="NEVER" />
|
||||||
<Label text="%stateline.csv" GridPane.columnIndex="1" GridPane.hgrow="NEVER" />
|
<Label text="%stateline.csv" GridPane.columnIndex="1" GridPane.hgrow="NEVER" />
|
||||||
<Label fx:id="csvName" GridPane.columnIndex="2" GridPane.hgrow="ALWAYS" />
|
<Label fx:id="csvName" GridPane.columnIndex="2" GridPane.hgrow="ALWAYS" />
|
||||||
<FontAwesomeIconView styleClass="open-icon" GridPane.columnIndex="3" GridPane.hgrow="NEVER" />
|
<MaterialDesignIconView styleClass="config-check-icon" GridPane.columnIndex="3" GridPane.hgrow="NEVER" />
|
||||||
<Label text="%stateline.configuration" GridPane.columnIndex="4" GridPane.hgrow="NEVER" />
|
<Label text="%stateline.configuration" GridPane.columnIndex="4" GridPane.hgrow="NEVER" />
|
||||||
<Label fx:id="configurationName" GridPane.columnIndex="5" GridPane.hgrow="ALWAYS" />
|
<Label fx:id="configurationName" GridPane.columnIndex="5" GridPane.hgrow="ALWAYS" />
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
menu.open.csv = Open CSV File
|
menu.open.csv = Open CSV File
|
||||||
menu.open.config = Open Validation Config
|
menu.open.config = Open Validation Config
|
||||||
|
menu.create.config = Create Validation Config
|
||||||
menu.save = Save
|
menu.save = Save
|
||||||
menu.save.as = Save As ...
|
menu.save.as = Save As ...
|
||||||
menu.save.config = Save Validation Config
|
menu.save.config = Save Validation Config
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
menu.open.csv = CSV Datei \u00f6ffnen
|
menu.open.csv = CSV Datei \u00f6ffnen
|
||||||
menu.open.config = Pr\u00fcfkonfiguration \u00f6ffnen
|
menu.open.config = Pr\u00fcfkonfiguration \u00f6ffnen
|
||||||
|
menu.create.config = Pr\u00fcfkonfiguration erzeugen
|
||||||
menu.save = Speichern
|
menu.save = Speichern
|
||||||
menu.save.as = Speichern als ...
|
menu.save.as = Speichern als ...
|
||||||
menu.save.config = Pr\u00fcfkonfiguration speichern
|
menu.save.config = Pr\u00fcfkonfiguration speichern
|
||||||
|
|||||||
Reference in New Issue
Block a user