Skip to content

Commit

Permalink
Merge branch 'main' into postgresql
Browse files Browse the repository at this point in the history
  • Loading branch information
LoayGhreeb authored Sep 29, 2024
2 parents 9073d0c + b44f30e commit 51f1655
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 145 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We improved [cleanup](https://docs.jabref.org/finding-sorting-and-cleaning-entries/cleanupentries) of `arXiv` IDs in distributed in the fields `note`, `version`, `institution`, and `eid` fields. [#11306](https://github.com/JabRef/jabref/issues/11306)
- We added a switch not to store the linked file URL, because it caused troubles at other apps. [#11735](https://github.com/JabRef/jabref/pull/11735)
- When starting a new SLR, the selected catalogs now persist within and across JabRef sessions. [koppor#614](https://github.com/koppor/jabref/issues/614)
- We added support for drag'n'drop on an entry in the maintable to an external application to get the entry preview dropped. [#11846](https://github.com/JabRef/jabref/pull/11846)
- We added a different background color to the search bar to indicate when the search syntax is wrong. [#11658](https://github.com/JabRef/jabref/pull/11658)
- We added a setting which always adds the literal "Cited on pages" text before each JStyle citation. [#11691](https://github.com/JabRef/jabref/pull/11732)

Expand All @@ -49,6 +50,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We improved the display of long messages in the integrity check dialog. [#11619](https://github.com/JabRef/jabref/pull/11619)
- We improved the undo/redo buttons in the main toolbar and main menu to be disabled when there is nothing to undo/redo. [#8807](https://github.com/JabRef/jabref/issues/8807)
- We improved the DOI detection in PDF imports. [#11782](https://github.com/JabRef/jabref/pull/11782)
- We improved the performance when pasting and importing entries in an existing library. [#11843](https://github.com/JabRef/jabref/pull/11843)

### Fixed

Expand Down
25 changes: 15 additions & 10 deletions src/main/java/org/jabref/gui/externalfiles/ImportHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,21 @@ public void importEntryWithDuplicateCheck(BibDatabaseContext bibDatabaseContext,

private void importEntryWithDuplicateCheck(BibDatabaseContext bibDatabaseContext, BibEntry entry, DuplicateResolverDialog.DuplicateResolverResult decision) {
BibEntry entryToInsert = cleanUpEntry(bibDatabaseContext, entry);
Optional<BibEntry> existingDuplicateInLibrary = findDuplicate(bibDatabaseContext, entryToInsert);
if (existingDuplicateInLibrary.isPresent()) {
Optional<BibEntry> duplicateHandledEntry = handleDuplicates(bibDatabaseContext, entryToInsert, existingDuplicateInLibrary.get(), decision);
if (duplicateHandledEntry.isEmpty()) {
return;
}
entryToInsert = duplicateHandledEntry.get();
}
importCleanedEntries(List.of(entryToInsert));
downloadLinkedFiles(entryToInsert);

BackgroundTask.wrap(() -> findDuplicate(bibDatabaseContext, entryToInsert))
.onFailure(e -> LOGGER.error("Error in duplicate search"))
.onSuccess(existingDuplicateInLibrary -> {
BibEntry finalEntry = entryToInsert;
if (existingDuplicateInLibrary.isPresent()) {
Optional<BibEntry> duplicateHandledEntry = handleDuplicates(bibDatabaseContext, entryToInsert, existingDuplicateInLibrary.get(), decision);
if (duplicateHandledEntry.isEmpty()) {
return;
}
finalEntry = duplicateHandledEntry.get();
}
importCleanedEntries(List.of(finalEntry));
downloadLinkedFiles(finalEntry);
}).executeWith(taskExecutor);
}

@VisibleForTesting
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/org/jabref/gui/maintable/MainTable.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jabref.gui.maintable;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -39,12 +40,14 @@
import org.jabref.gui.maintable.columns.LibraryColumn;
import org.jabref.gui.maintable.columns.MainTableColumn;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.preview.ClipboardContentGenerator;
import org.jabref.gui.search.MatchCategory;
import org.jabref.gui.util.ControlHelper;
import org.jabref.gui.util.CustomLocalDragboard;
import org.jabref.gui.util.UiTaskExecutor;
import org.jabref.gui.util.ViewModelTableRowFactory;
import org.jabref.logic.FilePreferences;
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.logic.util.TaskExecutor;
import org.jabref.model.database.BibDatabaseContext;
Expand Down Expand Up @@ -75,6 +78,8 @@ public class MainTable extends TableView<BibEntryTableViewModel> {
private final UndoManager undoManager;
private final FilePreferences filePreferences;
private final ImportHandler importHandler;
private final ClipboardContentGenerator clipboardContentGenerator;

private long lastKeyPressTime;
private String columnSearchTerm;

Expand All @@ -100,6 +105,7 @@ public MainTable(MainTableDataModel model,
this.undoManager = libraryTab.getUndoManager();
this.filePreferences = preferences.getFilePreferences();
this.importHandler = importHandler;
this.clipboardContentGenerator = new ClipboardContentGenerator(preferences.getPreviewPreferences(), preferences.getLayoutFormatterPreferences(), Injector.instantiateModelOrService(JournalAbbreviationRepository.class));

MainTablePreferences mainTablePreferences = preferences.getMainTablePreferences();

Expand Down Expand Up @@ -392,12 +398,18 @@ private void handleOnDragDetected(TableRow<BibEntryTableViewModel> row, BibEntry

List<BibEntry> entries = getSelectionModel().getSelectedItems().stream().map(BibEntryTableViewModel::getEntry).collect(Collectors.toList());

// The following is necessary to initiate the drag and drop in JavaFX,
// although we don't need the contents, it does not work without
ClipboardContent content;
try {
content = clipboardContentGenerator.generate(entries, CitationStyleOutputFormat.HTML, database);
} catch (IOException e) {
LOGGER.warn("Could not generate clipboard content. Falling back to empty clipboard", e);
content = new ClipboardContent();
}
// Required to be able to drop the entries inside JabRef
content.put(DragAndDropDataFormats.ENTRIES, "");

// Drag'n'drop to other tabs use COPY TransferMode, drop to group sidepane use MOVE
ClipboardContent content = new ClipboardContent();
Dragboard dragboard = startDragAndDrop(TransferMode.COPY_OR_MOVE);
content.put(DragAndDropDataFormats.ENTRIES, "");
dragboard.setContent(content);

if (!entries.isEmpty()) {
Expand Down
136 changes: 136 additions & 0 deletions src/main/java/org/jabref/gui/preview/ClipboardContentGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.jabref.gui.preview;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javafx.scene.input.ClipboardContent;

import org.jabref.logic.citationstyle.CitationStyleGenerator;
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.logic.layout.Layout;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.layout.LayoutHelper;
import org.jabref.logic.layout.TextBasedPreviewLayout;
import org.jabref.logic.os.OS;
import org.jabref.logic.preview.PreviewLayout;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryTypesManager;

import com.airhacks.afterburner.injection.Injector;
import com.google.common.annotations.VisibleForTesting;

public class ClipboardContentGenerator {

private PreviewPreferences previewPreferences;
private final LayoutFormatterPreferences layoutFormatterPreferences;
private final JournalAbbreviationRepository abbreviationRepository;

public ClipboardContentGenerator(PreviewPreferences previewPreferences,
LayoutFormatterPreferences layoutFormatterPreferences,
JournalAbbreviationRepository abbreviationRepository) {
this.previewPreferences = previewPreferences;
this.layoutFormatterPreferences = layoutFormatterPreferences;
this.abbreviationRepository = abbreviationRepository;
}

public ClipboardContent generate(List<BibEntry> selectedEntries, CitationStyleOutputFormat outputFormat, BibDatabaseContext bibDatabaseContext) throws IOException {
List<String> citations = generateCitations(selectedEntries, outputFormat, bibDatabaseContext);
PreviewLayout previewLayout = previewPreferences.getSelectedPreviewLayout();

// if it is not a citation style take care of the preview
if (!(previewLayout instanceof CitationStylePreviewLayout)) {
return processPreview(citations);
} else {
// if it's generated by a citation style take care of each output format
ClipboardContent content;
return switch (outputFormat) {
case HTML -> processHtml(citations);
case TEXT -> processText(citations);
};
}
}

private List<String> generateCitations(List<BibEntry> selectedEntries, CitationStyleOutputFormat outputFormat, BibDatabaseContext bibDatabaseContext) throws IOException {
// This worker stored the style as filename. The CSLAdapter and the CitationStyleCache store the source of the
// style. Therefore, we extract the style source from the file.
String styleSource = null;
PreviewLayout previewLayout = previewPreferences.getSelectedPreviewLayout();

if (previewLayout instanceof CitationStylePreviewLayout citationStyleLayout) {
styleSource = citationStyleLayout.getText();
}

if (styleSource != null) {
return CitationStyleGenerator.generateBibliographies(
selectedEntries,
styleSource,
outputFormat,
bibDatabaseContext,
Injector.instantiateModelOrService(BibEntryTypesManager.class));
} else {
return generateTextBasedPreviewLayoutCitations(selectedEntries, bibDatabaseContext);
}
}

/**
* Generates a plain text string out of the preview (based on {@link org.jabref.logic.layout.TextBasedPreviewLayout} or {@link org.jabref.logic.bst.BstPreviewLayout})
* and copies it additionally to the html to the clipboard (WYSIWYG Editors use the HTML, plain text editors the text)
*/
@VisibleForTesting
static ClipboardContent processPreview(List<String> citations) {
ClipboardContent content = new ClipboardContent();
content.putHtml(String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations));
content.putString(String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations));
return content;
}

/**
* Joins every citation with a newline and returns it.
*/
@VisibleForTesting
static ClipboardContent processText(List<String> citations) {
ClipboardContent content = new ClipboardContent();
content.putString(String.join(CitationStyleOutputFormat.TEXT.getLineSeparator(), citations));
return content;
}

/**
* Inserts each citation into a HTML body and copies it to the clipboard.
* The given preview is based on {@link org.jabref.logic.citationstyle.CitationStylePreviewLayout}.
*/
@VisibleForTesting
static ClipboardContent processHtml(List<String> citations) {
String result = "<!DOCTYPE html>" + OS.NEWLINE +
"<html>" + OS.NEWLINE +
" <head>" + OS.NEWLINE +
" <meta charset=\"utf-8\">" + OS.NEWLINE +
" </head>" + OS.NEWLINE +
" <body>" + OS.NEWLINE + OS.NEWLINE;

result += String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations);
result += OS.NEWLINE +
" </body>" + OS.NEWLINE +
"</html>" + OS.NEWLINE;

ClipboardContent content = new ClipboardContent();
content.putString(result);
content.putHtml(result);
return content;
}

private List<String> generateTextBasedPreviewLayoutCitations(List<BibEntry> selectedEntries, BibDatabaseContext bibDatabaseContext) throws IOException {
TextBasedPreviewLayout customPreviewLayout = previewPreferences.getCustomPreviewLayout();
StringReader customLayoutReader = new StringReader(customPreviewLayout.getText().replace("__NEWLINE__", "\n"));
Layout layout = new LayoutHelper(customLayoutReader, layoutFormatterPreferences, abbreviationRepository).getLayoutFromText();
List<String> citations = new ArrayList<>(selectedEntries.size());
for (BibEntry entry : selectedEntries) {
citations.add(layout.doLayout(entry, bibDatabaseContext.getDatabase()));
}
return citations;
}
}
Loading

0 comments on commit 51f1655

Please sign in to comment.