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

Integrate mrdlib redesign #4361

Merged
merged 25 commits into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cfa4356
Recommendation retrieval from new Mr. DLib
conorfos Sep 5, 2018
1320270
Create GDPR dialog and update GUI
conorfos Sep 17, 2018
0416402
Privacy dialog text wrapping
conorfos Sep 18, 2018
86350c9
Created dev switch based on JabRef version
conorfos Sep 21, 2018
25e5cb8
Adjusted Hyperlink styling
conorfos Sep 26, 2018
045c15d
Removed .bib file included by mistake
conorfos Sep 26, 2018
69c6383
Simplification of Dev switch
conorfos Sep 27, 2018
3518596
Removed unnecessary setting of html_representation
conorfos Sep 27, 2018
4215e13
Removed .orig file mistakenly added
conorfos Sep 27, 2018
55ca696
Fixed Codacy issues and removed abstracts from tests
conorfos Sep 27, 2018
4ccbea6
Moved root styling to css file
conorfos Oct 11, 2018
440db51
Removed Print Stack Trace call
conorfos Oct 12, 2018
40af08c
Replaced UI strings with Localization.lang strings
conorfos Oct 12, 2018
4d5df3d
everted to EntryEditorPreferences
conorfos Oct 12, 2018
761ed98
Removed reference to Globals in MrDLibFetcher
conorfos Oct 15, 2018
b4dabe0
Fixed awkward syntax with JSONObject
conorfos Oct 15, 2018
bfe5abf
Implemented Dialogs
conorfos Oct 15, 2018
fdd1e03
Merge latest from Master
conorfos Oct 15, 2018
fb2fc79
Reverting unintended change
conorfos Oct 17, 2018
fd82562
Set Accept button as default button
conorfos Oct 17, 2018
9c769b1
Updated CHANGELOG.md
conorfos Oct 18, 2018
4357ada
Merge branch 'master' into integrate-mrdlib-redesign
conorfos Oct 18, 2018
493d5e6
Fix for broken MrDLibFetcherTest
conorfos Oct 25, 2018
571618c
Fix unused imports, refactor event listener to lambda, call static me…
halirutan Oct 26, 2018
ecf9eb5
Fix localization strings
halirutan Oct 26, 2018
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 @@ -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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the EntryEditorPreferences which are already passed via constructor. Apart form that lgtm

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But shouldn't this setting not go into the JabRefPreferences and not the preferences of the EntryEditor? When I see this correctly in the above screenshot, this setting was supposed to be available main preferences.

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