Skip to content

Commit

Permalink
Integrate mrdlib redesign (#4361)
Browse files Browse the repository at this point in the history
* Recommendation retrieval from new Mr. DLib

MrDLibImporter and MrDLibFetcher updated to support JSON and new Mr.
DLib format. Tests updated and passing.

* Create GDPR dialog and update GUI

Created dialog to ask for consent to sed data to Mr. DLib
Created preference setting to keep track of consent
Updated the recommendations GUI to use JavaFX

* Privacy dialog text wrapping

Changed privacy dialog text and allowed the text to wrap.

* Created dev switch based on JabRef version

* Adjusted Hyperlink styling

* Removed .bib file included by mistake

* Simplification of Dev switch

Replaced if/else with in-line conditional

* Removed unnecessary setting of html_representation

Recommendation html_representation field no longer set as it is not used

* Removed .orig file mistakenly added

* Fixed Codacy issues and removed abstracts from tests

Removed html representation test
Removed abstracts from tests

* Moved root styling to css file

* Removed Print Stack Trace call

* Replaced UI strings with Localization.lang strings

* everted to EntryEditorPreferences

* Removed reference to Globals in MrDLibFetcher

* Fixed awkward syntax with JSONObject

* Implemented Dialogs

One to notify the user to restart JabRef after changing preferences
Two to show IOExceptions to the user

* Reverting unintended change

* Set Accept button as default button

* Updated CHANGELOG.md

* Fix for broken MrDLibFetcherTest

* Fix unused imports, refactor event listener to lambda, call static method through classname

* Fix localization strings

Co-authored-by: halirutan <patrick@halirutan.de>
  • Loading branch information
2 people authored and tobiasdiez committed Oct 26, 2018
1 parent 4d89b0a commit f1c29c2
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 240 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We added a minimal height for the entry editor so that it can no longer be hidden by accident. [#4279](https://github.com/JabRef/jabref/issues/4279)
- We added a new keyboard shortcut so that the entry editor could be closed by <kbd>Ctrl<kbd> + <kbd>E<kbd>. [#4222] (https://github.com/JabRef/jabref/issues/4222)
- We added an option in the preference dialog box, that allows user to pick the dark or light theme option. [#4130] (https://github.com/JabRef/jabref/issues/4130)
- We updated updated the Related Articles tab to accept JSON from the new version of the Mr. DLib service



Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jabref/gui/Base.css
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
-fx-underline: false;
-fx-border-style: null;
-fx-border-color: null;
-fx-text-fill: -jr-theme;
}

.hyperlink:visited {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditor.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,13 @@
.code-area .text {
-fx-fill: -fx-text-background-color;
}

.gdpr-dialog {
-fx-font-size: 14pt;
}

.related-articles-tab {
-fx-padding: 20 20 20 20;
}


2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/entryeditor/EntryEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ private List<EntryEditorTab> createTabs() {
// Special tabs
tabs.add(new MathSciNetTab());
tabs.add(new FileAnnotationTab(panel.getAnnotationCache()));
tabs.add(new RelatedArticlesTab(preferences));
tabs.add(new RelatedArticlesTab(preferences, dialogService));

// Source tab
sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ public class EntryEditorPreferences {
private final BibtexKeyPatternPreferences bibtexKeyPatternPreferences;
private final List<String> customTabFieldNames;
private final boolean shouldShowRecommendationsTab;
private final boolean isMrdlibAccepted;
private boolean showSourceTabByDefault;
private final KeyBindingRepository keyBindings;
private boolean avoidOverwritingCiteKey;

public EntryEditorPreferences(Map<String, List<String>> entryEditorTabList, LatexFieldFormatterPreferences latexFieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, List<String> customTabFieldNames, boolean shouldShowRecommendationsTab, boolean showSourceTabByDefault, BibtexKeyPatternPreferences bibtexKeyPatternPreferences, KeyBindingRepository keyBindings, boolean avoidOverwritingCiteKey) {
public EntryEditorPreferences(Map<String, List<String>> entryEditorTabList, LatexFieldFormatterPreferences latexFieldFormatterPreferences, ImportFormatPreferences importFormatPreferences, List<String> customTabFieldNames, boolean shouldShowRecommendationsTab, boolean isMrdlibAccepted, boolean showSourceTabByDefault, BibtexKeyPatternPreferences bibtexKeyPatternPreferences, KeyBindingRepository keyBindings, boolean avoidOverwritingCiteKey) {
this.entryEditorTabList = entryEditorTabList;
this.latexFieldFormatterPreferences = latexFieldFormatterPreferences;
this.importFormatPreferences = importFormatPreferences;
this.customTabFieldNames = customTabFieldNames;
this.shouldShowRecommendationsTab = shouldShowRecommendationsTab;
this.isMrdlibAccepted = isMrdlibAccepted;
this.showSourceTabByDefault = showSourceTabByDefault;
this.bibtexKeyPatternPreferences = bibtexKeyPatternPreferences;
this.keyBindings = keyBindings;
Expand All @@ -52,6 +54,10 @@ public boolean shouldShowRecommendationsTab() {
return shouldShowRecommendationsTab;
}

public boolean isMrdlibAccepted() {
return isMrdlibAccepted;
}

public boolean showSourceTabByDefault() {
return showSourceTabByDefault;
}
Expand Down
164 changes: 121 additions & 43 deletions src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java
Original file line number Diff line number Diff line change
@@ -1,82 +1,155 @@
package org.jabref.gui.entryeditor;

import java.net.URL;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.Text;

import org.jabref.Globals;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.DialogService;
import org.jabref.gui.desktop.JabRefDesktop;
import org.jabref.gui.util.BackgroundTask;
import org.jabref.gui.util.OpenHyperlinksInExternalBrowser;
import org.jabref.logic.importer.fetcher.MrDLibFetcher;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
import org.jabref.preferences.JabRefPreferences;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* GUI for tab displaying article recommendations based on the currently selected BibEntry
*/
public class RelatedArticlesTab extends EntryEditorTab {

private static final Logger LOGGER = LoggerFactory.getLogger(RelatedArticlesTab.class);
private final EntryEditorPreferences preferences;
private final DialogService dialogService;

public RelatedArticlesTab(EntryEditorPreferences preferences) {
public RelatedArticlesTab(EntryEditorPreferences preferences, DialogService dialogService) {
setText(Localization.lang("Related articles"));
setTooltip(new Tooltip(Localization.lang("Related articles")));
this.preferences = preferences;
this.dialogService = dialogService;
}

private StackPane getPane(BibEntry entry) {
/**
* Gets a StackPane of related article information to be displayed in the Related Articles tab
* @param entry The currently selected BibEntry on the JabRef UI.
* @return A StackPane with related article information to be displayed in the Related Articles tab.
*/
private StackPane getRelatedArticlesPane(BibEntry entry) {
StackPane root = new StackPane();
root.getStyleClass().add("related-articles-tab");
ProgressIndicator progress = new ProgressIndicator();
progress.setMaxSize(100, 100);
WebView browser = new WebView();
root.getChildren().addAll(browser, progress);

MrDLibFetcher fetcher = new MrDLibFetcher(Globals.prefs.get(JabRefPreferences.LANGUAGE),
Globals.BUILD_INFO.getVersion().getFullVersion());
Globals.BUILD_INFO.getVersion());
BackgroundTask
.wrap(() -> fetcher.performSearch(entry))
.onRunning(() -> progress.setVisible(true))
.onSuccess(relatedArticles -> {
progress.setVisible(false);
browser.getEngine().loadContent(convertToHtml(relatedArticles));
})
.executeWith(Globals.TASK_EXECUTOR);
.wrap(() -> fetcher.performSearch(entry))
.onRunning(() -> progress.setVisible(true))
.onSuccess(relatedArticles -> {
progress.setVisible(false);
root.getChildren().add(getRelatedArticleInfo(relatedArticles));
})
.executeWith(Globals.TASK_EXECUTOR);

browser.getEngine().getLoadWorker().stateProperty().addListener(new OpenHyperlinksInExternalBrowser(browser));
root.getChildren().add(progress);

return root;
}

/**
* Takes a List of HTML snippets stored in the field "html_representation" of a list of bibentries
*
* @param list of bib entries having a field html_representation
* Creates a VBox of the related article information to be used in the StackPane displayed in the Related Articles tab
* @param list List of BibEntries of related articles
* @return VBox of related article descriptions to be displayed in the Related Articles tab
*/
private String convertToHtml(List<BibEntry> list) {
StringBuilder htmlContent = new StringBuilder();
URL url = IconTheme.getIconUrl("mdlListIcon");
htmlContent
.append("<html><head><title></title></head><body bgcolor='#ffffff'>");
htmlContent.append("<ul style='list-style-image:(");
htmlContent.append(url);
htmlContent.append(")'>");
list.stream()
.map(bibEntry -> bibEntry.getField("html_representation"))
.filter(Optional::isPresent)
.map(o -> "<li style='margin: 5px'>" + o.get() + "</li>")
.forEach(html -> htmlContent.append(html));
htmlContent.append("</ul>");
htmlContent.append("<br><div style='margin-left: 5px'>");
htmlContent.append(
"<a href='http://mr-dlib.org/information-for-users/information-about-mr-dlib-for-jabref-users/#' target=\"_blank\">");
htmlContent.append(Localization.lang("What is Mr. DLib?"));
htmlContent.append("</a></div>");
htmlContent.append("</body></html>");
return htmlContent.toString();
private VBox getRelatedArticleInfo(List<BibEntry> list) {
VBox vBox = new VBox();
vBox.setSpacing(20.0);

for (BibEntry entry : list) {
HBox hBox = new HBox();
hBox.setSpacing(5.0);

String title = entry.getTitle().orElse("");
String journal = entry.getField(FieldName.JOURNAL).orElse("");
String authors = entry.getField(FieldName.AUTHOR).orElse("");
String year = entry.getField(FieldName.YEAR).orElse("");

Hyperlink titleLink = new Hyperlink(title);
Text journalText = new Text(journal);
journalText.setFont(Font.font(Font.getDefault().getFamily(), FontPosture.ITALIC, Font.getDefault().getSize()));
Text authorsText = new Text(authors);
Text yearText = new Text("(" + year + ")");
titleLink.setOnAction(event -> {
if (entry.getField(FieldName.URL).isPresent()) {
try {
JabRefDesktop.openBrowser(entry.getField(FieldName.URL).get());
} catch (IOException e) {
LOGGER.error("Error opening the browser to: " + entry.getField(FieldName.URL).get(), e);
dialogService.showErrorDialogAndWait(e);
}
}
});

hBox.getChildren().addAll(titleLink, journalText, authorsText, yearText);
vBox.getChildren().add(hBox);
}
return vBox;
}

/**
* Returns a consent dialog used to ask permission to send data to Mr. DLib.
* @param entry Currently selected BibEntry. (required to allow reloading of pane if accepted)
* @return StackPane returned to be placed into Related Articles tab.
*/
private ScrollPane getPrivacyDialog(BibEntry entry) {
ScrollPane root = new ScrollPane();
root.getStyleClass().add("related-articles-tab");
VBox vbox = new VBox();
vbox.getStyleClass().add("gdpr-dialog");
vbox.setSpacing(20.0);

Button button = new Button(Localization.lang("I Agree"));
button.setDefaultButton(true);
Text line1 = new Text(Localization.lang("Mr. DLib is an external service which provides article recommendations based on the currently selected entry. Data about the selected entry must be sent to Mr. DLib in order to provide these recommendations. Do you agree that this data may be sent?"));

line1.setWrappingWidth(1300.0);
Text line2 = new Text(Localization.lang("This setting may be changed in preferences at any time."));
Hyperlink mdlLink = new Hyperlink(Localization.lang("Further information about Mr DLib. for JabRef users."));
mdlLink.setOnAction(event -> {
try {
JabRefDesktop.openBrowser("http://mr-dlib.org/information-for-users/information-about-mr-dlib-for-jabref-users/");
} catch (IOException e) {
LOGGER.error("Error opening the browser to Mr. DLib information page.", e);
dialogService.showErrorDialogAndWait(e);
}
});

button.setOnAction(event -> {
JabRefPreferences prefs = JabRefPreferences.getInstance();
prefs.putBoolean(JabRefPreferences.ACCEPT_RECOMMENDATIONS, true);
dialogService.showWarningDialogAndWait(Localization.lang("Restart"), Localization.lang("Please restart JabRef for preferences to take effect."));
setContent(getRelatedArticlesPane(entry));
});

vbox.getChildren().addAll(line1, mdlLink, line2, button);
root.setContent(vbox);

return root;
}

@Override
Expand All @@ -86,6 +159,11 @@ public boolean shouldShow(BibEntry entry) {

@Override
protected void bindToEntry(BibEntry entry) {
setContent(getPane(entry));
// Ask for consent to send data to Mr. DLib on first time to tab
if (preferences.isMrdlibAccepted()) {
setContent(getRelatedArticlesPane(entry));
} else {
setContent(getPrivacyDialog(entry));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class EntryEditorPrefsTab extends Pane implements PrefsTab {
private final CheckBox emacsRebindCtrlF;
private final CheckBox autoComplete;
private final CheckBox recommendations;
private final CheckBox acceptRecommendations;
private final CheckBox validation;
private final RadioButton autoCompBoth;
private final RadioButton autoCompFF;
Expand All @@ -51,6 +52,7 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) {
emacsRebindCtrlF = new CheckBox(Localization.lang("Rebind C-f, too"));
autoComplete = new CheckBox(Localization.lang("Enable word/name autocompletion"));
recommendations = new CheckBox(Localization.lang("Show 'Related Articles' tab"));
acceptRecommendations = new CheckBox(Localization.lang("Accept recommendations from Mr. DLib"));
validation = new CheckBox(Localization.lang("Show validation messages"));

// allowed name formats
Expand Down Expand Up @@ -84,8 +86,9 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) {
builder.add(emacsRebindCtrlA, 1, 5);
builder.add(emacsRebindCtrlF, 1, 6);
builder.add(recommendations, 1, 7);
builder.add(validation, 1, 8);
builder.add(new Label(""), 1, 9);
builder.add(acceptRecommendations, 1, 8);
builder.add(validation, 1, 9);
builder.add(new Label(""), 1, 10);

Label autocompletionOptions = new Label(Localization.lang("Autocompletion options"));
autocompletionOptions.getStyleClass().add("sectionHeader");
Expand Down Expand Up @@ -113,6 +116,7 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) {
builder.add(firstNameModeBoth, 1, 22);
}

@Override
public Node getBuilder() {
return builder;
}
Expand All @@ -135,6 +139,7 @@ public void setValues() {
emacsRebindCtrlA.setSelected(prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA));
emacsRebindCtrlF.setSelected(prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF));
recommendations.setSelected(prefs.getBoolean(JabRefPreferences.SHOW_RECOMMENDATIONS));
acceptRecommendations.setSelected(prefs.getBoolean(JabRefPreferences.ACCEPT_RECOMMENDATIONS));
autoComplete.setSelected(autoCompletePreferences.shouldAutoComplete());
autoCompFields.setText(autoCompletePreferences.getCompleteNamesAsString());

Expand Down Expand Up @@ -171,6 +176,7 @@ public void storeSettings() {
prefs.putBoolean(JabRefPreferences.AUTO_OPEN_FORM, autoOpenForm.isSelected());
prefs.putBoolean(JabRefPreferences.DEFAULT_SHOW_SOURCE, defSource.isSelected());
prefs.putBoolean(JabRefPreferences.SHOW_RECOMMENDATIONS, recommendations.isSelected());
prefs.putBoolean(JabRefPreferences.ACCEPT_RECOMMENDATIONS, acceptRecommendations.isSelected());
prefs.putBoolean(JabRefPreferences.VALIDATE_IN_ENTRY_EDITOR, validation.isSelected());
boolean emacsModeChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS) != emacsMode.isSelected();
boolean emacsRebindCtrlAChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA) != emacsRebindCtrlA.isSelected();
Expand Down
Loading

0 comments on commit f1c29c2

Please sign in to comment.