diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index c7961bff628..4289c29d1b2 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -300,7 +300,7 @@ private List createTabs() { tabs.add(new RelatedArticlesTab(preferences, dialogService)); // Source tab - sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor); + sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService); tabs.add(sourceTab); return tabs; } diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index f380e64e269..b96fed0bea4 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -13,6 +13,7 @@ import javafx.collections.ListChangeListener; import javafx.scene.control.Tooltip; +import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.gui.undo.NamedCompound; @@ -53,8 +54,9 @@ public class SourceTab extends EntryEditorTab { private final ObservableRuleBasedValidator sourceValidator = new ObservableRuleBasedValidator(sourceIsValid); private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; + private final DialogService dialogService; - public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor) { + public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager, LatexFieldFormatterPreferences fieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor, DialogService dialogService) { this.mode = bibDatabaseContext.getMode(); this.setText(Localization.lang("%0 source", mode.getFormattedName())); this.setTooltip(new Tooltip(Localization.lang("Show/edit %0 source", mode.getFormattedName()))); @@ -63,6 +65,7 @@ public SourceTab(BibDatabaseContext bibDatabaseContext, CountingUndoManager undo this.fieldFormatterPreferences = fieldFormatterPreferences; this.importFormatPreferences = importFormatPreferences; this.fileMonitor = fileMonitor; + this.dialogService = dialogService; } @@ -95,14 +98,21 @@ protected void bindToEntry(BibEntry entry) { if (sourceValidator.getValidationStatus().isValid()) { notificationPane.hide(); } else { - sourceValidator.getValidationStatus().getHighestMessage().ifPresent(validationMessage -> notificationPane.show(validationMessage.getMessage())); + sourceValidator.getValidationStatus().getHighestMessage().ifPresent(validationMessage -> { + notificationPane.show(validationMessage.getMessage());//this seems not working + dialogService.showErrorDialogAndWait(validationMessage.getMessage()); + }); } }); this.setContent(codeArea); - // Store source for every change in the source code + // Store source for on focus out event in the source code (within its text area) // and update source code for every change of entry field values - BindingsHelper.bindContentBidirectional(entry.getFieldsObservable(), codeArea.textProperty(), this::storeSource, fields -> { + BindingsHelper.bindContentBidirectional(entry.getFieldsObservable(), codeArea.focusedProperty(), onFocus -> { + if (!onFocus) { + storeSource(codeArea.textProperty().getValue()); + } + }, fields -> { DefaultTaskExecutor.runAndWaitInJavaFXThread(() -> { codeArea.clear(); try { @@ -110,7 +120,7 @@ protected void bindToEntry(BibEntry entry) { } catch (IOException ex) { codeArea.setEditable(false); codeArea.appendText(ex.getMessage() + "\n\n" + - Localization.lang("Correct the entry, and reopen editor to display/edit source.")); + Localization.lang("Correct the entry, and reopen editor to display/edit source.")); LOGGER.debug("Incorrect entry", ex); } }); @@ -141,6 +151,12 @@ private void storeSource(String text) { } } + if (parserResult.hasWarnings()) { + // put the warning into as exception text -> it will be displayed to the user + + throw new IllegalStateException(parserResult.getErrorMessage()); + } + NamedCompound compound = new NamedCompound(Localization.lang("source edit")); BibEntry newEntry = database.getEntries().get(0); String newKey = newEntry.getCiteKeyOptional().orElse(null); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java index 06accaed956..db4bffee679 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.regex.Pattern; import org.jabref.logic.bibtex.FieldContentParser; import org.jabref.logic.exporter.BibtexDatabaseWriter; @@ -70,7 +71,7 @@ public class BibtexParser implements Parser { private boolean eof; private int line = 1; private ParserResult parserResult; - private MetaDataParser metaDataParser; + private final MetaDataParser metaDataParser; public BibtexParser(ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor) { this.importFormatPreferences = Objects.requireNonNull(importFormatPreferences); @@ -211,9 +212,20 @@ private ParserResult parseFileContent() throws IOException { parseRemainingContent(); + checkEpilog(); + return parserResult; } + private void checkEpilog() { + // This is an incomplete and inaccurate try to verify if something went wrong with previous parsing activity even though there were no warnings so far + // regex looks for something like 'identifier = blabla ,' + if (!parserResult.hasWarnings() && Pattern.compile("\\w+\\s*=.*,").matcher(database.getEpilog()).find()) { + parserResult.addWarning("following BibTex fragment has not been parsed:\n" + database.getEpilog()); + } + + } + private void parseRemainingContent() { database.setEpilog(dumpTextReadSoFarToString().trim()); } diff --git a/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java b/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java index 48bf1243fc7..df3012e67ad 100644 --- a/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java +++ b/src/test/java/org/jabref/gui/entryeditor/SourceTabTest.java @@ -6,6 +6,7 @@ import javafx.scene.control.TabPane; import javafx.stage.Stage; +import org.jabref.gui.FXDialogService; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.logic.bibtex.LatexFieldFormatterPreferences; import org.jabref.logic.importer.ImportFormatPreferences; @@ -35,7 +36,7 @@ public class SourceTabTest { public void onStart(Stage stage) { area = new CodeArea(); area.appendText("some example\n text to go here\n across a couple of \n lines...."); - sourceTab = new SourceTab(new BibDatabaseContext(), new CountingUndoManager(), new LatexFieldFormatterPreferences(), mock(ImportFormatPreferences.class), new DummyFileUpdateMonitor()); + sourceTab = new SourceTab(new BibDatabaseContext(), new CountingUndoManager(), new LatexFieldFormatterPreferences(), mock(ImportFormatPreferences.class), new DummyFileUpdateMonitor(), new FXDialogService()); pane = new TabPane( new Tab("main area", area), new Tab("other tab", new Label("some text")),