From a0d6f729f418eaffb568fa83019206d9fdea48e1 Mon Sep 17 00:00:00 2001 From: Anders Blomqvist Date: Fri, 1 Mar 2024 13:46:48 +0100 Subject: [PATCH 01/25] [Copy] Include string constants in copy (#11) Signed-off-by: Anders Blomqvist --- .../java/org/jabref/gui/maintable/MainTable.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index e778fa13425..acfa2100c9e 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -51,6 +51,7 @@ import org.jabref.model.database.event.EntriesAddedEvent; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.entry.BibtexString; import org.jabref.model.util.FileUpdateMonitor; import org.jabref.preferences.PreferencesService; @@ -257,8 +258,14 @@ public void copy() { List selectedEntries = getSelectedEntries(); if (!selectedEntries.isEmpty()) { + List stringConstants = getStringValues(); + try { - clipBoardManager.setContent(selectedEntries, entryTypesManager); + if (!stringConstants.isEmpty()) { + clipBoardManager.setContent(selectedEntries, entryTypesManager, stringConstants); + } else { + clipBoardManager.setContent(selectedEntries, entryTypesManager); + } dialogService.notify(Localization.lang("Copied %0 entry(ies)", selectedEntries.size())); } catch (IOException e) { LOGGER.error("Error while copying selected entries to clipboard.", e); @@ -489,4 +496,11 @@ private Optional findEntry(BibEntry entry) { .filter(viewModel -> viewModel.getEntry().equals(entry)) .findFirst(); } + + private List getStringValues() { + return database.getDatabase() + .getStringValues() + .stream() + .toList(); + } } From 5e98a050b10abc0a9d2007e58be1e644feb86da8 Mon Sep 17 00:00:00 2001 From: Anders Blomqvist Date: Fri, 1 Mar 2024 13:47:20 +0100 Subject: [PATCH 02/25] [Copy] New method for serializing string constants (#12) Signed-off-by: Anders Blomqvist --- .../java/org/jabref/gui/ClipBoardManager.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index 792c4733384..8b292853d1d 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -21,6 +21,7 @@ import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.entry.BibtexString; import org.jabref.preferences.PreferencesService; import org.slf4j.Logger; @@ -165,4 +166,19 @@ public void setContent(List entries, BibEntryTypesManager entryTypesMa clipboard.setContent(content); setPrimaryClipboardContent(content); } + + public void setContent(List entries, BibEntryTypesManager entryTypesManager, List stringConstants) throws IOException { + final ClipboardContent content = new ClipboardContent(); + BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); + StringBuilder builder = new StringBuilder(); + stringConstants.forEach(strConst -> builder.append(strConst.getParsedSerialization())); + String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); + builder.append(serializedEntries); + // BibEntry is not Java serializable. Thus, we need to do the serialization manually + // At reading of the clipboard in JabRef, we parse the plain string in all cases, so we don't need to flag we put BibEntries here + // Furthermore, storing a string also enables other applications to work with the data + content.putString(builder.toString()); + clipboard.setContent(content); + setPrimaryClipboardContent(content); + } } From 4dc86bbbbab442d6441188997e11945144dc6c4c Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Fri, 1 Mar 2024 18:52:58 +0100 Subject: [PATCH 03/25] Add a sanity check for null for clipboard content Currenlty, the clipboard content can be null since the database does not seem to be updating. This is a sanity check to prevent the program from adding null to the clipboard. Link to DD2480-Group1/jabref#13 --- src/main/java/org/jabref/gui/ClipBoardManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index 8b292853d1d..4adaca84236 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -171,7 +171,11 @@ public void setContent(List entries, BibEntryTypesManager entryTypesMa final ClipboardContent content = new ClipboardContent(); BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); StringBuilder builder = new StringBuilder(); - stringConstants.forEach(strConst -> builder.append(strConst.getParsedSerialization())); + for (BibtexString strConst : stringConstants) { + if (strConst.getParsedSerialization() != null) { + builder.append(strConst.getParsedSerialization()); + } + } String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); builder.append(serializedEntries); // BibEntry is not Java serializable. Thus, we need to do the serialization manually From 765cb0e0fa1f6ed3ec5fec7d2948da6021ddd01a Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Fri, 1 Mar 2024 20:25:28 +0100 Subject: [PATCH 04/25] [Fix] Add parsed serilization when save settings When loading from existing files or libraries, the parser will set the serilization of the string constant to the correct value. However, when editing via the GUI, the serilization was not set and a new string constant list will be created without the serilization. This result in the serilization being null and when copying with the clipboard. Link to DD2480-Group1/jabref#13 --- .../constants/ConstantsPropertiesViewModel.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java index 36f4ddeff07..6241508f34f 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java @@ -1,6 +1,7 @@ package org.jabref.gui.libraryproperties.constants; import java.util.Comparator; +import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; @@ -86,9 +87,12 @@ private ConstantsItemModel convertFromBibTexString(BibtexString bibtexString) { @Override public void storeSettings() { - databaseContext.getDatabase().setStrings(stringsListProperty.stream() - .map(this::fromBibtexStringViewModel) - .collect(Collectors.toList())); + List strings = stringsListProperty.stream() + .map(this::fromBibtexStringViewModel) + .toList(); + strings.forEach(string -> string.setParsedSerialization("@String{" + + string.getName() + " = " + string.getContent() + "}\n")); + databaseContext.getDatabase().setStrings(strings); } private BibtexString fromBibtexStringViewModel(ConstantsItemModel viewModel) { From 5129ae9afbe27374f0df4e4393901166138bb782 Mon Sep 17 00:00:00 2001 From: Hannes Stig Date: Sun, 3 Mar 2024 05:07:09 +0100 Subject: [PATCH 05/25] feat: import string constants when pasting #9 Add functionality to import string constants in the paste function Should add functionality to handle colliding string constants. Should also check that the constants are valid using the ConstantsItemModel class. --- .../gui/externalfiles/ImportHandler.java | 21 ++++++++++++++++++- .../importer/fileformat/BibtexParser.java | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 18ac20841ee..e936b697d48 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -40,7 +40,9 @@ import org.jabref.logic.util.io.FileUtil; import org.jabref.model.FieldChange; import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.database.KeyCollisionException; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexString; import org.jabref.model.entry.LinkedFile; import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.identifier.ArXivIdentifier; @@ -311,13 +313,30 @@ private void generateKeys(List entries) { public List handleBibTeXData(String entries) { BibtexParser parser = new BibtexParser(preferencesService.getImportFormatPreferences(), fileUpdateMonitor); try { - return parser.parseEntries(new ByteArrayInputStream(entries.getBytes(StandardCharsets.UTF_8))); + List result = parser.parseEntries(new ByteArrayInputStream(entries.getBytes(StandardCharsets.UTF_8))); + List stringConstants = parser.getStringValues(); + importStringConstantsWithDuplicateCheck(stringConstants); + return result; } catch (ParseException ex) { LOGGER.error("Could not paste", ex); return Collections.emptyList(); } } + public void importStringConstantsWithDuplicateCheck(List stringConstants) { + for(BibtexString stringConstantToAdd : stringConstants) { + try { + bibDatabaseContext.getDatabase().addString(stringConstantToAdd); + } catch (KeyCollisionException ex) { + LOGGER.debug("Collision when inserting constants"); + // TODO: Handle collision with merge window. + + // TODO: Use ConstantsItemModel(?) to validate string constants + // In the same way as when adding them manually in library properties + } + } + } + public List handleStringData(String data) throws FetcherException { if ((data == null) || data.isEmpty()) { return Collections.emptyList(); 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 0a32dd95989..33cb3f6ba7f 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java @@ -117,6 +117,10 @@ public List parseEntries(InputStream inputStream) throws ParseExceptio } } + public List getStringValues() { + return database.getStringValues().stream().toList(); + } + public Optional parseSingleEntry(String bibtexString) throws ParseException { return parseEntries(bibtexString).stream().findFirst(); } From dd821b94f903d0cb195f37b0a98ed0d5632cc351 Mon Sep 17 00:00:00 2001 From: Hannes Stig Date: Sun, 3 Mar 2024 22:39:01 +0100 Subject: [PATCH 06/25] feat: Add string constant validity checker and dialog messages #9 Check that a pasted string constant is valid using the ConstantsItemModel class. Add diagnostic messages notifying users when adding a string constant fails while pasting. --- .../jabref/gui/externalfiles/ImportHandler.java | 14 ++++++++------ src/main/resources/l10n/JabRef_en.properties | 4 ++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index e936b697d48..2a4db4976fe 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -18,6 +18,7 @@ import org.jabref.gui.StateManager; import org.jabref.gui.duplicationFinder.DuplicateResolverDialog; import org.jabref.gui.fieldeditors.LinkedFileViewModel; +import org.jabref.gui.libraryproperties.constants.ConstantsItemModel; import org.jabref.gui.undo.UndoableInsertEntries; import org.jabref.gui.util.BackgroundTask; import org.jabref.gui.util.DefaultTaskExecutor; @@ -326,13 +327,14 @@ public List handleBibTeXData(String entries) { public void importStringConstantsWithDuplicateCheck(List stringConstants) { for(BibtexString stringConstantToAdd : stringConstants) { try { - bibDatabaseContext.getDatabase().addString(stringConstantToAdd); + ConstantsItemModel checker = new ConstantsItemModel(stringConstantToAdd.getName(), stringConstantToAdd.getContent()); + if(checker.combinedValidationValidProperty().get()) { + bibDatabaseContext.getDatabase().addString(stringConstantToAdd); + } else { + dialogService.showErrorDialogAndWait(Localization.lang("Pasted string constant \"%0\" was not added because it is not a valid string constant", stringConstantToAdd.getName())); + } } catch (KeyCollisionException ex) { - LOGGER.debug("Collision when inserting constants"); - // TODO: Handle collision with merge window. - - // TODO: Use ConstantsItemModel(?) to validate string constants - // In the same way as when adding them manually in library properties + dialogService.showErrorDialogAndWait(Localization.lang("Pasted string constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); } } } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 26eb731b57d..e8dff158caf 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2643,3 +2643,7 @@ Source\ URL=Source URL Redownload\ file=Redownload file Redownload\ missing\ files=Redownload missing files Redownload\ missing\ files\ for\ current\ library?=Redownload missing files for current library? + +Pasted\ string\ constant\ "%0"\ was\ not\ added\ because\ it\ is\ not\ a\ valid\ string\ constant=Pasted string constant "%0" was not added because it is not a valid string constant +Pasted\ string\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=Pasted string constant %0 was not imported because it already exists in this library + From 404e7812b497777e0842def47766a2445803a74f Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:47:05 +0100 Subject: [PATCH 07/25] [Copy] Copy referenced constant strings to clipboard (#16) * feat: Add parsed serialized string when cloning * feat: Add sanity check for null in ClipBoardManager * closes #15 --- src/main/java/org/jabref/gui/ClipBoardManager.java | 6 +----- src/main/java/org/jabref/gui/maintable/MainTable.java | 10 +++------- src/main/java/org/jabref/model/entry/BibtexString.java | 3 +++ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index 4adaca84236..197f6f85d4a 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -171,11 +171,7 @@ public void setContent(List entries, BibEntryTypesManager entryTypesMa final ClipboardContent content = new ClipboardContent(); BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); StringBuilder builder = new StringBuilder(); - for (BibtexString strConst : stringConstants) { - if (strConst.getParsedSerialization() != null) { - builder.append(strConst.getParsedSerialization()); - } - } + stringConstants.forEach(strConst -> builder.append(strConst.getParsedSerialization() == null ? "" : strConst.getParsedSerialization())); String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); builder.append(serializedEntries); // BibEntry is not Java serializable. Thus, we need to do the serialization manually diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index acfa2100c9e..230ad5c23e7 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -258,8 +258,7 @@ public void copy() { List selectedEntries = getSelectedEntries(); if (!selectedEntries.isEmpty()) { - List stringConstants = getStringValues(); - + List stringConstants = getUsedStringValues(selectedEntries); try { if (!stringConstants.isEmpty()) { clipBoardManager.setContent(selectedEntries, entryTypesManager, stringConstants); @@ -497,10 +496,7 @@ private Optional findEntry(BibEntry entry) { .findFirst(); } - private List getStringValues() { - return database.getDatabase() - .getStringValues() - .stream() - .toList(); + private List getUsedStringValues(List entries) { + return database.getDatabase().getUsedStrings(entries).stream().toList(); } } diff --git a/src/main/java/org/jabref/model/entry/BibtexString.java b/src/main/java/org/jabref/model/entry/BibtexString.java index d8e83fb6477..3515e0584e9 100644 --- a/src/main/java/org/jabref/model/entry/BibtexString.java +++ b/src/main/java/org/jabref/model/entry/BibtexString.java @@ -158,6 +158,9 @@ public String getUserComments() { public Object clone() { BibtexString clone = new BibtexString(name, content); clone.setId(id); + if (parsedSerialization != null) { + clone.setParsedSerialization(parsedSerialization); + } return clone; } From 7485e1626c97f8a1c11faba969a77454cec1f142 Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 4 Mar 2024 11:43:46 +0100 Subject: [PATCH 08/25] feat: new unit tests Add 4 new unit tests, testing the new features added for issue-10872. Specifically the tests are for the `storeSettings` method in the ConstantsPropertiesViewModel.java, and `setContent` in the ClipBaordManager.java. Closes #6 --- .../org/jabref/gui/ClipBoardManagerTest.java | 133 ++++++++++++++++++ .../ConstantsPropertiesViewModelTest.java | 62 ++++++++ 2 files changed, 195 insertions(+) create mode 100644 src/test/java/org/jabref/gui/ClipBoardManagerTest.java diff --git a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java new file mode 100644 index 00000000000..d9bd263f4ff --- /dev/null +++ b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java @@ -0,0 +1,133 @@ +package org.jabref.gui; + +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.input.Clipboard; + +import org.jabref.architecture.AllowedToUseAwt; +import org.jabref.logic.bibtex.FieldPreferences; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibEntryType; +import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.entry.BibtexString; +import org.jabref.model.entry.field.Field; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.types.StandardEntryType; +import org.jabref.preferences.PreferencesService; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@AllowedToUseAwt("Requires AWT for clipboard access") +public class ClipBoardManagerTest { + + private BibEntryTypesManager entryTypesManager; + private ClipBoardManager clipBoardManager; + + @BeforeEach + void setUp() { + // create preference service mock + PreferencesService preferencesService = mock(PreferencesService.class); + FieldPreferences fieldPreferences = mock(FieldPreferences.class); + List fields = Arrays.asList(StandardField.URL); + ObservableList nonWrappableFields = FXCollections.observableArrayList(fields); + // set up mock behaviours for preferences service + when(fieldPreferences.getNonWrappableFields()).thenReturn(nonWrappableFields); + when(preferencesService.getFieldPreferences()).thenReturn(fieldPreferences); + + // create mock clipboard + Clipboard clipboard = mock(Clipboard.class); + // create primary clipboard and set a temporary value + StringSelection selection = new StringSelection("test"); + java.awt.datatransfer.Clipboard clipboardPrimary = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboardPrimary.setContents(selection, selection); + + // create mock entry manager and set up behaviour for mock + entryTypesManager = mock(BibEntryTypesManager.class); + BibEntryType entryTypeMock = mock(BibEntryType.class); + when(entryTypesManager.enrich(any(), any())).thenReturn(Optional.of(entryTypeMock)); + // initialize a clipBoardManager + clipBoardManager = new ClipBoardManager(clipboard, clipboardPrimary, preferencesService); + } + + @DisplayName("Check that the ClipBoardManager can set a bibentry as its content from the clipboard") + @Test + void testCopyStringBibEntry() throws IOException { + // Arrange + String expected = "@Article{,\n author = {Claudepierre, S. G.},\n journal = {IEEE},\n}"; + + // create BibEntry + BibEntry bibEntry = new BibEntry(); + // construct an entry + bibEntry.setType(StandardEntryType.Article); + bibEntry.setField(StandardField.JOURNAL, "IEEE"); + bibEntry.setField(StandardField.AUTHOR, "Claudepierre, S. G."); + // add entry to list + List bibEntries = new ArrayList<>(); + bibEntries.add(bibEntry); + + // Act + clipBoardManager.setContent(bibEntries, entryTypesManager); + + // Assert + String actual = ClipBoardManager.getContentsPrimary(); + // clean strings + actual = actual.replaceAll("\\s+", " ").trim(); + expected = expected.replaceAll("\\s+", " ").trim(); + + assertEquals(expected, actual); + } + + @Test + @DisplayName("Check that the ClipBoardManager can handle a bibentry with string constants correctly from the clipboard") + void testCopyStringBibEntryWithStringConstants() throws IOException { + // Arrange + String expected = "@String{grl = \"Geophys. Res. Lett.\"}@Article{,\n" + " author = {Claudepierre, S. G.},\n" + + " journal = {grl},\n" + "}"; + // create BibEntry + BibEntry bibEntry = new BibEntry(); + // construct an entry + bibEntry.setType(StandardEntryType.Article); + bibEntry.setField(StandardField.JOURNAL, "grl"); + bibEntry.setField(StandardField.AUTHOR, "Claudepierre, S. G."); + // add entry to list + List bibEntries = new ArrayList<>(); + bibEntries.add(bibEntry); + + // string constants + List constants = new ArrayList<>(); + + // Mock BibtexString + BibtexString bibtexString = mock(BibtexString.class); + + // define return value for getParsedSerialization() + when(bibtexString.getParsedSerialization()).thenReturn("@String{grl = \"Geophys. Res. Lett.\"}"); + // add the constant + constants.add(bibtexString); + + // Act + clipBoardManager.setContent(bibEntries, entryTypesManager, constants); + + // Assert + String actual = ClipBoardManager.getContentsPrimary(); + // clean strings + actual = actual.replaceAll("\\s+", " ").trim(); + expected = expected.replaceAll("\\s+", " ").trim(); + + assertEquals(expected, actual); + } +} diff --git a/src/test/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModelTest.java b/src/test/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModelTest.java index 60311301dee..d7a75a60be3 100644 --- a/src/test/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModelTest.java +++ b/src/test/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModelTest.java @@ -1,6 +1,7 @@ package org.jabref.gui.libraryproperties.constants; import java.util.List; +import java.util.stream.Stream; import javafx.beans.property.StringProperty; @@ -70,4 +71,65 @@ void stringsListPropertyResorting() { assertEquals(expected, actual); } + + @Test + @DisplayName("Check that the storeSettings method store settings on the model") + void storeSettingsTest() { + // Setup + // create a bibdatabse + BibDatabase db = new BibDatabase(); + BibDatabaseContext context = new BibDatabaseContext(db); + List expected = List.of("KTH", "Royal Institute of Technology"); + // initialize a constantsPropertiesViewModel + ConstantsPropertiesViewModel model = new ConstantsPropertiesViewModel(context, service, filePreferences); + + // construct value to store in model + var stringsList = model.stringsListProperty(); + stringsList.add(new ConstantsItemModel("KTH", "Royal Institute of Technology")); + + // Act + model.storeSettings(); + + // Assert + // get the names stored + List names = context.getDatabase().getStringValues().stream() + .map(BibtexString::getName).toList(); + // get the content stored + List content = context.getDatabase().getStringValues().stream() + .map(BibtexString::getContent).toList(); + + List actual = Stream.concat(names.stream(), content.stream()).toList(); + + assertEquals(expected, actual); + } + + @Test + @DisplayName("Check that the storeSettings method can identify string constants") + void storeSettingsWithStringConstantTest() { + // Setup + // create a bibdatabse + BibDatabase db = new BibDatabase(); + BibDatabaseContext context = new BibDatabaseContext(db); + List expected = List.of("@String{KTH = Royal Institute of Technology}"); + // initialize a constantsPropertiesViewModel + ConstantsPropertiesViewModel model = new ConstantsPropertiesViewModel(context, service, filePreferences); + + // construct value to store in model + var stringsList = model.stringsListProperty(); + stringsList.add(new ConstantsItemModel("KTH", "Royal Institute of Technology")); + + // Act + model.storeSettings(); + + // Assert + // get string the constants through parsedSerialization() method + List actual = context.getDatabase().getStringValues().stream() + .map(BibtexString::getParsedSerialization).toList(); + + // get the first value and clean strings + String actual_value = actual.getFirst().replaceAll("\\s+", " ").trim(); + String expected_value = expected.getFirst().replaceAll("\\s+", " ").trim(); + + assertEquals(expected_value, actual_value); + } } From c00ee33c047ab1b2593db1e83a6be6bef2a636b9 Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:36:17 +0100 Subject: [PATCH 09/25] Update CHANGELOG with copy and paste function --- CHANGELOG.md | 1 + buildres/abbrv.jabref.org | 2 +- src/main/resources/csl-styles | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41a596a3abb..ac6f98c6f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We enhanced the dialog for adding new fields in the content selector with a selection box containing a list of standard fields. [#10912](https://github.com/JabRef/jabref/pull/10912) - We store the citation relations in an LRU cache to avoid bloating the memory and out-of-memory exceptions. [#10958](https://github.com/JabRef/jabref/issues/10958) - Keywords filed are now displayed as tags. [#10910](https://github.com/JabRef/jabref/pull/10910) +- When pasting, string constants are automatically added to the library database, while referenced constants are added to the clipboard during copying. [#10872](https://github.com/JabRef/jabref/issues/10872) ### Fixed diff --git a/buildres/abbrv.jabref.org b/buildres/abbrv.jabref.org index 8fbad5a1285..1a8ca63172f 160000 --- a/buildres/abbrv.jabref.org +++ b/buildres/abbrv.jabref.org @@ -1 +1 @@ -Subproject commit 8fbad5a1285926b177803087b35b0eb6b0fd0142 +Subproject commit 1a8ca63172f96b77632810bb726dbc6a2df7ac7e diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index 1bb9097598f..fab696b6f36 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit 1bb9097598f2d85d3e5997702bddc2d73ecfb584 +Subproject commit fab696b6f365a770547df90b84a54691462b7c21 From 7a53d8a29b05bc188ed22b1bbf3e74517cdefd5b Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:21:00 +0100 Subject: [PATCH 10/25] Fix Checkstyle failing by reformat the code --- src/main/java/org/jabref/gui/externalfiles/ImportHandler.java | 4 ++-- .../constants/ConstantsPropertiesViewModel.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 2a4db4976fe..f0ce9a34c37 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -325,10 +325,10 @@ public List handleBibTeXData(String entries) { } public void importStringConstantsWithDuplicateCheck(List stringConstants) { - for(BibtexString stringConstantToAdd : stringConstants) { + for (BibtexString stringConstantToAdd : stringConstants) { try { ConstantsItemModel checker = new ConstantsItemModel(stringConstantToAdd.getName(), stringConstantToAdd.getContent()); - if(checker.combinedValidationValidProperty().get()) { + if (checker.combinedValidationValidProperty().get()) { bibDatabaseContext.getDatabase().addString(stringConstantToAdd); } else { dialogService.showErrorDialogAndWait(Localization.lang("Pasted string constant \"%0\" was not added because it is not a valid string constant", stringConstantToAdd.getName())); diff --git a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java index 6241508f34f..62de209074c 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Locale; import java.util.Optional; -import java.util.stream.Collectors; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ListProperty; From bae8338cd2b437ac3d9d313e194adfe0bfa23df9 Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:33:30 +0100 Subject: [PATCH 11/25] Fix OpenRewrite failing by running rewriteRun --- src/test/java/org/jabref/gui/ClipBoardManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java index d9bd263f4ff..08555035686 100644 --- a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java +++ b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java @@ -66,7 +66,7 @@ void setUp() { @DisplayName("Check that the ClipBoardManager can set a bibentry as its content from the clipboard") @Test - void testCopyStringBibEntry() throws IOException { + void copyStringBibEntry() throws IOException { // Arrange String expected = "@Article{,\n author = {Claudepierre, S. G.},\n journal = {IEEE},\n}"; @@ -94,7 +94,7 @@ void testCopyStringBibEntry() throws IOException { @Test @DisplayName("Check that the ClipBoardManager can handle a bibentry with string constants correctly from the clipboard") - void testCopyStringBibEntryWithStringConstants() throws IOException { + void copyStringBibEntryWithStringConstants() throws IOException { // Arrange String expected = "@String{grl = \"Geophys. Res. Lett.\"}@Article{,\n" + " author = {Claudepierre, S. G.},\n" + " journal = {grl},\n" + "}"; From c3ffd8bededbc142794c044be4e06c35054518bc Mon Sep 17 00:00:00 2001 From: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:34:10 +0100 Subject: [PATCH 12/25] Refactor by extract methods in setContent --- .../java/org/jabref/gui/ClipBoardManager.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index 197f6f85d4a..f90dc1b0f36 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -156,29 +156,23 @@ public void setContent(String string) { } public void setContent(List entries, BibEntryTypesManager entryTypesManager) throws IOException { - final ClipboardContent content = new ClipboardContent(); - BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); - String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); - // BibEntry is not Java serializable. Thus, we need to do the serialization manually - // At reading of the clipboard in JabRef, we parse the plain string in all cases, so we don't need to flag we put BibEntries here - // Furthermore, storing a string also enables other applications to work with the data - content.putString(serializedEntries); - clipboard.setContent(content); - setPrimaryClipboardContent(content); + String serializedEntries = serializeEntries(entries, entryTypesManager); + setContent(serializedEntries); } public void setContent(List entries, BibEntryTypesManager entryTypesManager, List stringConstants) throws IOException { - final ClipboardContent content = new ClipboardContent(); - BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); StringBuilder builder = new StringBuilder(); stringConstants.forEach(strConst -> builder.append(strConst.getParsedSerialization() == null ? "" : strConst.getParsedSerialization())); - String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); + String serializedEntries = serializeEntries(entries, entryTypesManager); builder.append(serializedEntries); + setContent(builder.toString()); + } + + private String serializeEntries(List entries, BibEntryTypesManager entryTypesManager) throws IOException { // BibEntry is not Java serializable. Thus, we need to do the serialization manually // At reading of the clipboard in JabRef, we parse the plain string in all cases, so we don't need to flag we put BibEntries here // Furthermore, storing a string also enables other applications to work with the data - content.putString(builder.toString()); - clipboard.setContent(content); - setPrimaryClipboardContent(content); + BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager); + return writer.serializeAll(entries, BibDatabaseMode.BIBTEX); } } From 1030d344e8d37cbc0592c7638250837c75dc2aac Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 17 Mar 2024 20:12:12 +0100 Subject: [PATCH 13/25] collet failures --- .../org/jabref/gui/externalfiles/ImportHandler.java | 11 ++++++++--- src/main/resources/l10n/JabRef_en.properties | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index f0ce9a34c37..43420a962d8 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -325,18 +325,23 @@ public List handleBibTeXData(String entries) { } public void importStringConstantsWithDuplicateCheck(List stringConstants) { + List failures = new ArrayList<>(); + for (BibtexString stringConstantToAdd : stringConstants) { try { ConstantsItemModel checker = new ConstantsItemModel(stringConstantToAdd.getName(), stringConstantToAdd.getContent()); if (checker.combinedValidationValidProperty().get()) { bibDatabaseContext.getDatabase().addString(stringConstantToAdd); } else { - dialogService.showErrorDialogAndWait(Localization.lang("Pasted string constant \"%0\" was not added because it is not a valid string constant", stringConstantToAdd.getName())); + failures.add(Localization.lang("String constant \"%0\" was not imported because it is not a valid string constant", stringConstantToAdd.getName())); } } catch (KeyCollisionException ex) { - dialogService.showErrorDialogAndWait(Localization.lang("Pasted string constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); + failures.add(Localization.lang("String constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); } } + if(! failures.isEmpty()){ + dialogService.showErrorDialogAndWait(Localization.lang("Could not import the following string constants:\n %0", String.join("\n", failures))); + } } public List handleStringData(String data) throws FetcherException { @@ -377,7 +382,7 @@ private List tryImportFormats(String data) { } private List fetchByDOI(DOI doi) throws FetcherException { - LOGGER.info("Found DOI identifer in clipboard"); + LOGGER.info("Found DOI identifier in clipboard"); Optional entry = new DoiFetcher(preferencesService.getImportFormatPreferences()).performSearchById(doi.getDOI()); return OptionalUtil.toList(entry); } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index edf020e74ea..cdf95fe51ff 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2647,6 +2647,7 @@ Redownload\ file=Redownload file Redownload\ missing\ files=Redownload missing files Redownload\ missing\ files\ for\ current\ library?=Redownload missing files for current library? -Pasted\ string\ constant\ "%0"\ was\ not\ added\ because\ it\ is\ not\ a\ valid\ string\ constant=Pasted string constant "%0" was not added because it is not a valid string constant -Pasted\ string\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=Pasted string constant %0 was not imported because it already exists in this library +String\ constant\ "%0"\ was\ not\ imported\ because\ it\ is\ not\ a\ valid\ string\ constant=String constant "%0" was not imported because it is not a valid string constant +String\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=String constant %0 was not imported because it already exists in this library +Could\ not\ import\ the\ following\ string\ constants\:\n\ %0=Could not import the following string constants:\n %0 From 15746c0902d070915c105de089165ceab5ced3e9 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 17 Mar 2024 20:34:21 +0100 Subject: [PATCH 14/25] changelog and use os.newline --- CHANGELOG.md | 1 + src/main/java/org/jabref/gui/externalfiles/ImportHandler.java | 4 ++-- .../constants/ConstantsPropertiesViewModel.java | 3 ++- src/main/resources/l10n/JabRef_en.properties | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f9d41546e..906d523e2fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We added the ability to zoom in and out in the document viewer using Ctrl + Scroll. [#10964](https://github.com/JabRef/jabref/pull/10964) - We added a Cleanup for removing non-existent files and grouped the related options [#10929](https://github.com/JabRef/jabref/issues/10929) - We added the functionality to parse the bibliography of PDFs using the GROBID online service. [#10200](https://github.com/JabRef/jabref/issues/10200) +- We added support for BibTeX String constants during copy & paste between libraries [#10872](https://github.com/JabRef/jabref/issues/10872) ### Changed diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 43420a962d8..23cbb0aaf5b 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -339,8 +339,8 @@ public void importStringConstantsWithDuplicateCheck(List stringCon failures.add(Localization.lang("String constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); } } - if(! failures.isEmpty()){ - dialogService.showErrorDialogAndWait(Localization.lang("Could not import the following string constants:\n %0", String.join("\n", failures))); + if(!failures.isEmpty()){ + dialogService.showWarningDialogAndWait(Localization.lang("Importing String constants"),Localization.lang("Could not import the following string constants:\n %0", String.join("\n", failures))); } } diff --git a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java index 62de209074c..aca91dced46 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java @@ -18,6 +18,7 @@ import org.jabref.gui.libraryproperties.PropertiesTabViewModel; import org.jabref.logic.bibtex.comparator.BibtexStringComparator; import org.jabref.logic.help.HelpFile; +import org.jabref.logic.util.OS; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibtexString; import org.jabref.preferences.FilePreferences; @@ -90,7 +91,7 @@ public void storeSettings() { .map(this::fromBibtexStringViewModel) .toList(); strings.forEach(string -> string.setParsedSerialization("@String{" + - string.getName() + " = " + string.getContent() + "}\n")); + string.getName() + " = " + string.getContent() + "}"+ OS.NEWLINE)); databaseContext.getDatabase().setStrings(strings); } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index cdf95fe51ff..e3a3602823a 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2650,4 +2650,5 @@ Redownload\ missing\ files\ for\ current\ library?=Redownload missing files for String\ constant\ "%0"\ was\ not\ imported\ because\ it\ is\ not\ a\ valid\ string\ constant=String constant "%0" was not imported because it is not a valid string constant String\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=String constant %0 was not imported because it already exists in this library Could\ not\ import\ the\ following\ string\ constants\:\n\ %0=Could not import the following string constants:\n %0 +Importing\ String\ constants=Importing String constants From f58283c198fda6c834894bb3677f28ac7cc415bd Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 17 Mar 2024 20:38:01 +0100 Subject: [PATCH 15/25] checkstyle --- .../java/org/jabref/gui/externalfiles/ImportHandler.java | 6 +++--- .../constants/ConstantsPropertiesViewModel.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 23cbb0aaf5b..66fb6617fa6 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -336,11 +336,11 @@ public void importStringConstantsWithDuplicateCheck(List stringCon failures.add(Localization.lang("String constant \"%0\" was not imported because it is not a valid string constant", stringConstantToAdd.getName())); } } catch (KeyCollisionException ex) { - failures.add(Localization.lang("String constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); + failures.add(Localization.lang("String constant %0 was not imported because it already exists in this library", stringConstantToAdd.getName())); } } - if(!failures.isEmpty()){ - dialogService.showWarningDialogAndWait(Localization.lang("Importing String constants"),Localization.lang("Could not import the following string constants:\n %0", String.join("\n", failures))); + if (!failures.isEmpty()) { + dialogService.showWarningDialogAndWait(Localization.lang("Importing String constants"), Localization.lang("Could not import the following string constants:\n %0", String.join("\n", failures))); } } diff --git a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java index aca91dced46..f29079199c8 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/constants/ConstantsPropertiesViewModel.java @@ -88,10 +88,10 @@ private ConstantsItemModel convertFromBibTexString(BibtexString bibtexString) { @Override public void storeSettings() { List strings = stringsListProperty.stream() - .map(this::fromBibtexStringViewModel) - .toList(); + .map(this::fromBibtexStringViewModel) + .toList(); strings.forEach(string -> string.setParsedSerialization("@String{" + - string.getName() + " = " + string.getContent() + "}"+ OS.NEWLINE)); + string.getName() + " = " + string.getContent() + "}" + OS.NEWLINE)); databaseContext.getDatabase().setStrings(strings); } From 7244e8b892eac765a1ebfeff03969c1b5b545748 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sun, 17 Mar 2024 21:20:07 +0100 Subject: [PATCH 16/25] use real bibentrytypes manager --- .../java/org/jabref/gui/ClipBoardManagerTest.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java index 08555035686..087e6573b9d 100644 --- a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java +++ b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java @@ -4,9 +4,7 @@ import java.awt.datatransfer.StringSelection; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Optional; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -15,7 +13,6 @@ import org.jabref.architecture.AllowedToUseAwt; import org.jabref.logic.bibtex.FieldPreferences; import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.BibEntryType; import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.entry.BibtexString; import org.jabref.model.entry.field.Field; @@ -28,7 +25,6 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -43,7 +39,7 @@ void setUp() { // create preference service mock PreferencesService preferencesService = mock(PreferencesService.class); FieldPreferences fieldPreferences = mock(FieldPreferences.class); - List fields = Arrays.asList(StandardField.URL); + List fields = List.of(StandardField.URL); ObservableList nonWrappableFields = FXCollections.observableArrayList(fields); // set up mock behaviours for preferences service when(fieldPreferences.getNonWrappableFields()).thenReturn(nonWrappableFields); @@ -57,9 +53,8 @@ void setUp() { clipboardPrimary.setContents(selection, selection); // create mock entry manager and set up behaviour for mock - entryTypesManager = mock(BibEntryTypesManager.class); - BibEntryType entryTypeMock = mock(BibEntryType.class); - when(entryTypesManager.enrich(any(), any())).thenReturn(Optional.of(entryTypeMock)); + entryTypesManager = new BibEntryTypesManager(); + // initialize a clipBoardManager clipBoardManager = new ClipBoardManager(clipboard, clipboardPrimary, preferencesService); } From 404e4a24f74b1b3d9fa91da8fa757fd896a0e3ce Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:31:51 +0100 Subject: [PATCH 17/25] Fix CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 906d523e2fa..b0d664c8dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,6 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We enhanced the dialog for adding new fields in the content selector with a selection box containing a list of standard fields. [#10912](https://github.com/JabRef/jabref/pull/10912) - We store the citation relations in an LRU cache to avoid bloating the memory and out-of-memory exceptions. [#10958](https://github.com/JabRef/jabref/issues/10958) - Keywords filed are now displayed as tags. [#10910](https://github.com/JabRef/jabref/pull/10910) -- When pasting, string constants are automatically added to the library database, while referenced constants are added to the clipboard during copying. [#10872](https://github.com/JabRef/jabref/issues/10872) ### Fixed From 8b4220aa6d8149ac4198594d2ecc57a6bbe3f6cf Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:36:21 +0100 Subject: [PATCH 18/25] Swap if branches --- src/main/java/org/jabref/gui/maintable/MainTable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index 230ad5c23e7..ac4b707e723 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -260,10 +260,10 @@ public void copy() { if (!selectedEntries.isEmpty()) { List stringConstants = getUsedStringValues(selectedEntries); try { - if (!stringConstants.isEmpty()) { - clipBoardManager.setContent(selectedEntries, entryTypesManager, stringConstants); - } else { + if (stringConstants.isEmpty()) { clipBoardManager.setContent(selectedEntries, entryTypesManager); + } else { + clipBoardManager.setContent(selectedEntries, entryTypesManager, stringConstants); } dialogService.notify(Localization.lang("Copied %0 entry(ies)", selectedEntries.size())); } catch (IOException e) { From fa28472f5aa38dc7c611a2e84375a20e4e5318ed Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:40:43 +0100 Subject: [PATCH 19/25] Code cleanup --- .../java/org/jabref/model/database/BibDatabase.java | 7 +------ .../org/jabref/model/database/BibDatabaseTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/model/database/BibDatabase.java b/src/main/java/org/jabref/model/database/BibDatabase.java index 12f1ba3f08b..51ab5b7074b 100644 --- a/src/main/java/org/jabref/model/database/BibDatabase.java +++ b/src/main/java/org/jabref/model/database/BibDatabase.java @@ -371,7 +371,6 @@ public String resolveForStrings(String content) { * Get all strings used in the entries. */ public Collection getUsedStrings(Collection entries) { - List result = new ArrayList<>(); Set allUsedIds = new HashSet<>(); // All entries @@ -386,11 +385,7 @@ public Collection getUsedStrings(Collection entries) { resolveContent(preamble, new HashSet<>(), allUsedIds); } - for (String stringId : allUsedIds) { - result.add((BibtexString) bibtexStrings.get(stringId).clone()); - } - - return result; + return allUsedIds.stream().map(bibtexStrings::get).toList(); } /** diff --git a/src/test/java/org/jabref/model/database/BibDatabaseTest.java b/src/test/java/org/jabref/model/database/BibDatabaseTest.java index 28e9db06298..e904015354a 100644 --- a/src/test/java/org/jabref/model/database/BibDatabaseTest.java +++ b/src/test/java/org/jabref/model/database/BibDatabaseTest.java @@ -392,8 +392,8 @@ void resolveForStringsOddHashMarkAtTheEnd() { @Test void getUsedStrings() { - BibEntry entry = new BibEntry(); - entry.setField(StandardField.AUTHOR, "#AAA#"); + BibEntry entry = new BibEntry() + .withField(StandardField.AUTHOR, "#AAA#"); BibtexString tripleA = new BibtexString("AAA", "Some other #BBB#"); BibtexString tripleB = new BibtexString("BBB", "Some more text"); BibtexString tripleC = new BibtexString("CCC", "Even more text"); @@ -412,8 +412,8 @@ void getUsedStrings() { @Test void getUsedStringsSingleString() { - BibEntry entry = new BibEntry(); - entry.setField(StandardField.AUTHOR, "#AAA#"); + BibEntry entry = new BibEntry() + .withField(StandardField.AUTHOR, "#AAA#"); BibtexString tripleA = new BibtexString("AAA", "Some other text"); BibtexString tripleB = new BibtexString("BBB", "Some more text"); List strings = new ArrayList<>(1); @@ -429,8 +429,8 @@ void getUsedStringsSingleString() { @Test void getUsedStringsNoString() { - BibEntry entry = new BibEntry(); - entry.setField(StandardField.AUTHOR, "Oscar Gustafsson"); + BibEntry entry = new BibEntry() + .withField(StandardField.AUTHOR, "Oscar Gustafsson"); BibtexString string = new BibtexString("AAA", "Some other text"); database.addString(string); database.insertEntry(entry); From ccc0a84c13cf9c31affa10333bdaf229bd03ce74 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:42:22 +0100 Subject: [PATCH 20/25] Use List for getUsedStringValues --- .../java/org/jabref/gui/maintable/MainTable.java | 2 +- .../java/org/jabref/model/database/BibDatabase.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index ac4b707e723..eb460dd0e94 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -497,6 +497,6 @@ private Optional findEntry(BibEntry entry) { } private List getUsedStringValues(List entries) { - return database.getDatabase().getUsedStrings(entries).stream().toList(); + return database.getDatabase().getUsedStrings(entries); } } diff --git a/src/main/java/org/jabref/model/database/BibDatabase.java b/src/main/java/org/jabref/model/database/BibDatabase.java index 51ab5b7074b..221e8334399 100644 --- a/src/main/java/org/jabref/model/database/BibDatabase.java +++ b/src/main/java/org/jabref/model/database/BibDatabase.java @@ -370,9 +370,14 @@ public String resolveForStrings(String content) { /** * Get all strings used in the entries. */ - public Collection getUsedStrings(Collection entries) { + public List getUsedStrings(Collection entries) { Set allUsedIds = new HashSet<>(); + // Preamble + if (preamble != null) { + resolveContent(preamble, new HashSet<>(), allUsedIds); + } + // All entries for (BibEntry entry : entries) { for (String fieldContent : entry.getFieldValues()) { @@ -380,11 +385,6 @@ public Collection getUsedStrings(Collection entries) { } } - // Preamble - if (preamble != null) { - resolveContent(preamble, new HashSet<>(), allUsedIds); - } - return allUsedIds.stream().map(bibtexStrings::get).toList(); } From e81d5c0e857025a7806350ce1c8e3473f0710fe7 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:43:43 +0100 Subject: [PATCH 21/25] Fix submodule --- buildres/abbrv.jabref.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildres/abbrv.jabref.org b/buildres/abbrv.jabref.org index 1a8ca63172f..8fbad5a1285 160000 --- a/buildres/abbrv.jabref.org +++ b/buildres/abbrv.jabref.org @@ -1 +1 @@ -Subproject commit 1a8ca63172f96b77632810bb726dbc6a2df7ac7e +Subproject commit 8fbad5a1285926b177803087b35b0eb6b0fd0142 From 40d6f02261fdeb357c21dd18b1e1aaaadc537aa9 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:47:33 +0100 Subject: [PATCH 22/25] Collection is better --- src/main/java/org/jabref/gui/externalfiles/ImportHandler.java | 4 ++-- .../org/jabref/logic/importer/fileformat/BibtexParser.java | 4 ++-- src/main/java/org/jabref/model/database/BibDatabase.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 66fb6617fa6..b7fffe46b7f 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -315,7 +315,7 @@ public List handleBibTeXData(String entries) { BibtexParser parser = new BibtexParser(preferencesService.getImportFormatPreferences(), fileUpdateMonitor); try { List result = parser.parseEntries(new ByteArrayInputStream(entries.getBytes(StandardCharsets.UTF_8))); - List stringConstants = parser.getStringValues(); + Collection stringConstants = parser.getStringValues(); importStringConstantsWithDuplicateCheck(stringConstants); return result; } catch (ParseException ex) { @@ -324,7 +324,7 @@ public List handleBibTeXData(String entries) { } } - public void importStringConstantsWithDuplicateCheck(List stringConstants) { + public void importStringConstantsWithDuplicateCheck(Collection stringConstants) { List failures = new ArrayList<>(); for (BibtexString stringConstantToAdd : stringConstants) { 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 deb32598663..7669712a465 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java @@ -144,8 +144,8 @@ public List parseEntries(InputStream inputStream) throws ParseExceptio } } - public List getStringValues() { - return database.getStringValues().stream().toList(); + public Collection getStringValues() { + return database.getStringValues(); } public Optional parseSingleEntry(String bibtexString) throws ParseException { diff --git a/src/main/java/org/jabref/model/database/BibDatabase.java b/src/main/java/org/jabref/model/database/BibDatabase.java index 221e8334399..b28f6cc6398 100644 --- a/src/main/java/org/jabref/model/database/BibDatabase.java +++ b/src/main/java/org/jabref/model/database/BibDatabase.java @@ -454,7 +454,7 @@ private String resolveString(String label, Set usedIds, Set allU // circular reference, and have to stop to avoid // infinite recursion. if (usedIds.contains(string.getId())) { - LOGGER.info("Stopped due to circular reference in strings: " + label); + LOGGER.info("Stopped due to circular reference in strings: {}", label); return label; } // If not, log this string's ID now. From abefd5fd219b6d3937c2b0bbc857eb46667374d1 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:49:36 +0100 Subject: [PATCH 23/25] Fix csl-styles --- src/main/resources/csl-styles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index 5c999d60196..713bf5738ac 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit 5c999d6019645fc48ae0ac07c8c5d462c767914f +Subproject commit 713bf5738ac0b13c502e364cded9445c48d18193 From b0b7e90a1a744d3146178b37e5c2e23918782716 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:56:02 +0100 Subject: [PATCH 24/25] Remove empty line --- src/main/java/org/jabref/gui/edit/ReplaceStringAction.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/edit/ReplaceStringAction.java b/src/main/java/org/jabref/gui/edit/ReplaceStringAction.java index 8339b5db7f3..3a7ba00795c 100644 --- a/src/main/java/org/jabref/gui/edit/ReplaceStringAction.java +++ b/src/main/java/org/jabref/gui/edit/ReplaceStringAction.java @@ -15,7 +15,6 @@ public class ReplaceStringAction extends SimpleCommand { public ReplaceStringAction(Supplier tabSupplier, StateManager stateManager, DialogService dialogService) { this.tabSupplier = tabSupplier; this.dialogService = dialogService; - this.executable.bind(ActionHelper.needsDatabase(stateManager)); } From dcef84e9ea8e766811c6aa6b35f1bf3351d5c46b Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 18 Mar 2024 10:56:51 +0100 Subject: [PATCH 25/25] Group BibTeX string l10n together --- src/main/resources/l10n/JabRef_en.properties | 63 ++++++++------------ 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index e3a3602823a..d72fceb0f63 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -60,6 +60,30 @@ Added\ group\ "%0".=Added group "%0". Added\ string\:\ '%0'=Added string: '%0' Added\ string=Added string +Edit\ strings=Edit strings +Duplicate\ string\ name=Duplicate string name +Modified\ string=Modified string +Modified\ string\:\ '%0' =Modified string: '%0' +New\ string=New string +Remove\ string\ %0=Remove string %0 +Deleted\ string=Deleted string +Deleted\ string\:\ '%0'=Deleted string: '%0' +Renamed\ string\:\ '%0'=Renamed string: '%0' +Please\ enter\ the\ string's\ label=Please enter the string's label +Resolve\ BibTeX\ strings=Resolve BibTeX strings +The\ label\ of\ the\ string\ cannot\ be\ a\ number.=The label of the string cannot be a number. +The\ label\ of\ the\ string\ cannot\ contain\ spaces.=The label of the string cannot contain spaces. +The\ label\ of\ the\ string\ cannot\ contain\ the\ '\#'\ character.=The label of the string cannot contain the '#' character. +String\ dialog,\ add\ string=String dialog, add string +String\ dialog,\ remove\ string=String dialog, remove string +Add\ new\ String=Add new String +String\ constants=String constants +Must\ not\ be\ empty\!=Must not be empty\! +A\ string\ with\ the\ label\ '%0'\ already\ exists.=A string with the label '%0' already exists. +String\ constant\ "%0"\ was\ not\ imported\ because\ it\ is\ not\ a\ valid\ string\ constant=String constant "%0" was not imported because it is not a valid string constant +String\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=String constant %0 was not imported because it already exists in this library +Could\ not\ import\ the\ following\ string\ constants\:\n\ %0=Could not import the following string constants:\n %0 +Importing\ String\ constants=Importing String constants All\ entries=All entries @@ -260,8 +284,6 @@ Duplicate\ fields=Duplicate fields Unable\ to\ change\ field\ name\.\ "%0"\ already\ in\ use.=Unable to change field name. "%0" already in use. -Duplicate\ string\ name=Duplicate string name - Duplicates\ found=Duplicates found Dynamically\ group\ entries\ by\ a\ free-form\ search\ expression=Dynamically group entries by a free-form search expression @@ -276,8 +298,6 @@ Edit\ file\ type=Edit file type Edit\ group=Edit group -Edit\ strings=Edit strings - empty\ library=empty library Autocompletion=Autocompletion @@ -526,9 +546,6 @@ Modified\ group\ "%0".=Modified group "%0". Modified\ groups=Modified groups -Modified\ string=Modified string -Modified\ string\:\ '%0' =Modified string: '%0' - Modify=Modify move\ group=move group @@ -557,8 +574,6 @@ New\ BibTeX\ sublibrary=New BibTeX sublibrary New\ group=New group -New\ string=New string - Next\ entry=Next entry no\ base-BibTeX-file\ specified!=no base-BibTeX-file specified! @@ -631,8 +646,6 @@ File\ has\ no\ attached\ annotations=File has no attached annotations Please\ enter\ a\ name\ for\ the\ group.=Please enter a name for the group. -Please\ enter\ the\ string's\ label=Please enter the string's label - Please\ restart\ JabRef\ for\ preferences\ to\ take\ effect.=Please restart JabRef for preferences to take effect. Possible\ duplicate\ entries=Possible duplicate entries @@ -714,15 +727,8 @@ Remove\ group\ "%0"?=Remove group "%0"? Remove\ link=Remove link -Remove\ string\ %0=Remove string %0 - Removed\ group\ "%0".=Removed group "%0". -Deleted\ string=Deleted string -Deleted\ string\:\ '%0'=Deleted string: '%0' - -Renamed\ string\:\ '%0'=Renamed string: '%0' - Replace=Replace Replace\ With\:=Replace With: Limit\ to\ Selected\ Entries=Limit to Selected Entries @@ -741,8 +747,6 @@ Replaces\ Unicode\ ligatures\ with\ their\ expanded\ form=Replaces Unicode ligat Required\ fields=Required fields -Resolve\ BibTeX\ strings=Resolve BibTeX strings - resolved=resolved Restart=Restart @@ -893,12 +897,6 @@ Switches\ between\ full\ and\ abbreviated\ journal\ name\ if\ the\ journal\ name the\ field\ %0=the field %0 The\ group\ "%0"\ already\ contains\ the\ selection.=The group "%0" already contains the selection. -The\ label\ of\ the\ string\ cannot\ be\ a\ number.=The label of the string cannot be a number. - -The\ label\ of\ the\ string\ cannot\ contain\ spaces.=The label of the string cannot contain spaces. - -The\ label\ of\ the\ string\ cannot\ contain\ the\ '\#'\ character.=The label of the string cannot contain the '#' character. - The\ output\ option\ depends\ on\ a\ valid\ import\ option.=The output option depends on a valid import option. This\ operation\ requires\ all\ selected\ entries\ to\ have\ citation\ keys\ defined.=This operation requires all selected entries to have citation keys defined. @@ -1385,8 +1383,6 @@ Push\ to\ application=Push to application Refresh\ OpenOffice/LibreOffice=Refresh OpenOffice/LibreOffice Resolve\ duplicate\ citation\ keys=Resolve duplicate citation keys Save\ all=Save all -String\ dialog,\ add\ string=String dialog, add string -String\ dialog,\ remove\ string=String dialog, remove string Synchronize\ files=Synchronize files Unabbreviate=Unabbreviate should\ contain\ a\ protocol=should contain a protocol @@ -1978,8 +1974,6 @@ Total\ items\ found\:=Total items found: Selected\ items\:=Selected items: Download\ linked\ online\ files=Download linked online files Select\ the\ entries\ to\ be\ imported\:=Select the entries to be imported\: -Add\ new\ String=Add new String -Must\ not\ be\ empty\!=Must not be empty\! Open\ Help\ page=Open Help page Add\ new\ keyword=Add new keyword Keyword\:=Keyword: @@ -1988,7 +1982,6 @@ Keyword\ separator=Keyword separator Remove\ keyword=Remove keyword Are\ you\ sure\ you\ want\ to\ remove\ keyword\:\ \"%0\"?=Are you sure you want to remove keyword: "%0"? Reset\ to\ default=Reset to default -String\ constants=String constants Export\ all\ entries=Export all entries Generate\ citation\ keys=Generate citation keys New\ library=New library @@ -2008,8 +2001,6 @@ Set\ rank\ to\ three=Set rank to three Set\ rank\ to\ four=Set rank to four Set\ rank\ to\ five=Set rank to five -A\ string\ with\ the\ label\ '%0'\ already\ exists.=A string with the label '%0' already exists. - Executing\ command\ "%0"...=Executing command "%0"... Rename\ file\ to\ a\ given\ name=Rename file to a given name @@ -2646,9 +2637,3 @@ Source\ URL=Source URL Redownload\ file=Redownload file Redownload\ missing\ files=Redownload missing files Redownload\ missing\ files\ for\ current\ library?=Redownload missing files for current library? - -String\ constant\ "%0"\ was\ not\ imported\ because\ it\ is\ not\ a\ valid\ string\ constant=String constant "%0" was not imported because it is not a valid string constant -String\ constant\ %0\ was\ not\ imported\ because\ it\ already\ exists\ in\ this\ library=String constant %0 was not imported because it already exists in this library -Could\ not\ import\ the\ following\ string\ constants\:\n\ %0=Could not import the following string constants:\n %0 -Importing\ String\ constants=Importing String constants -