Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change copy-paste function to handle string constants (follow up PR) #11037

Merged
merged 32 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a0d6f72
[Copy] Include string constants in copy (#11)
andersblomqvist Mar 1, 2024
5e98a05
[Copy] New method for serializing string constants (#12)
andersblomqvist Mar 1, 2024
4dc86bb
Add a sanity check for null for clipboard content
JXNCTED Mar 1, 2024
765cb0e
[Fix] Add parsed serilization when save settings
JXNCTED Mar 1, 2024
ea946c4
Merge pull request #14 from DD2480-Group1/issue-13/null-when-copying
andersblomqvist Mar 2, 2024
5129ae9
feat: import string constants when pasting #9
hanstig Mar 3, 2024
dd821b9
feat: Add string constant validity checker and dialog messages #9
hanstig Mar 3, 2024
404e781
[Copy] Copy referenced constant strings to clipboard (#16)
JXNCTED Mar 4, 2024
e49562f
Merge pull request #19 from DD2480-Group1/paste-function-revert
andersblomqvist Mar 4, 2024
7485e16
feat: new unit tests
real-darth Mar 4, 2024
1e69400
Merge branch 'JabRef:main' into fix-for-issue-10872
andersblomqvist Mar 5, 2024
997537a
Merge remote-tracking branch 'origin/main' into fix-for-issue-10872
JXNCTED Mar 7, 2024
c00ee33
Update CHANGELOG with copy and paste function
JXNCTED Mar 7, 2024
7a53d8a
Fix Checkstyle failing by reformat the code
JXNCTED Mar 7, 2024
bae8338
Fix OpenRewrite failing by running rewriteRun
JXNCTED Mar 7, 2024
c3ffd8b
Refactor by extract methods in setContent
JXNCTED Mar 7, 2024
053b25e
Merge branch 'main' into fix-for-issue-10872
JXNCTED Mar 10, 2024
047828d
Merge remote-tracking branch 'upstream/main' into fix-for-issue-10872
Siedlerchr Mar 17, 2024
1030d34
collet failures
Siedlerchr Mar 17, 2024
15746c0
changelog and use os.newline
Siedlerchr Mar 17, 2024
f58283c
checkstyle
Siedlerchr Mar 17, 2024
7244e8b
use real bibentrytypes manager
Siedlerchr Mar 17, 2024
404e4a2
Fix CHANGELOG.md
koppor Mar 18, 2024
8b4220a
Swap if branches
koppor Mar 18, 2024
fa28472
Code cleanup
koppor Mar 18, 2024
ccc0a84
Use List for getUsedStringValues
koppor Mar 18, 2024
4e104a5
Merge remote-tracking branch 'origin/main' into fix-for-issue-10872
koppor Mar 18, 2024
e81d5c0
Fix submodule
koppor Mar 18, 2024
40d6f02
Collection is better
koppor Mar 18, 2024
abefd5f
Fix csl-styles
koppor Mar 18, 2024
b0b7e90
Remove empty line
koppor Mar 18, 2024
dcef84e
Group BibTeX string l10n together
koppor Mar 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <kbd>Ctrl</kbd> + <kbd>Scroll</kbd>. [#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

Expand Down
22 changes: 16 additions & 6 deletions src/main/java/org/jabref/gui/ClipBoardManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -155,14 +156,23 @@ public void setContent(String string) {
}

public void setContent(List<BibEntry> 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);
String serializedEntries = serializeEntries(entries, entryTypesManager);
setContent(serializedEntries);
}

public void setContent(List<BibEntry> entries, BibEntryTypesManager entryTypesManager, List<BibtexString> stringConstants) throws IOException {
StringBuilder builder = new StringBuilder();
stringConstants.forEach(strConst -> builder.append(strConst.getParsedSerialization() == null ? "" : strConst.getParsedSerialization()));
String serializedEntries = serializeEntries(entries, entryTypesManager);
builder.append(serializedEntries);
setContent(builder.toString());
}

private String serializeEntries(List<BibEntry> 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(serializedEntries);
clipboard.setContent(content);
setPrimaryClipboardContent(content);
BibEntryWriter writer = new BibEntryWriter(new FieldWriter(preferencesService.getFieldPreferences()), entryTypesManager);
return writer.serializeAll(entries, BibDatabaseMode.BIBTEX);
}
}
1 change: 0 additions & 1 deletion src/main/java/org/jabref/gui/edit/ReplaceStringAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public class ReplaceStringAction extends SimpleCommand {
public ReplaceStringAction(Supplier<LibraryTab> tabSupplier, StateManager stateManager, DialogService dialogService) {
this.tabSupplier = tabSupplier;
this.dialogService = dialogService;

this.executable.bind(ActionHelper.needsDatabase(stateManager));
}

Expand Down
30 changes: 28 additions & 2 deletions src/main/java/org/jabref/gui/externalfiles/ImportHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -40,7 +41,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;
Expand Down Expand Up @@ -311,13 +314,36 @@ private void generateKeys(List<BibEntry> entries) {
public List<BibEntry> handleBibTeXData(String entries) {
BibtexParser parser = new BibtexParser(preferencesService.getImportFormatPreferences(), fileUpdateMonitor);
try {
return parser.parseEntries(new ByteArrayInputStream(entries.getBytes(StandardCharsets.UTF_8)));
List<BibEntry> result = parser.parseEntries(new ByteArrayInputStream(entries.getBytes(StandardCharsets.UTF_8)));
Collection<BibtexString> stringConstants = parser.getStringValues();
importStringConstantsWithDuplicateCheck(stringConstants);
return result;
} catch (ParseException ex) {
LOGGER.error("Could not paste", ex);
return Collections.emptyList();
}
}

public void importStringConstantsWithDuplicateCheck(Collection<BibtexString> stringConstants) {
List<String> 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 {
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()));
}
}
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)));
}
}

