mirror of
https://github.com/frosch95/SmartCSV.fx.git
synced 2026-04-11 13:38:23 +02:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6742a4e30 | |||
| 7472c66823 | |||
| c7873ef0ba | |||
| b79a20201e | |||
|
|
3ebf78805c |
@@ -14,7 +14,7 @@ even in a "normal" CSV editor. So I decided to write this simple JavaFX applicat
|
||||
|
||||
[Wiki & Documentation](https://github.com/frosch95/SmartCSV.fx/wiki)
|
||||
|
||||
binary distribution of the [latest release (0.5)](https://drive.google.com/file/d/0BwY9gBUvn5qmejllOTRwbEJYdDA/view?usp=sharing)
|
||||
binary distribution of the [latest release (0.6)](https://github.com/frosch95/SmartCSV.fx/releases/download/0.6/SmartCSV.fx-0.6-SNAPSHOT.zip)
|
||||
|
||||
##Talks
|
||||
[Introduction](http://javafx.ninja/talks/introduction/)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
group 'ninja.javafx'
|
||||
version '0.6-SNAPSHOT'
|
||||
version '0.7-SNAPSHOT'
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'groovy'
|
||||
|
||||
71
src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java
Normal file
71
src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package ninja.javafx.smartcsv.export;
|
||||
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage;
|
||||
|
||||
/**
|
||||
* this class exports the error messages into a log file
|
||||
*/
|
||||
@org.springframework.stereotype.Service
|
||||
public class ErrorExport extends Service {
|
||||
|
||||
private CSVModel model;
|
||||
private File file;
|
||||
private ResourceBundle resourceBundle;
|
||||
private String csvFilename;
|
||||
|
||||
public void setCsvFilename(String csvFilename) {
|
||||
this.csvFilename = csvFilename;
|
||||
}
|
||||
|
||||
public void setResourceBundle(ResourceBundle resourceBundle) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
public void setModel(CSVModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task createTask() {
|
||||
return new Task() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
try {
|
||||
StringWriter log = new StringWriter();
|
||||
log.append(
|
||||
format(resourceBundle.getString("log.header.message"),
|
||||
csvFilename,
|
||||
Integer.toString(model.getValidationError().size()))).append("\n\n");
|
||||
for (ValidationError error:model.getValidationError()) {
|
||||
log.append(
|
||||
format(resourceBundle.getString("log.message"),
|
||||
error.getLineNumber().toString(),
|
||||
error.getColumn(),
|
||||
getI18nValidatioMessage(resourceBundle, error))).append("\n");
|
||||
}
|
||||
Files.write(file.toPath(), log.toString().getBytes());
|
||||
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
package ninja.javafx.smartcsv.fx;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.WeakListChangeListener;
|
||||
import javafx.concurrent.WorkerStateEvent;
|
||||
@@ -39,6 +40,7 @@ import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
||||
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
||||
import ninja.javafx.smartcsv.export.ErrorExport;
|
||||
import ninja.javafx.smartcsv.files.FileStorage;
|
||||
import ninja.javafx.smartcsv.fx.about.AboutController;
|
||||
import ninja.javafx.smartcsv.fx.list.ErrorSideBar;
|
||||
@@ -95,6 +97,9 @@ public class SmartCSVController extends FXMLController {
|
||||
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";
|
||||
public static final String EXPORT_LOG_FILTER_TEXT = "Error log files (*.log)";
|
||||
public static final String EXPORT_LOG_FILTER_EXTENSION = "*.log";
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// injections
|
||||
@@ -115,6 +120,9 @@ public class SmartCSVController extends FXMLController {
|
||||
@Autowired
|
||||
private SaveFileService saveFileService;
|
||||
|
||||
@Autowired
|
||||
private ErrorExport errorExport;
|
||||
|
||||
@FXML
|
||||
private BorderPane applicationPane;
|
||||
|
||||
@@ -157,6 +165,9 @@ public class SmartCSVController extends FXMLController {
|
||||
@FXML
|
||||
private MenuItem gotoLineMenuItem;
|
||||
|
||||
@FXML
|
||||
private MenuItem exportMenuItem;
|
||||
|
||||
@FXML
|
||||
private Button saveButton;
|
||||
|
||||
@@ -181,6 +192,9 @@ public class SmartCSVController extends FXMLController {
|
||||
@FXML
|
||||
private Button addRowButton;
|
||||
|
||||
@FXML
|
||||
private Button exportButton;
|
||||
|
||||
@FXML
|
||||
private Label currentLineNumber;
|
||||
|
||||
@@ -370,6 +384,26 @@ public class SmartCSVController extends FXMLController {
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canExit() {
|
||||
boolean canExit = true;
|
||||
if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) {
|
||||
@@ -552,6 +586,8 @@ public class SmartCSVController extends FXMLController {
|
||||
* Creates new table view and add the new content
|
||||
*/
|
||||
private void resetContent() {
|
||||
resetExportButtons();
|
||||
|
||||
if (currentCsvFile.getContent() != null) {
|
||||
currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener);
|
||||
currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent());
|
||||
@@ -575,9 +611,22 @@ public class SmartCSVController extends FXMLController {
|
||||
setRightAnchor(tableView, 0.0);
|
||||
tableWrapper.getChildren().setAll(tableView);
|
||||
errorSideBar.setModel(currentCsvFile.getContent());
|
||||
binExportButtons();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a column with the given name to the tableview
|
||||
* @param header name of the column header
|
||||
|
||||
@@ -48,7 +48,7 @@ import java.util.ResourceBundle;
|
||||
import static javafx.geometry.Pos.CENTER;
|
||||
import static ninja.javafx.smartcsv.fx.util.ColorConstants.ERROR_COLOR;
|
||||
import static ninja.javafx.smartcsv.fx.util.ColorConstants.OK_COLOR;
|
||||
import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage;
|
||||
import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessageWithColumn;
|
||||
|
||||
/**
|
||||
* clickable side bar with error markers
|
||||
@@ -158,7 +158,7 @@ public class ErrorSideBar extends Region {
|
||||
errorMarker.setStyle("-fx-background-color: " + ERROR_COLOR);
|
||||
errorMarker.setOnMouseClicked(event -> selectedValidationError.setValue(error));
|
||||
errorMarker.setOnMouseEntered(event -> {
|
||||
popOver.setContentNode(popupContent(getI18nValidatioMessage(resourceBundle, error)));
|
||||
popOver.setContentNode(popupContent(getI18nValidatioMessageWithColumn(resourceBundle, error)));
|
||||
popOver.show(errorMarker, -16);
|
||||
});
|
||||
return errorMarker;
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.apache.logging.log4j.Logger;
|
||||
* The CSVModel is the client representation for the csv filepath.
|
||||
* It holds the data in rows, stores the header and manages the validator.
|
||||
*/
|
||||
public final class CSVModel {
|
||||
public final class CSVModel implements ColumnValueProvider {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(CSVModel.class);
|
||||
|
||||
@@ -55,7 +55,7 @@ public final class CSVModel {
|
||||
* @param validationConfiguration the validator configuration for this data
|
||||
*/
|
||||
public void setValidationConfiguration(ValidationConfiguration validationConfiguration) {
|
||||
this.validator = new Validator(validationConfiguration);
|
||||
this.validator = new Validator(validationConfiguration, this);
|
||||
revalidate();
|
||||
}
|
||||
|
||||
@@ -145,11 +145,19 @@ public final class CSVModel {
|
||||
public ValidationConfiguration createValidationConfiguration() {
|
||||
ValidationConfiguration newValidationConfiguration = new ValidationConfiguration();
|
||||
newValidationConfiguration.setHeaderNames(this.header);
|
||||
this.validator = new Validator(newValidationConfiguration);
|
||||
this.validator = new Validator(newValidationConfiguration, this);
|
||||
this.revalidate();
|
||||
return newValidationConfiguration;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getValue(int row, String column) {
|
||||
return rows.get(row).getColumns().get(column).getValue().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfRows() {
|
||||
return rows.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package ninja.javafx.smartcsv.fx.table.model;
|
||||
|
||||
/**
|
||||
* interface for easier access to values in a column
|
||||
*/
|
||||
public interface ColumnValueProvider {
|
||||
|
||||
String getValue(int row, String column);
|
||||
int getNumberOfRows();
|
||||
|
||||
}
|
||||
@@ -54,11 +54,20 @@ public class I18nValidationUtil {
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getI18nValidatioMessageWithColumn(ResourceBundle resourceBundle, ValidationError error) {
|
||||
return getI18nValidatioMessage(resourceBundle, error, resourceBundle.getString("column") + " " + error.getColumn() + " : ");
|
||||
}
|
||||
|
||||
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) {
|
||||
return getI18nValidatioMessage(resourceBundle, error, "");
|
||||
}
|
||||
|
||||
private static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error, String prefix) {
|
||||
|
||||
List<ValidationMessage> validationMessages = error.getMessages();
|
||||
StringWriter message = new StringWriter();
|
||||
for (ValidationMessage validationMessage: validationMessages) {
|
||||
message.append(prefix);
|
||||
if (resourceBundle.containsKey(validationMessage.getKey())) {
|
||||
String resourceText = resourceBundle.getString(validationMessage.getKey());
|
||||
if (validationMessage.getParameters().length > 0) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.matchRegexp;
|
||||
/**
|
||||
* Checks if the value is alpha numeric
|
||||
*/
|
||||
public class AlphaNumericValidation implements Validation {
|
||||
public class AlphaNumericValidation extends EmptyValueIsValid {
|
||||
@Override
|
||||
public void check(int row, String value, ValidationError error) {
|
||||
if (!matchRegexp(value, "[0-9a-zA-Z]*")) {
|
||||
@@ -42,4 +42,6 @@ public class AlphaNumericValidation implements Validation {
|
||||
public Type getType() {
|
||||
return Type.ALPHANUMERIC;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.isDate;
|
||||
/**
|
||||
* Checks if the date has the right format
|
||||
*/
|
||||
public class DateValidation implements Validation {
|
||||
public class DateValidation extends EmptyValueIsValid {
|
||||
|
||||
private String dateformat;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.isDouble;
|
||||
/**
|
||||
* Checks if the value is a double
|
||||
*/
|
||||
public class DoubleValidation implements Validation {
|
||||
public class DoubleValidation extends EmptyValueIsValid {
|
||||
|
||||
@Override
|
||||
public void check(int row, String value, ValidationError error) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package ninja.javafx.smartcsv.validation;
|
||||
|
||||
/**
|
||||
* validations based on this are not validated when the value is null or empty
|
||||
*/
|
||||
public abstract class EmptyValueIsValid implements Validation {
|
||||
|
||||
@Override
|
||||
public boolean canBeChecked(String value) {
|
||||
return value != null && !value.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import org.codehaus.groovy.control.CompilationFailedException;
|
||||
/**
|
||||
* Executes the given groovy as check
|
||||
*/
|
||||
public class GroovyValidation implements Validation {
|
||||
public class GroovyValidation extends EmptyValueIsValid {
|
||||
|
||||
private String groovyScript;
|
||||
private GroovyShell shell = new GroovyShell();
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.isInt;
|
||||
/**
|
||||
* Checks if the value is an integer
|
||||
*/
|
||||
public class IntegerValidation implements Validation {
|
||||
public class IntegerValidation extends EmptyValueIsValid {
|
||||
|
||||
@Override
|
||||
public void check(int row, String value, ValidationError error) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.maxLength;
|
||||
/**
|
||||
* Checks if the value is shorter or exactly as long as the given max length
|
||||
*/
|
||||
public class MaxLengthValidation implements Validation {
|
||||
public class MaxLengthValidation extends EmptyValueIsValid {
|
||||
|
||||
private int maxLength;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.minLength;
|
||||
/**
|
||||
* Checks if the value is at minimum long as the given min length
|
||||
*/
|
||||
public class MinLengthValidation implements Validation {
|
||||
public class MinLengthValidation extends EmptyValueIsValid {
|
||||
|
||||
private int minLength;
|
||||
|
||||
|
||||
@@ -43,4 +43,9 @@ public class NotEmptyValidation implements Validation {
|
||||
public Type getType() {
|
||||
return Type.NOT_EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeChecked(String value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import static org.apache.commons.validator.GenericValidator.matchRegexp;
|
||||
/**
|
||||
* Checks the value against the given reg exp
|
||||
*/
|
||||
public class RegExpValidation implements Validation {
|
||||
public class RegExpValidation extends EmptyValueIsValid {
|
||||
|
||||
private String regexp;
|
||||
|
||||
|
||||
@@ -25,26 +25,50 @@
|
||||
*/
|
||||
package ninja.javafx.smartcsv.validation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import ninja.javafx.smartcsv.fx.table.model.ColumnValueProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.sort;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
/**
|
||||
* Checks if the value is unique in the column
|
||||
*/
|
||||
public class UniqueValidation implements Validation {
|
||||
public class UniqueValidation extends EmptyValueIsValid {
|
||||
|
||||
private HashMap<String, Integer> columnValueMap = new HashMap<>();
|
||||
private ColumnValueProvider columnValueProvider;
|
||||
private String column;
|
||||
|
||||
public UniqueValidation(ColumnValueProvider columnValueProvider, String column) {
|
||||
this.columnValueProvider = columnValueProvider;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(int row, String value, ValidationError error) {
|
||||
Integer valueInLineNumber = columnValueMap.get(value);
|
||||
if (valueInLineNumber != null) {
|
||||
if (!valueInLineNumber.equals(row)) {
|
||||
valueInLineNumber += 1; // show not 0 based line numbers to user
|
||||
error.add("validation.message.uniqueness", value, valueInLineNumber.toString());
|
||||
|
||||
List<Integer> lineNumbers = new ArrayList<>();
|
||||
|
||||
int numberOfRows = columnValueProvider.getNumberOfRows();
|
||||
for (int currentRowOfIteration = 0; currentRowOfIteration < numberOfRows; currentRowOfIteration++) {
|
||||
String storedValue = columnValueProvider.getValue(currentRowOfIteration, column);
|
||||
|
||||
if (value.equals(storedValue) && currentRowOfIteration != row) {
|
||||
lineNumbers.add(currentRowOfIteration + 1); // show not 0 based line numbers to user
|
||||
}
|
||||
} else {
|
||||
columnValueMap.put(value, row);
|
||||
}
|
||||
|
||||
if (!lineNumbers.isEmpty()) {
|
||||
if (lineNumbers.size() > 1) {
|
||||
sort(lineNumbers);
|
||||
error.add("validation.message.uniqueness.multiple", value, lineNumbers.stream().map(Object::toString).collect(joining(", ")));
|
||||
} else {
|
||||
error.add("validation.message.uniqueness.single", value, lineNumbers.get(0).toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,4 +33,5 @@ public interface Validation {
|
||||
enum Type { NOT_EMPTY, UNIQUE, DOUBLE, INTEGER, MIN_LENGTH, MAX_LENGTH, DATE, ALPHANUMERIC, REGEXP, VALUE_OF, GROOVY }
|
||||
void check(int row, String value, ValidationError error);
|
||||
Type getType();
|
||||
boolean canBeChecked(String value);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public class ValidationError {
|
||||
|
||||
private List<ValidationMessage> messages = new ArrayList<>();
|
||||
private Integer lineNumber;
|
||||
private String column = "";
|
||||
|
||||
private ValidationError(Integer lineNumber) {
|
||||
this.lineNumber = lineNumber;
|
||||
@@ -51,10 +52,19 @@ public class ValidationError {
|
||||
return new ValidationError(-1);
|
||||
}
|
||||
|
||||
public ValidationError column(String column) {
|
||||
this.column = column;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public String getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
package ninja.javafx.smartcsv.validation;
|
||||
|
||||
import ninja.javafx.smartcsv.fx.table.model.ColumnValueProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -41,6 +43,7 @@ public class Validator {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private ValidationConfiguration validationConfig;
|
||||
private ColumnValueProvider columnValueProvider;
|
||||
private Map<String, Map<Validation.Type, Validation>> columnValidationMap = new HashMap<>();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -52,8 +55,9 @@ public class Validator {
|
||||
*
|
||||
* @param validationConfig
|
||||
*/
|
||||
public Validator(ValidationConfiguration validationConfig) {
|
||||
public Validator(ValidationConfiguration validationConfig, ColumnValueProvider columnValueProvider) {
|
||||
this.validationConfig = validationConfig;
|
||||
this.columnValueProvider = columnValueProvider;
|
||||
initColumnValidations();
|
||||
}
|
||||
|
||||
@@ -82,17 +86,12 @@ public class Validator {
|
||||
public ValidationError isValid(Integer row, String column, String value) {
|
||||
ValidationError result = null;
|
||||
if (hasConfig()) {
|
||||
ValidationError error = ValidationError.withLineNumber(row);
|
||||
ValidationError error = ValidationError.withLineNumber(row).column(column);
|
||||
Map<Validation.Type, Validation> validationMap = columnValidationMap.get(column);
|
||||
if (validationMap != null) {
|
||||
for (Validation validation: validationMap.values()) {
|
||||
|
||||
if (validation.getType() == Validation.Type.NOT_EMPTY) {
|
||||
if (validation.canBeChecked(value)) {
|
||||
validation.check(row, value, error);
|
||||
} else {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
validation.check(row, value, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +164,7 @@ public class Validator {
|
||||
|
||||
Boolean uniqueRule = validationConfig.getUniqueRuleFor(column);
|
||||
if (uniqueRule != null && uniqueRule) {
|
||||
add(column, new UniqueValidation());
|
||||
add(column, new UniqueValidation(columnValueProvider, column));
|
||||
}
|
||||
|
||||
String dateRule = validationConfig.getDateRuleFor(column);
|
||||
|
||||
@@ -32,7 +32,7 @@ import static java.util.stream.Collectors.joining;
|
||||
/**
|
||||
* Checks if the value is part of a list of values
|
||||
*/
|
||||
public class ValueOfValidation implements Validation {
|
||||
public class ValueOfValidation extends EmptyValueIsValid {
|
||||
|
||||
private List<String> values;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
application.name = SmartCSV.fx
|
||||
application.version = 0.6
|
||||
application.version = 0.7
|
||||
|
||||
# fxml views
|
||||
fxml.smartcvs.view = /ninja/javafx/smartcsv/fx/smartcsv.fxml
|
||||
|
||||
@@ -82,9 +82,14 @@
|
||||
.goto-icon {
|
||||
-glyph-name: "SUBDIRECTORY_ARROW_RIGHT";
|
||||
-glyph-size: 16px;
|
||||
|
||||
}
|
||||
|
||||
.export-icon {
|
||||
-glyph-name: "BUG";
|
||||
-glyph-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */
|
||||
|
||||
#background {
|
||||
@@ -149,6 +154,11 @@
|
||||
-fx-fill: white;
|
||||
}
|
||||
|
||||
.tool-bar .export-icon {
|
||||
-glyph-size: 16px;
|
||||
-fx-fill: white;
|
||||
}
|
||||
|
||||
.segmented-button-bar .button {
|
||||
-fx-background-color:
|
||||
-darkest-black,
|
||||
|
||||
@@ -78,6 +78,11 @@
|
||||
<MaterialDesignIconView styleClass="preferences-icon" />
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
<MenuItem fx:id="exportMenuItem" disable="true" mnemonicParsing="false" onAction="#export" text="%menu.export">
|
||||
<graphic>
|
||||
<MaterialDesignIconView styleClass="export-icon" />
|
||||
</graphic>
|
||||
</MenuItem>
|
||||
<SeparatorMenuItem mnemonicParsing="false" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#close" text="%menu.close">
|
||||
<graphic>
|
||||
@@ -229,6 +234,14 @@
|
||||
<MaterialDesignIconView styleClass="preferences-icon" />
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="exportButton" disable="true" mnemonicParsing="false" onAction="#export">
|
||||
<tooltip>
|
||||
<Tooltip text="%menu.export" />
|
||||
</tooltip>
|
||||
<graphic>
|
||||
<MaterialDesignIconView styleClass="export-icon" />
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button mnemonicParsing="false" onAction="#close" styleClass="last">
|
||||
<tooltip>
|
||||
<Tooltip text="%menu.close" />
|
||||
|
||||
@@ -14,6 +14,7 @@ menu.preferences = Preferences
|
||||
menu.delete.row = Delete row
|
||||
menu.add.row = Add row
|
||||
menu.goto.line = Goto line
|
||||
menu.export = Export error log
|
||||
|
||||
title.validation.errors = Validation Errors:
|
||||
|
||||
@@ -52,7 +53,8 @@ validation.message.min.length = has not min length of {0}
|
||||
validation.message.max.length = has not max length of {0}
|
||||
validation.message.date.format = is not a date of format {0}
|
||||
validation.message.regexp = does not match {0}
|
||||
validation.message.uniqueness = value {0} is not unique (found in line {1})
|
||||
validation.message.uniqueness.multiple = value {0} is not unique (found in rows {1})
|
||||
validation.message.uniqueness.single = value {0} is not unique (found in row {1})
|
||||
|
||||
validation.message.header.length = number of headers is not correct! there are {0} but there should be {1}
|
||||
validation.message.header.match = header number {0} does not match "{1}" should be "{2}"
|
||||
@@ -77,4 +79,9 @@ dialog.validation.rules.title = Validation rules
|
||||
dialog.validation.rules.header = Validation rules of column "{0}"
|
||||
context.menu.edit.column.rules = Edit rules
|
||||
|
||||
lineNumber = Selected line:
|
||||
lineNumber = Selected line:
|
||||
|
||||
log.header.message = {0} has {1} errors
|
||||
log.message = row {0} column {1} : {2}
|
||||
|
||||
column = column
|
||||
@@ -23,6 +23,7 @@ menu.preferences = Einstellungen
|
||||
menu.delete.row = Zeile l\u00f6schen
|
||||
menu.add.row = Zeile hinzuf\u00fcgen
|
||||
menu.goto.line = Springe zur Zeile
|
||||
menu.export = Export Fehlerdatei
|
||||
|
||||
title.validation.errors = Fehler in der Datei:
|
||||
|
||||
@@ -61,7 +62,8 @@ validation.message.min.length = Hat nicht die minimale L\u00e4nge von {0}
|
||||
validation.message.max.length = Hat nicht die maximale L\u00e4nge von {0}
|
||||
validation.message.date.format = Das Datumsformat entspricht nicht {0}
|
||||
validation.message.regexp = entspricht nicht dem regul\u00e4ren Ausdruck {0}
|
||||
validation.message.uniqueness = Wert {0} ist nicht einmalig (gefunden in Zeile {1})
|
||||
validation.message.uniqueness.multiple = Wert {0} ist nicht einmalig (gefunden in den Zeilen {1})
|
||||
validation.message.uniqueness.single = Wert {0} ist nicht einmalig (gefunden in Zeile {1})
|
||||
|
||||
validation.message.header.length = Anzahl der \u00dcberschriften ist nicht korrekt! Es sind {0} aber es sollten {1} sein
|
||||
validation.message.header.match = \u00dcberschrift in Spalte {0} stimmt nicht. "{1}" sollte "{3}" sein
|
||||
@@ -87,4 +89,9 @@ dialog.validation.rules.header = Pr\u00fcfregeln f\u00fcr die Spalte "{0}"
|
||||
|
||||
context.menu.edit.column.rules = Pr\u00fcfregeln bearbeiten
|
||||
|
||||
lineNumber = Ausgew\u00e4hlte Zeile:
|
||||
lineNumber = Ausgew\u00e4hlte Zeile:
|
||||
|
||||
log.header.message = {0} hat {1} Fehler
|
||||
log.message = Zeile {0} Spalte {1} : {2}
|
||||
|
||||
column = Spalte
|
||||
Reference in New Issue
Block a user