diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6863e32cdf7..ca7162119e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We made the font size in the entry editor and group panel customizable by "Menu and label font size". [#3034](https://github.com/JabRef/jabref/issues/3034)
- If fetched article is already in database, then the entry merge dialog is shown.
- An error message is now displayed if you try to create a group containing the keyword separator or if there is already a group with the same name. [#3075](https://github.com/JabRef/jabref/issues/3075) and [#1495](https://github.com/JabRef/jabref/issues/1495)
+- Integrity warnings are now directly displayed in the entry editor.
### Fixed
@@ -26,6 +27,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We fixed an issue where DEL, Ctrl+C, Ctrl+V and Ctrl+A in the search field triggered corresponding actions in the main table [#3067](https://github.com/JabRef/jabref/issues/3067)
- We fixed an issue where JabRef freezed when editing an assigned file in the `General`-Tab [#2930, comment](https://github.com/JabRef/jabref/issues/2930#issuecomment-311050976)
- We fixed an issue where a file could not be assigned to an existing entry via the entry context menu action `Attach file` [#3080](https://github.com/JabRef/jabref/issues/3080)
+
### Removed
diff --git a/build.gradle b/build.gradle
index f3f7b8c4126..96268da5bbf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -103,6 +103,7 @@ dependencies {
compile 'de.codecentric.centerdevice:javafxsvg:1.2.1'
compile 'org.controlsfx:controlsfx:8.40.13'
compile 'org.fxmisc.easybind:easybind:1.0.3'
+ compile 'de.saxsys:mvvmfx-validation:1.6.0'
compile 'org.fxmisc.flowless:flowless:0.5.2'
compile 'de.jensd:fontawesomefx-materialdesignfont:1.7.22-4'
diff --git a/external-libraries.txt b/external-libraries.txt
index 02e257a40bc..6a2a5d15ba3 100644
--- a/external-libraries.txt
+++ b/external-libraries.txt
@@ -224,6 +224,11 @@ Project: javafxsvg
URL: https://github.com/codecentric/javafxsvg
License: BSD 3-Clause
+Id: de.saxsys:mvvmfx
+Project: mvvm(fx)
+URL: https://github.com/sialcasa/mvvmFX
+License: Apache-2.0
+
Id: com.github.tomtung
Project: latex2unicode
URL: https://github.com/tomtung/latex2unicode
diff --git a/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java
index 7f458cc5310..f249aa1c37a 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java
@@ -13,8 +13,14 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.undo.UndoableFieldChange;
import org.jabref.gui.util.BindingsHelper;
+import org.jabref.logic.integrity.FieldCheckers;
+import org.jabref.logic.integrity.ValueChecker;
import org.jabref.model.entry.BibEntry;
+import de.saxsys.mvvmfx.utils.validation.CompositeValidator;
+import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator;
+import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
+import de.saxsys.mvvmfx.utils.validation.Validator;
import org.controlsfx.control.textfield.AutoCompletionBinding;
public class AbstractEditorViewModel extends AbstractViewModel {
@@ -22,11 +28,23 @@ public class AbstractEditorViewModel extends AbstractViewModel {
protected StringProperty text = new SimpleStringProperty("");
protected BibEntry entry;
private final AutoCompleteSuggestionProvider> suggestionProvider;
+ private final CompositeValidator fieldValidator;
private ObjectBinding fieldBinding;
- public AbstractEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
+ public AbstractEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
this.fieldName = fieldName;
this.suggestionProvider = suggestionProvider;
+
+ this.fieldValidator = new CompositeValidator();
+ for (ValueChecker checker : fieldCheckers.getForField(fieldName)) {
+ FunctionBasedValidator validator = new FunctionBasedValidator<>(text, value ->
+ checker.checkValue(value).map(ValidationMessage::warning).orElse(null));
+ fieldValidator.addValidators(validator);
+ }
+ }
+
+ public Validator getFieldValidator() {
+ return fieldValidator;
}
public StringProperty textProperty() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java
index 65a1dbcce55..78bff7f6bc4 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java
@@ -9,6 +9,7 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.util.ControlHelper;
import org.jabref.gui.util.component.TemporalAccessorPicker;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.BibEntry;
public class DateEditor extends HBox implements FieldEditorFX {
@@ -16,8 +17,8 @@ public class DateEditor extends HBox implements FieldEditorFX {
@FXML private DateEditorViewModel viewModel;
@FXML private TemporalAccessorPicker datePicker;
- public DateEditor(String fieldName, DateTimeFormatter dateFormatter, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new DateEditorViewModel(fieldName, suggestionProvider, dateFormatter);
+ public DateEditor(String fieldName, DateTimeFormatter dateFormatter, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new DateEditorViewModel(fieldName, suggestionProvider, dateFormatter, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
diff --git a/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java
index 6ea9f8d2237..dc68f1d5d15 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java
@@ -7,14 +7,15 @@
import javafx.util.StringConverter;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.Date;
import org.jabref.model.strings.StringUtil;
public class DateEditorViewModel extends AbstractEditorViewModel {
private final DateTimeFormatter dateFormatter;
- public DateEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DateTimeFormatter dateFormatter) {
- super(fieldName, suggestionProvider);
+ public DateEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DateTimeFormatter dateFormatter, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.dateFormatter = dateFormatter;
}
diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTypeEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTypeEditorViewModel.java
index 118430fea4b..e3c7ccfd40a 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/EditorTypeEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTypeEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import com.google.common.collect.BiMap;
@@ -10,8 +11,8 @@ public class EditorTypeEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(7);
- public EditorTypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public EditorTypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("editor", Localization.lang("Editor"));
itemMap.put("compiler", Localization.lang("Compiler"));
diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java
index 089a71ab3f2..20083ef3680 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java
@@ -10,6 +10,7 @@
import org.jabref.gui.autocompleter.ContentSelectorSuggestionProvider;
import org.jabref.gui.autocompleter.SuggestionProviders;
import org.jabref.gui.util.TaskExecutor;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.model.database.BibDatabaseContext;
@@ -30,46 +31,48 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu
AutoCompleteSuggestionProvider> suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData());
+ FieldCheckers fieldCheckers = new FieldCheckers(databaseContext, preferences.getFileDirectoryPreferences());
+
if (Globals.prefs.getTimestampPreferences().getTimestampField().equals(fieldName) || fieldExtras.contains(FieldProperty.DATE)) {
if (fieldExtras.contains(FieldProperty.ISO_DATE)) {
- return new DateEditor(fieldName, DateTimeFormatter.ofPattern("[uuuu][-MM][-dd]"), suggestionProvider);
+ return new DateEditor(fieldName, DateTimeFormatter.ofPattern("[uuuu][-MM][-dd]"), suggestionProvider, fieldCheckers);
} else {
- return new DateEditor(fieldName, DateTimeFormatter.ofPattern(Globals.prefs.getTimestampPreferences().getTimestampFormat()), suggestionProvider);
+ return new DateEditor(fieldName, DateTimeFormatter.ofPattern(Globals.prefs.getTimestampPreferences().getTimestampFormat()), suggestionProvider, fieldCheckers);
}
} else if (fieldExtras.contains(FieldProperty.EXTERNAL)) {
- return new UrlEditor(fieldName, dialogService, suggestionProvider);
+ return new UrlEditor(fieldName, dialogService, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.JOURNAL_NAME)) {
- return new JournalEditor(fieldName, journalAbbreviationLoader, journalAbbreviationPreferences, suggestionProvider);
+ return new JournalEditor(fieldName, journalAbbreviationLoader, journalAbbreviationPreferences, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.DOI) || fieldExtras.contains(FieldProperty.EPRINT) || fieldExtras.contains(FieldProperty.ISBN)) {
- return new IdentifierEditor(fieldName, taskExecutor, dialogService, suggestionProvider);
+ return new IdentifierEditor(fieldName, taskExecutor, dialogService, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.OWNER)) {
- return new OwnerEditor(fieldName, preferences, suggestionProvider);
+ return new OwnerEditor(fieldName, preferences, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.FILE_EDITOR)) {
- return new LinkedFilesEditor(fieldName, dialogService, databaseContext, taskExecutor, suggestionProvider);
+ return new LinkedFilesEditor(fieldName, dialogService, databaseContext, taskExecutor, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.YES_NO)) {
- return new OptionEditor<>(fieldName, new YesNoEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new YesNoEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
} else if (fieldExtras.contains(FieldProperty.MONTH)) {
- return new OptionEditor<>(fieldName, new MonthEditorViewModel(fieldName, suggestionProvider, databaseContext.getMode()));
+ return new OptionEditor<>(fieldName, new MonthEditorViewModel(fieldName, suggestionProvider, databaseContext.getMode(), fieldCheckers));
} else if (fieldExtras.contains(FieldProperty.GENDER)) {
- return new OptionEditor<>(fieldName, new GenderEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new GenderEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
} else if (fieldExtras.contains(FieldProperty.EDITOR_TYPE)) {
- return new OptionEditor<>(fieldName, new EditorTypeEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new EditorTypeEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
} else if (fieldExtras.contains(FieldProperty.PAGINATION)) {
- return new OptionEditor<>(fieldName, new PaginationEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new PaginationEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
} else if (fieldExtras.contains(FieldProperty.TYPE)) {
if ("patent".equalsIgnoreCase(entryType)) {
- return new OptionEditor<>(fieldName, new PatentTypeEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new PatentTypeEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
} else {
- return new OptionEditor<>(fieldName, new TypeEditorViewModel(fieldName, suggestionProvider));
+ return new OptionEditor<>(fieldName, new TypeEditorViewModel(fieldName, suggestionProvider, fieldCheckers));
}
} else if (fieldExtras.contains(FieldProperty.SINGLE_ENTRY_LINK) || fieldExtras.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) {
- return new LinkedEntriesEditor(fieldName, databaseContext, suggestionProvider);
+ return new LinkedEntriesEditor(fieldName, databaseContext, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.PERSON_NAMES)) {
- return new PersonsEditor(fieldName, suggestionProvider, preferences.getAutoCompletePreferences());
+ return new PersonsEditor(fieldName, suggestionProvider, preferences.getAutoCompletePreferences(), fieldCheckers);
}
// default
- return new SimpleEditor(fieldName, suggestionProvider);
+ return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers);
}
@SuppressWarnings("unchecked")
diff --git a/src/main/java/org/jabref/gui/fieldeditors/GenderEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/GenderEditorViewModel.java
index 8678807cb0b..a1ec99fed4f 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/GenderEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/GenderEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import com.google.common.collect.BiMap;
@@ -10,8 +11,8 @@ public class GenderEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(7);
- public GenderEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public GenderEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("sf", Localization.lang("Female name"));
itemMap.put("sm", Localization.lang("Male name"));
diff --git a/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditor.java b/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditor.java
index 49640668bae..d99389be2e6 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditor.java
@@ -17,10 +17,13 @@
import org.jabref.gui.fieldeditors.contextmenu.EditorMenus;
import org.jabref.gui.util.ControlHelper;
import org.jabref.gui.util.TaskExecutor;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class IdentifierEditor extends HBox implements FieldEditorFX {
@FXML private IdentifierEditorViewModel viewModel;
@@ -29,8 +32,8 @@ public class IdentifierEditor extends HBox implements FieldEditorFX {
@FXML private Button lookupIdentifierButton;
private Optional entry;
- public IdentifierEditor(String fieldName, TaskExecutor taskExecutor, DialogService dialogService, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new IdentifierEditorViewModel(fieldName, suggestionProvider, taskExecutor, dialogService);
+ public IdentifierEditor(String fieldName, TaskExecutor taskExecutor, DialogService dialogService, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new IdentifierEditorViewModel(fieldName, suggestionProvider, taskExecutor, dialogService, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
@@ -47,6 +50,9 @@ public IdentifierEditor(String fieldName, TaskExecutor taskExecutor, DialogServi
}
menuItems.addAll(EditorMenus.getDefaultMenu(textArea));
textArea.addToContextMenu(menuItems);
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
public IdentifierEditorViewModel getViewModel() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModel.java
index 850d041c827..f714e0764b4 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModel.java
@@ -16,6 +16,7 @@
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.importer.WebFetchers;
import org.jabref.logic.importer.util.IdentifierParser;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
@@ -31,8 +32,8 @@ public class IdentifierEditorViewModel extends AbstractEditorViewModel {
private TaskExecutor taskExecutor;
private DialogService dialogService;
- public IdentifierEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, TaskExecutor taskExecutor, DialogService dialogService) {
- super(fieldName, suggestionProvider);
+ public IdentifierEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, TaskExecutor taskExecutor, DialogService dialogService, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.taskExecutor = taskExecutor;
this.dialogService = dialogService;
diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java
index 27a6c823e38..71eb2bacbc6 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java
@@ -11,18 +11,21 @@
import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding;
import org.jabref.gui.fieldeditors.contextmenu.EditorMenus;
import org.jabref.gui.util.ControlHelper;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.model.entry.BibEntry;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class JournalEditor extends HBox implements FieldEditorFX {
@FXML private JournalEditorViewModel viewModel;
@FXML private EditorTextArea textArea;
private Optional entry;
- public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, journalAbbreviationPreferences);
+ public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, journalAbbreviationPreferences, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
@@ -30,6 +33,9 @@ public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbrevia
textArea.addToContextMenu(EditorMenus.getDefaultMenu(textArea));
AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete);
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
public JournalEditorViewModel getViewModel() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java
index 278f6c955f2..e59d1305efc 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java
@@ -3,6 +3,7 @@
import java.util.Optional;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.logic.journals.JournalAbbreviationRepository;
@@ -12,8 +13,8 @@ public class JournalEditorViewModel extends AbstractEditorViewModel {
private final JournalAbbreviationLoader journalAbbreviationLoader;
private final JournalAbbreviationPreferences journalAbbreviationPreferences;
- public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences) {
- super(fieldName, suggestionProvider);
+ public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.journalAbbreviationLoader = journalAbbreviationLoader;
this.journalAbbreviationPreferences = journalAbbreviationPreferences;
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditor.java
index f90dc27a89e..6c8a940ca90 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditor.java
@@ -8,6 +8,7 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.util.ControlHelper;
import org.jabref.gui.util.component.TagBar;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.ParsedEntryLink;
@@ -17,8 +18,8 @@ public class LinkedEntriesEditor extends HBox implements FieldEditorFX {
@FXML private LinkedEntriesEditorViewModel viewModel;
@FXML private TagBar linkedEntriesBar;
- public LinkedEntriesEditor(String fieldName, BibDatabaseContext databaseContext, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new LinkedEntriesEditorViewModel(fieldName, suggestionProvider, databaseContext);
+ public LinkedEntriesEditor(String fieldName, BibDatabaseContext databaseContext, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new LinkedEntriesEditorViewModel(fieldName, suggestionProvider, databaseContext, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditorViewModel.java
index dce4a28b009..bf9e889de6c 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedEntriesEditorViewModel.java
@@ -7,6 +7,7 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.util.BindingsHelper;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.EntryLinkList;
import org.jabref.model.entry.ParsedEntryLink;
@@ -16,8 +17,8 @@ public class LinkedEntriesEditorViewModel extends AbstractEditorViewModel {
private final BibDatabaseContext databaseContext;
private final ListProperty linkedEntries;
- public LinkedEntriesEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, BibDatabaseContext databaseContext) {
- super(fieldName, suggestionProvider);
+ public LinkedEntriesEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, BibDatabaseContext databaseContext, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.databaseContext = databaseContext;
linkedEntries = new SimpleListProperty<>(FXCollections.observableArrayList());
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
index 9e83cf2a34e..7a2675f165e 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
@@ -27,6 +27,7 @@
import org.jabref.gui.util.ControlHelper;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.gui.util.ViewModelListCellFactory;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
@@ -39,8 +40,8 @@ public class LinkedFilesEditor extends HBox implements FieldEditorFX {
@FXML private final LinkedFilesEditorViewModel viewModel;
@FXML private ListView listView;
- public LinkedFilesEditor(String fieldName, DialogService dialogService, BibDatabaseContext databaseContext, TaskExecutor taskExecutor, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new LinkedFilesEditorViewModel(fieldName, suggestionProvider, dialogService, databaseContext, taskExecutor);
+ public LinkedFilesEditor(String fieldName, DialogService dialogService, BibDatabaseContext databaseContext, TaskExecutor taskExecutor, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new LinkedFilesEditorViewModel(fieldName, suggestionProvider, dialogService, databaseContext, taskExecutor, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java
index 87a944f430b..b18680cb654 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java
@@ -30,6 +30,7 @@
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.importer.FulltextFetchers;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.net.URLDownload;
import org.jabref.logic.util.OS;
@@ -57,8 +58,8 @@ public class LinkedFilesEditorViewModel extends AbstractEditorViewModel {
private final BibDatabaseContext databaseContext;
private final TaskExecutor taskExecutor;
- public LinkedFilesEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DialogService dialogService, BibDatabaseContext databaseContext, TaskExecutor taskExecutor) {
- super(fieldName, suggestionProvider);
+ public LinkedFilesEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DialogService dialogService, BibDatabaseContext databaseContext, TaskExecutor taskExecutor, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.dialogService = dialogService;
this.databaseContext = databaseContext;
diff --git a/src/main/java/org/jabref/gui/fieldeditors/MapBasedEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/MapBasedEditorViewModel.java
index 8fd185db2f3..e3ae0b22920 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/MapBasedEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/MapBasedEditorViewModel.java
@@ -6,6 +6,7 @@
import javafx.util.StringConverter;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import com.google.common.collect.BiMap;
@@ -14,8 +15,8 @@
*/
public abstract class MapBasedEditorViewModel extends OptionEditorViewModel {
- public MapBasedEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public MapBasedEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
}
protected abstract BiMap getItemMap();
diff --git a/src/main/java/org/jabref/gui/fieldeditors/MonthEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/MonthEditorViewModel.java
index 49c3c1592e5..16cadcd7d4f 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/MonthEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/MonthEditorViewModel.java
@@ -6,6 +6,7 @@
import javafx.util.StringConverter;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.database.BibDatabaseMode;
import org.jabref.model.entry.Month;
import org.jabref.model.strings.StringUtil;
@@ -13,8 +14,8 @@
public class MonthEditorViewModel extends OptionEditorViewModel {
private BibDatabaseMode databaseMode;
- public MonthEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, BibDatabaseMode databaseMode) {
- super(fieldName, suggestionProvider);
+ public MonthEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, BibDatabaseMode databaseMode, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.databaseMode = databaseMode;
}
diff --git a/src/main/java/org/jabref/gui/fieldeditors/OptionEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/OptionEditorViewModel.java
index 4bafb4de7c8..f642144d9b8 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/OptionEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/OptionEditorViewModel.java
@@ -5,11 +5,12 @@
import javafx.util.StringConverter;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
public abstract class OptionEditorViewModel extends AbstractEditorViewModel {
- public OptionEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public OptionEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
}
public abstract StringConverter getStringConverter();
diff --git a/src/main/java/org/jabref/gui/fieldeditors/OwnerEditor.java b/src/main/java/org/jabref/gui/fieldeditors/OwnerEditor.java
index ea869e1cf9e..c1558ed8899 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/OwnerEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/OwnerEditor.java
@@ -7,20 +7,26 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.util.ControlHelper;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class OwnerEditor extends HBox implements FieldEditorFX {
@FXML private OwnerEditorViewModel viewModel;
@FXML private EditorTextArea textArea;
- public OwnerEditor(String fieldName, JabRefPreferences preferences, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new OwnerEditorViewModel(fieldName, suggestionProvider, preferences);
+ public OwnerEditor(String fieldName, JabRefPreferences preferences, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new OwnerEditorViewModel(fieldName, suggestionProvider, preferences, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
textArea.textProperty().bindBidirectional(viewModel.textProperty());
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
public OwnerEditorViewModel getViewModel() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/OwnerEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/OwnerEditorViewModel.java
index 7c2bef29fae..3b071dffb1b 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/OwnerEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/OwnerEditorViewModel.java
@@ -1,13 +1,14 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.preferences.JabRefPreferences;
public class OwnerEditorViewModel extends AbstractEditorViewModel {
private final JabRefPreferences preferences;
- public OwnerEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, JabRefPreferences preferences) {
- super(fieldName, suggestionProvider);
+ public OwnerEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, JabRefPreferences preferences, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.preferences = preferences;
}
diff --git a/src/main/java/org/jabref/gui/fieldeditors/PaginationEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/PaginationEditorViewModel.java
index 2b51e82266e..b9e269131d2 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/PaginationEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/PaginationEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import com.google.common.collect.BiMap;
@@ -10,8 +11,8 @@ public class PaginationEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(7);
- public PaginationEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public PaginationEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("page", Localization.lang("Page"));
itemMap.put("column", Localization.lang("Column"));
diff --git a/src/main/java/org/jabref/gui/fieldeditors/PatentTypeEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/PatentTypeEditorViewModel.java
index 5523efe3cb6..d8cdd5d3dd1 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/PatentTypeEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/PatentTypeEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import com.google.common.collect.BiMap;
@@ -10,8 +11,8 @@ public class PatentTypeEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(12);
- public PatentTypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public PatentTypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("patent", Localization.lang("Patent"));
itemMap.put("patentde", Localization.lang("German patent"));
diff --git a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java
index 36dd9ed425c..f55b88b4f34 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java
@@ -9,14 +9,17 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding;
import org.jabref.gui.fieldeditors.contextmenu.EditorMenus;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.BibEntry;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class PersonsEditor extends HBox implements FieldEditorFX {
@FXML private final PersonsEditorViewModel viewModel;
- public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, AutoCompletePreferences autoCompletePreferences) {
- this.viewModel = new PersonsEditorViewModel(fieldName, suggestionProvider, autoCompletePreferences);
+ public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, AutoCompletePreferences autoCompletePreferences, FieldCheckers fieldCheckers) {
+ this.viewModel = new PersonsEditorViewModel(fieldName, suggestionProvider, autoCompletePreferences, fieldCheckers);
EditorTextArea textArea = new EditorTextArea();
HBox.setHgrow(textArea, Priority.ALWAYS);
@@ -25,6 +28,9 @@ public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider> suggest
this.getChildren().add(textArea);
AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy());
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
@Override
diff --git a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditorViewModel.java
index c41ac32773e..d85910c2953 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditorViewModel.java
@@ -9,6 +9,7 @@
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.autocompleter.AutoCompletionStrategy;
import org.jabref.gui.autocompleter.PersonNameStringConverter;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.Author;
import org.controlsfx.control.textfield.AutoCompletionBinding;
@@ -17,8 +18,8 @@ public class PersonsEditorViewModel extends AbstractEditorViewModel {
private final AutoCompletePreferences preferences;
- public PersonsEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, AutoCompletePreferences preferences) {
- super(fieldName, suggestionProvider);
+ public PersonsEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, AutoCompletePreferences preferences, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.preferences = preferences;
}
diff --git a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java
index 261e8a43501..168a3819a7a 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java
@@ -9,14 +9,17 @@
import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding;
import org.jabref.gui.autocompleter.ContentSelectorSuggestionProvider;
import org.jabref.gui.fieldeditors.contextmenu.EditorMenus;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.BibEntry;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class SimpleEditor extends HBox implements FieldEditorFX {
@FXML private final SimpleEditorViewModel viewModel;
- public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new SimpleEditorViewModel(fieldName, suggestionProvider);
+ public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new SimpleEditorViewModel(fieldName, suggestionProvider, fieldCheckers);
EditorTextArea textArea = new EditorTextArea();
HBox.setHgrow(textArea, Priority.ALWAYS);
@@ -29,6 +32,9 @@ public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider> suggesti
// If content selector values are present, then we want to show the auto complete suggestions immediately on focus
autoCompleter.setShowOnFocus(true);
}
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
@Override
diff --git a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditorViewModel.java
index 1cc61e93ab7..3a006fa460d 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditorViewModel.java
@@ -3,11 +3,12 @@
import org.jabref.gui.autocompleter.AppendWordsStrategy;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.autocompleter.AutoCompletionStrategy;
+import org.jabref.logic.integrity.FieldCheckers;
public class SimpleEditorViewModel extends AbstractEditorViewModel {
- public SimpleEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public SimpleEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
}
public AutoCompletionStrategy getAutoCompletionStrategy() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/TypeEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/TypeEditorViewModel.java
index 0ad32035de1..e13e4200323 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/TypeEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/TypeEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import com.google.common.collect.BiMap;
@@ -10,8 +11,8 @@ public class TypeEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(8);
- public TypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public TypeEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("mathesis", Localization.lang("Master's thesis"));
itemMap.put("phdthesis", Localization.lang("PhD thesis"));
diff --git a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java
index 6bffe03deee..7a621b5325a 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java
@@ -8,19 +8,25 @@
import org.jabref.gui.DialogService;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.util.ControlHelper;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.model.entry.BibEntry;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
public class UrlEditor extends HBox implements FieldEditorFX {
@FXML private UrlEditorViewModel viewModel;
@FXML private EditorTextArea textArea;
- public UrlEditor(String fieldName, DialogService dialogService, AutoCompleteSuggestionProvider> suggestionProvider) {
- this.viewModel = new UrlEditorViewModel(fieldName, suggestionProvider, dialogService);
+ public UrlEditor(String fieldName, DialogService dialogService, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ this.viewModel = new UrlEditorViewModel(fieldName, suggestionProvider, dialogService, fieldCheckers);
ControlHelper.loadFXMLForControl(this);
textArea.textProperty().bindBidirectional(viewModel.textProperty());
+
+ ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+ validationVisualizer.initVisualization(viewModel.getFieldValidator().getValidationStatus(), textArea);
}
public UrlEditorViewModel getViewModel() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/UrlEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/UrlEditorViewModel.java
index 051a5e34b56..f370a1a89ad 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/UrlEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/UrlEditorViewModel.java
@@ -8,6 +8,7 @@
import org.jabref.gui.DialogService;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.gui.desktop.JabRefDesktop;
+import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.net.URLUtil;
import org.jabref.model.strings.StringUtil;
@@ -18,8 +19,8 @@ public class UrlEditorViewModel extends AbstractEditorViewModel {
private DialogService dialogService;
private BooleanProperty validUrlIsNotPresent = new SimpleBooleanProperty(true);
- public UrlEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DialogService dialogService) {
- super(fieldName, suggestionProvider);
+ public UrlEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, DialogService dialogService, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
this.dialogService = dialogService;
validUrlIsNotPresent.bind(
diff --git a/src/main/java/org/jabref/gui/fieldeditors/YesNoEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/YesNoEditorViewModel.java
index 7cad3e7e356..fcf9c59e40b 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/YesNoEditorViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/YesNoEditorViewModel.java
@@ -1,6 +1,7 @@
package org.jabref.gui.fieldeditors;
import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
+import org.jabref.logic.integrity.FieldCheckers;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -9,8 +10,8 @@ public class YesNoEditorViewModel extends MapBasedEditorViewModel {
private BiMap itemMap = HashBiMap.create(2);
- public YesNoEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider) {
- super(fieldName, suggestionProvider);
+ public YesNoEditorViewModel(String fieldName, AutoCompleteSuggestionProvider> suggestionProvider, FieldCheckers fieldCheckers) {
+ super(fieldName, suggestionProvider, fieldCheckers);
itemMap.put("yes", "Yes");
itemMap.put("no", "No");
diff --git a/src/main/java/org/jabref/logic/integrity/AbbreviationChecker.java b/src/main/java/org/jabref/logic/integrity/AbbreviationChecker.java
index 9203d9e4bba..f8eff670c11 100644
--- a/src/main/java/org/jabref/logic/integrity/AbbreviationChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/AbbreviationChecker.java
@@ -3,11 +3,16 @@
import java.util.Optional;
import org.jabref.logic.l10n.Localization;
+import org.jabref.model.strings.StringUtil;
public class AbbreviationChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (value.contains(".")) {
return Optional.of(Localization.lang("abbreviation detected"));
}
diff --git a/src/main/java/org/jabref/logic/integrity/BooktitleChecker.java b/src/main/java/org/jabref/logic/integrity/BooktitleChecker.java
index ea781bf20b1..3ed8b36a6e7 100644
--- a/src/main/java/org/jabref/logic/integrity/BooktitleChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/BooktitleChecker.java
@@ -4,11 +4,16 @@
import java.util.Optional;
import org.jabref.logic.l10n.Localization;
+import org.jabref.model.strings.StringUtil;
public class BooktitleChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (value.toLowerCase(Locale.ENGLISH).endsWith("conference on")) {
return Optional.of(Localization.lang("booktitle ends with 'conference on'"));
}
diff --git a/src/main/java/org/jabref/logic/integrity/BracketChecker.java b/src/main/java/org/jabref/logic/integrity/BracketChecker.java
index d5215d9a94b..bff56b03770 100644
--- a/src/main/java/org/jabref/logic/integrity/BracketChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/BracketChecker.java
@@ -3,11 +3,16 @@
import java.util.Optional;
import org.jabref.logic.l10n.Localization;
+import org.jabref.model.strings.StringUtil;
public class BracketChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
// metaphor: integer-based stack (push + / pop -)
int counter = 0;
for (char a : value.trim().toCharArray()) {
diff --git a/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java b/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java
index e2f2f069303..09c144a087f 100644
--- a/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java
@@ -4,11 +4,16 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.identifier.DOI;
+import org.jabref.model.strings.StringUtil;
public class DOIValidityChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (DOI.isValid(value)) {
return Optional.empty();
} else {
diff --git a/src/main/java/org/jabref/logic/integrity/EditionChecker.java b/src/main/java/org/jabref/logic/integrity/EditionChecker.java
index 87f968346a2..54a1869bfe2 100644
--- a/src/main/java/org/jabref/logic/integrity/EditionChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/EditionChecker.java
@@ -7,6 +7,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class EditionChecker implements ValueChecker {
@@ -33,6 +34,10 @@ public EditionChecker(BibDatabaseContext bibDatabaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
//biblatex
if (bibDatabaseContextEdition.isBiblatexMode() && !ONLY_NUMERALS_OR_LITERALS.test(value.trim())) {
return Optional.of(Localization.lang("should contain an integer or a literal"));
diff --git a/src/main/java/org/jabref/logic/integrity/FieldCheckers.java b/src/main/java/org/jabref/logic/integrity/FieldCheckers.java
index f809d535cf2..5439e09b7ef 100644
--- a/src/main/java/org/jabref/logic/integrity/FieldCheckers.java
+++ b/src/main/java/org/jabref/logic/integrity/FieldCheckers.java
@@ -1,5 +1,6 @@
package org.jabref.logic.integrity;
+import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@@ -13,14 +14,10 @@
public class FieldCheckers {
- private FieldCheckers() {
- }
+ private Multimap fieldChecker;
- static List getAll(BibDatabaseContext databaseContext, FileDirectoryPreferences fileDirectoryPreferences) {
- return getAllMap(databaseContext, fileDirectoryPreferences)
- .entries().stream()
- .map(pair -> new FieldChecker(pair.getKey(), pair.getValue()))
- .collect(Collectors.toList());
+ public FieldCheckers(BibDatabaseContext databaseContext, FileDirectoryPreferences fileDirectoryPreferences) {
+ fieldChecker = getAllMap(databaseContext, fileDirectoryPreferences);
}
private static Multimap getAllMap(BibDatabaseContext databaseContext, FileDirectoryPreferences fileDirectoryPreferences) {
@@ -52,4 +49,17 @@ private static Multimap getAllMap(BibDatabaseContext datab
return fieldCheckers;
}
+
+ public List getAll() {
+ return fieldChecker
+ .entries()
+ .stream()
+ .map(pair -> new FieldChecker(pair.getKey(), pair.getValue()))
+ .collect(Collectors.toList());
+ }
+
+ public Collection getForField(String field) {
+ return fieldChecker
+ .get(field);
+ }
}
diff --git a/src/main/java/org/jabref/logic/integrity/FileChecker.java b/src/main/java/org/jabref/logic/integrity/FileChecker.java
index 56b9f89ca17..f631230922b 100644
--- a/src/main/java/org/jabref/logic/integrity/FileChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/FileChecker.java
@@ -11,6 +11,7 @@
import org.jabref.model.entry.FileFieldParser;
import org.jabref.model.entry.LinkedFile;
import org.jabref.model.metadata.FileDirectoryPreferences;
+import org.jabref.model.strings.StringUtil;
public class FileChecker implements ValueChecker {
@@ -25,6 +26,10 @@ public FileChecker(BibDatabaseContext context, FileDirectoryPreferences fileDire
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
List linkedFiles = FileFieldParser.parse(value).stream()
.filter(file -> !file.isOnlineLink())
.collect(Collectors.toList());
diff --git a/src/main/java/org/jabref/logic/integrity/HowPublishedChecker.java b/src/main/java/org/jabref/logic/integrity/HowPublishedChecker.java
index 2286caba87a..1406e3641a5 100644
--- a/src/main/java/org/jabref/logic/integrity/HowPublishedChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/HowPublishedChecker.java
@@ -7,6 +7,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class HowPublishedChecker implements ValueChecker {
@@ -27,6 +28,10 @@ public HowPublishedChecker(BibDatabaseContext databaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
//BibTeX
if (!databaseContext.isBiblatexMode() && !FIRST_LETTER_CAPITALIZED.test(value.trim())) {
return Optional.of(Localization.lang("should have the first letter capitalized"));
diff --git a/src/main/java/org/jabref/logic/integrity/ISBNChecker.java b/src/main/java/org/jabref/logic/integrity/ISBNChecker.java
index a8aa29054c0..c774dc9148a 100644
--- a/src/main/java/org/jabref/logic/integrity/ISBNChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/ISBNChecker.java
@@ -4,11 +4,16 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.identifier.ISBN;
+import org.jabref.model.strings.StringUtil;
public class ISBNChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
// Check that the ISBN is on the correct form
ISBN isbn = new ISBN(value);
diff --git a/src/main/java/org/jabref/logic/integrity/ISSNChecker.java b/src/main/java/org/jabref/logic/integrity/ISSNChecker.java
index 11dae320d84..23502ec9e8a 100644
--- a/src/main/java/org/jabref/logic/integrity/ISSNChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/ISSNChecker.java
@@ -4,11 +4,16 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.identifier.ISSN;
+import org.jabref.model.strings.StringUtil;
public class ISSNChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
// Check that the ISSN is on the correct form
String issnString = value.trim();
diff --git a/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java b/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java
index 62e49aa6232..8407864502e 100644
--- a/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java
+++ b/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java
@@ -46,7 +46,8 @@ private List checkBibtexEntry(BibEntry entry) {
return result;
}
- for (FieldChecker checker : FieldCheckers.getAll(bibDatabaseContext, fileDirectoryPreferences)) {
+ FieldCheckers fieldCheckers = new FieldCheckers(bibDatabaseContext, fileDirectoryPreferences);
+ for (FieldChecker checker : fieldCheckers.getAll()) {
result.addAll(checker.check(entry));
}
diff --git a/src/main/java/org/jabref/logic/integrity/MonthChecker.java b/src/main/java/org/jabref/logic/integrity/MonthChecker.java
index 3bb5a9c5b22..402fbf65f66 100644
--- a/src/main/java/org/jabref/logic/integrity/MonthChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/MonthChecker.java
@@ -7,6 +7,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class MonthChecker implements ValueChecker {
@@ -33,6 +34,10 @@ public MonthChecker(BibDatabaseContext bibDatabaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
//biblatex
if (bibDatabaseContextMonth.isBiblatexMode()
&& !(ONLY_AN_INTEGER.test(value.trim()) || MONTH_NORMALIZED.test(value.trim()))) {
diff --git a/src/main/java/org/jabref/logic/integrity/NoteChecker.java b/src/main/java/org/jabref/logic/integrity/NoteChecker.java
index a12236b1bd6..e6cdc6e6ba3 100644
--- a/src/main/java/org/jabref/logic/integrity/NoteChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/NoteChecker.java
@@ -7,6 +7,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class NoteChecker implements ValueChecker {
@@ -27,6 +28,10 @@ public NoteChecker(BibDatabaseContext bibDatabaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
//BibTeX
if (!bibDatabaseContextEdition.isBiblatexMode() && !FIRST_LETTER_CAPITALIZED.test(value.trim())) {
return Optional.of(Localization.lang("should have the first letter capitalized"));
diff --git a/src/main/java/org/jabref/logic/integrity/PagesChecker.java b/src/main/java/org/jabref/logic/integrity/PagesChecker.java
index ae0cdbba36e..0040afd2f2a 100644
--- a/src/main/java/org/jabref/logic/integrity/PagesChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/PagesChecker.java
@@ -6,6 +6,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class PagesChecker implements ValueChecker {
@@ -52,6 +53,10 @@ public PagesChecker(BibDatabaseContext databaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (!isValidPageNumber.test(value.trim())) {
return Optional.of(Localization.lang("should contain a valid page number range"));
}
diff --git a/src/main/java/org/jabref/logic/integrity/PersonNamesChecker.java b/src/main/java/org/jabref/logic/integrity/PersonNamesChecker.java
index 572070ae975..33ee505871a 100644
--- a/src/main/java/org/jabref/logic/integrity/PersonNamesChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/PersonNamesChecker.java
@@ -5,11 +5,16 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.AuthorList;
+import org.jabref.model.strings.StringUtil;
public class PersonNamesChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
String valueTrimmedAndLowerCase = value.trim().toLowerCase(Locale.ROOT);
if (valueTrimmedAndLowerCase.startsWith("and ") || valueTrimmedAndLowerCase.startsWith(",")) {
return Optional.of(Localization.lang("should start with a name"));
diff --git a/src/main/java/org/jabref/logic/integrity/TitleChecker.java b/src/main/java/org/jabref/logic/integrity/TitleChecker.java
index a321a2b7e91..c2725949d24 100644
--- a/src/main/java/org/jabref/logic/integrity/TitleChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/TitleChecker.java
@@ -7,6 +7,7 @@
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.strings.StringUtil;
public class TitleChecker implements ValueChecker {
@@ -28,6 +29,10 @@ public TitleChecker(BibDatabaseContext databaseContext) {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (databaseContext.isBiblatexMode()) {
return Optional.empty();
}
diff --git a/src/main/java/org/jabref/logic/integrity/UrlChecker.java b/src/main/java/org/jabref/logic/integrity/UrlChecker.java
index 7ce1bc219dd..8d99968ac96 100644
--- a/src/main/java/org/jabref/logic/integrity/UrlChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/UrlChecker.java
@@ -3,11 +3,16 @@
import java.util.Optional;
import org.jabref.logic.l10n.Localization;
+import org.jabref.model.strings.StringUtil;
public class UrlChecker implements ValueChecker {
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (!value.contains("://")) {
return Optional.of(Localization.lang("should contain a protocol") + ": http[s]://, file://, ftp://, ...");
}
diff --git a/src/main/java/org/jabref/logic/integrity/YearChecker.java b/src/main/java/org/jabref/logic/integrity/YearChecker.java
index 4a7fdb9cbb7..b137c0ea407 100644
--- a/src/main/java/org/jabref/logic/integrity/YearChecker.java
+++ b/src/main/java/org/jabref/logic/integrity/YearChecker.java
@@ -5,6 +5,7 @@
import java.util.regex.Pattern;
import org.jabref.logic.l10n.Localization;
+import org.jabref.model.strings.StringUtil;
public class YearChecker implements ValueChecker {
@@ -22,6 +23,10 @@ public class YearChecker implements ValueChecker {
*/
@Override
public Optional checkValue(String value) {
+ if (StringUtil.isBlank(value)) {
+ return Optional.empty();
+ }
+
if (!CONTAINS_FOUR_DIGIT.test(value.trim())) {
return Optional.of(Localization.lang("should contain a four digit number"));
}
diff --git a/src/test/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModelTest.java b/src/test/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModelTest.java
index 92c3e63eefa..d681344d9b0 100644
--- a/src/test/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModelTest.java
+++ b/src/test/java/org/jabref/gui/fieldeditors/IdentifierEditorViewModelTest.java
@@ -3,6 +3,7 @@
import org.jabref.gui.DialogService;
import org.jabref.gui.autocompleter.WordSuggestionProvider;
import org.jabref.gui.util.CurrentThreadTaskExecutor;
+import org.jabref.logic.integrity.FieldCheckers;
import org.junit.Before;
import org.junit.Test;
@@ -16,7 +17,7 @@ public class IdentifierEditorViewModelTest {
@Before
public void setUp() throws Exception {
- viewModel = new IdentifierEditorViewModel("DOI", new WordSuggestionProvider("DOI"), new CurrentThreadTaskExecutor(), mock(DialogService.class));
+ viewModel = new IdentifierEditorViewModel("DOI", new WordSuggestionProvider("DOI"), new CurrentThreadTaskExecutor(), mock(DialogService.class), mock(FieldCheckers.class));
}
@Test