public List<BibEntry> handleStringData(String data) throws FetcherException {
if ((data == null) || data.isEmpty()) {
return Collections.emptyList();
Expand Down Expand Up @@ -356,7 +382,7 @@ private List<BibEntry> tryImportFormats(String data) {
}

private List<BibEntry> fetchByDOI(DOI doi) throws FetcherException {
LOGGER.info("Found DOI identifer in clipboard");
LOGGER.info("Found DOI identifier in clipboard");
Optional<BibEntry> entry = new DoiFetcher(preferencesService.getImportFormatPreferences()).performSearchById(doi.getDOI());
return OptionalUtil.toList(entry);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
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;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ListProperty;
Expand All @@ -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;
Expand Down Expand Up @@ -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<BibtexString> strings = stringsListProperty.stream()
.map(this::fromBibtexStringViewModel)
.toList();
strings.forEach(string -> string.setParsedSerialization("@String{" +
string.getName() + " = " + string.getContent() + "}" + OS.NEWLINE));
databaseContext.getDatabase().setStrings(strings);
}

private BibtexString fromBibtexStringViewModel(ConstantsItemModel viewModel) {
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/org/jabref/gui/maintable/MainTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -257,8 +258,13 @@ public void copy() {
List<BibEntry> selectedEntries = getSelectedEntries();

if (!selectedEntries.isEmpty()) {
List<BibtexString> stringConstants = getUsedStringValues(selectedEntries);
try {
clipBoardManager.setContent(selectedEntries, entryTypesManager);
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) {
LOGGER.error("Error while copying selected entries to clipboard.", e);
Expand Down Expand Up @@ -489,4 +495,8 @@ private Optional<BibEntryTableViewModel> findEntry(BibEntry entry) {
.filter(viewModel -> viewModel.getEntry().equals(entry))
.findFirst();
}

private List<BibtexString> getUsedStringValues(List<BibEntry> entries) {
return database.getDatabase().getUsedStrings(entries);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ public List<BibEntry> parseEntries(InputStream inputStream) throws ParseExceptio
}
}

public Collection<BibtexString> getStringValues() {
return database.getStringValues();
}

public Optional<BibEntry> parseSingleEntry(String bibtexString) throws ParseException {
return parseEntries(bibtexString).stream().findFirst();
}
Expand Down
21 changes: 8 additions & 13 deletions src/main/java/org/jabref/model/database/BibDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -370,27 +370,22 @@ public String resolveForStrings(String content) {
/**
* Get all strings used in the entries.
*/
public Collection<BibtexString> getUsedStrings(Collection<BibEntry> entries) {
List<BibtexString> result = new ArrayList<>();
public List<BibtexString> getUsedStrings(Collection<BibEntry> entries) {
Set<String> allUsedIds = new HashSet<>();

// All entries
for (BibEntry entry : entries) {
for (String fieldContent : entry.getFieldValues()) {
resolveContent(fieldContent, new HashSet<>(), allUsedIds);
}
}

// Preamble
if (preamble != null) {
resolveContent(preamble, new HashSet<>(), allUsedIds);
}

for (String stringId : allUsedIds) {
result.add((BibtexString) bibtexStrings.get(stringId).clone());
// All entries
for (BibEntry entry : entries) {
for (String fieldContent : entry.getFieldValues()) {
resolveContent(fieldContent, new HashSet<>(), allUsedIds);
}
}

return result;
return allUsedIds.stream().map(bibtexStrings::get).toList();
}

/**
Expand Down Expand Up @@ -459,7 +454,7 @@ private String resolveString(String label, Set<String> usedIds, Set<String> 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.
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/jabref/model/entry/BibtexString.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading
Loading