-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: support open reference at semantic scholar #13278
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
Changes from all commits
3ddf7aa
9deeb9c
eab0d25
667308a
9f06f1b
2a33b4e
d5b7033
2d65f10
eade1cf
8463aeb
bd0e67b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,9 @@ public enum StandardActions implements Action { | |
EXTRACT_FILE_REFERENCES_OFFLINE(Localization.lang("Extract references from file (offline)"), IconTheme.JabRefIcons.FILE_STAR), | ||
OPEN_URL(Localization.lang("Open URL or DOI"), IconTheme.JabRefIcons.WWW, KeyBinding.OPEN_URL_OR_DOI), | ||
SEARCH_SHORTSCIENCE(Localization.lang("Search ShortScience")), | ||
SEARCH_GOOGLE_SCHOLAR(Localization.lang("Search Google Scholar")), | ||
SEARCH_SEMANTIC_SCHOLAR(Localization.lang("Search Semantic Scholar")), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new string 'Search Semantic Scholar' should be consistent with existing strings and grouped semantically with similar search actions. |
||
SEARCH(Localization.lang("Search...")), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new string 'Search...' should be consistent with existing strings and grouped semantically with similar search actions. |
||
MERGE_WITH_FETCHED_ENTRY(Localization.lang("Get bibliographic data from %0", "DOI/ISBN/..."), KeyBinding.MERGE_WITH_FETCHED_ENTRY), | ||
BATCH_MERGE_WITH_FETCHED_ENTRY(Localization.lang("Get bibliographic data from %0 (fully automated)", "DOI/ISBN/...")), | ||
ATTACH_FILE(Localization.lang("Attach file"), IconTheme.JabRefIcons.ATTACH_FILE), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ | |
import org.jabref.gui.specialfields.SpecialFieldMenuItemFactory; | ||
import org.jabref.logic.citationstyle.CitationStyleOutputFormat; | ||
import org.jabref.logic.citationstyle.CitationStylePreviewLayout; | ||
import org.jabref.logic.importer.ImporterPreferences; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ImporterPreferences import is added but not used in the patch. Unused imports should be removed to maintain clean code. |
||
import org.jabref.logic.importer.WebFetchers; | ||
import org.jabref.logic.journals.JournalAbbreviationRepository; | ||
import org.jabref.logic.l10n.Localization; | ||
|
@@ -62,7 +63,8 @@ public static ContextMenu create(BibEntryTableViewModel entry, | |
TaskExecutor taskExecutor, | ||
JournalAbbreviationRepository abbreviationRepository, | ||
BibEntryTypesManager entryTypesManager, | ||
ImportHandler importHandler) { | ||
ImportHandler importHandler, | ||
ImporterPreferences importerPreferences) { | ||
ActionFactory factory = new ActionFactory(); | ||
ContextMenu contextMenu = new ContextMenu(); | ||
|
||
|
@@ -101,8 +103,7 @@ public static ContextMenu create(BibEntryTableViewModel entry, | |
extractFileReferencesOffline, | ||
|
||
factory.createMenuItem(StandardActions.OPEN_URL, new OpenUrlAction(dialogService, stateManager, preferences)), | ||
factory.createMenuItem(StandardActions.SEARCH_SHORTSCIENCE, new SearchShortScienceAction(dialogService, stateManager, preferences)), | ||
|
||
createSearchSubMenu(factory, dialogService, stateManager, preferences, importerPreferences), | ||
new SeparatorMenuItem(), | ||
|
||
new ChangeEntryTypeMenu(libraryTab.getSelectedEntries(), libraryTab.getBibDatabaseContext(), undoManager, entryTypesManager).asSubMenu(), | ||
|
@@ -219,4 +220,18 @@ private static Menu createSendSubMenu(ActionFactory factory, | |
|
||
return sendMenu; | ||
} | ||
|
||
private static Menu createSearchSubMenu(ActionFactory factory, | ||
DialogService dialogService, | ||
StateManager stateManager, | ||
GuiPreferences preferences, | ||
ImporterPreferences importerPreferences) { | ||
Menu searchMenu = factory.createMenu(StandardActions.SEARCH); | ||
searchMenu.getItems().addAll( | ||
factory.createMenuItem(StandardActions.SEARCH_SHORTSCIENCE, new SearchShortScienceAction(dialogService, stateManager, preferences, importerPreferences)), | ||
factory.createMenuItem(StandardActions.SEARCH_GOOGLE_SCHOLAR, new SearchGoogleScholarAction(dialogService, stateManager, preferences, importerPreferences)), | ||
factory.createMenuItem(StandardActions.SEARCH_SEMANTIC_SCHOLAR, new SearchSemanticScholarAction(dialogService, stateManager, preferences, importerPreferences)) | ||
); | ||
return searchMenu; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package org.jabref.gui.maintable; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
import javafx.beans.binding.BooleanExpression; | ||
|
||
import org.jabref.gui.DialogService; | ||
import org.jabref.gui.StateManager; | ||
import org.jabref.gui.actions.SimpleCommand; | ||
import org.jabref.gui.desktop.os.NativeDesktop; | ||
import org.jabref.gui.preferences.GuiPreferences; | ||
import org.jabref.logic.importer.ImporterPreferences; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.ExternalLinkCreator; | ||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.field.StandardField; | ||
|
||
import static org.jabref.gui.actions.ActionHelper.isFieldSetForSelectedEntry; | ||
import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; | ||
|
||
public class SearchGoogleScholarAction extends SimpleCommand { | ||
private final DialogService dialogService; | ||
private final StateManager stateManager; | ||
private final GuiPreferences preferences; | ||
private final ExternalLinkCreator externalLinkCreator; | ||
|
||
public SearchGoogleScholarAction(DialogService dialogService, StateManager stateManager, GuiPreferences preferences, ImporterPreferences importerPreferences) { | ||
this.dialogService = dialogService; | ||
this.stateManager = stateManager; | ||
this.preferences = preferences; | ||
this.externalLinkCreator = new ExternalLinkCreator(importerPreferences); | ||
|
||
BooleanExpression fieldIsSet = isFieldSetForSelectedEntry(StandardField.TITLE, stateManager); | ||
this.executable.bind(needsEntriesSelected(1, stateManager).and(fieldIsSet)); | ||
} | ||
|
||
@Override | ||
public void execute() { | ||
stateManager.getActiveDatabase().ifPresent(databaseContext -> { | ||
final List<BibEntry> bibEntries = stateManager.getSelectedEntries(); | ||
|
||
if (bibEntries.size() != 1) { | ||
dialogService.notify(Localization.lang("This operation requires exactly one item to be selected.")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The notification message should be in sentence case, not title case, to maintain consistency with other user interface texts. |
||
return; | ||
} | ||
externalLinkCreator.getGoogleScholarSearchURL(bibEntries.getFirst()).ifPresent(url -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The method getGoogleScholarSearchURL should not return null. It should return an Optional to avoid null checks and improve code safety. |
||
try { | ||
NativeDesktop.openExternalViewer(databaseContext, preferences, url, StandardField.URL, dialogService, bibEntries.getFirst()); | ||
} catch (IOException ex) { | ||
Comment on lines
+48
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The try block covers too many statements. It should be minimized to cover only the statement that might throw the IOException. |
||
dialogService.showErrorDialogAndWait(Localization.lang("Unable to open Google Scholar."), ex); | ||
} | ||
}); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package org.jabref.gui.maintable; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
import javafx.beans.binding.BooleanExpression; | ||
|
||
import org.jabref.gui.DialogService; | ||
import org.jabref.gui.StateManager; | ||
import org.jabref.gui.actions.SimpleCommand; | ||
import org.jabref.gui.desktop.os.NativeDesktop; | ||
import org.jabref.gui.preferences.GuiPreferences; | ||
import org.jabref.logic.importer.ImporterPreferences; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.ExternalLinkCreator; | ||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.field.StandardField; | ||
|
||
import static org.jabref.gui.actions.ActionHelper.isFieldSetForSelectedEntry; | ||
import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; | ||
|
||
public class SearchSemanticScholarAction extends SimpleCommand { | ||
private final DialogService dialogService; | ||
private final StateManager stateManager; | ||
private final GuiPreferences preferences; | ||
private final ExternalLinkCreator externalLinkCreator; | ||
|
||
public SearchSemanticScholarAction(DialogService dialogService, StateManager stateManager, GuiPreferences preferences, ImporterPreferences importerPreferences) { | ||
this.dialogService = dialogService; | ||
this.stateManager = stateManager; | ||
this.preferences = preferences; | ||
this.externalLinkCreator = new ExternalLinkCreator(importerPreferences); | ||
|
||
BooleanExpression fieldIsSet = isFieldSetForSelectedEntry(StandardField.TITLE, stateManager); | ||
this.executable.bind(needsEntriesSelected(1, stateManager).and(fieldIsSet)); | ||
} | ||
|
||
@Override | ||
public void execute() { | ||
stateManager.getActiveDatabase().ifPresent(databaseContext -> { | ||
final List<BibEntry> bibEntries = stateManager.getSelectedEntries(); | ||
|
||
if (bibEntries.size() != 1) { | ||
dialogService.notify(Localization.lang("This operation requires exactly one item to be selected.")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The notification message should be in sentence case, not title case, to maintain consistency with other user interface texts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The notification message should be in sentence case, not title case, to maintain consistency with other user interface texts. |
||
return; | ||
} | ||
externalLinkCreator.getSemanticScholarSearchURL(bibEntries.getFirst()).ifPresent(url -> { | ||
try { | ||
NativeDesktop.openExternalViewer(databaseContext, preferences, url, StandardField.URL, dialogService, bibEntries.getFirst()); | ||
} catch (IOException ex) { | ||
Comment on lines
+48
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The try block covers too many statements. It should be minimized to only cover the statement that might throw the IOException. |
||
dialogService.showErrorDialogAndWait(Localization.lang("Unable to open Semantic Scholar."), ex); | ||
} | ||
}); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
import org.jabref.gui.actions.SimpleCommand; | ||
import org.jabref.gui.desktop.os.NativeDesktop; | ||
import org.jabref.gui.preferences.GuiPreferences; | ||
import org.jabref.logic.importer.ImporterPreferences; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.ExternalLinkCreator; | ||
import org.jabref.model.entry.BibEntry; | ||
|
@@ -22,11 +23,13 @@ public class SearchShortScienceAction extends SimpleCommand { | |
private final DialogService dialogService; | ||
private final StateManager stateManager; | ||
private final GuiPreferences preferences; | ||
private final ExternalLinkCreator externalLinkCreator; | ||
|
||
public SearchShortScienceAction(DialogService dialogService, StateManager stateManager, GuiPreferences preferences) { | ||
public SearchShortScienceAction(DialogService dialogService, StateManager stateManager, GuiPreferences preferences, ImporterPreferences importerPreferences) { | ||
this.dialogService = dialogService; | ||
this.stateManager = stateManager; | ||
this.preferences = preferences; | ||
this.externalLinkCreator = new ExternalLinkCreator(importerPreferences); | ||
|
||
BooleanExpression fieldIsSet = isFieldSetForSelectedEntry(StandardField.TITLE, stateManager); | ||
this.executable.bind(needsEntriesSelected(1, stateManager).and(fieldIsSet)); | ||
|
@@ -41,7 +44,7 @@ public void execute() { | |
dialogService.notify(Localization.lang("This operation requires exactly one item to be selected.")); | ||
return; | ||
} | ||
ExternalLinkCreator.getShortScienceSearchURL(bibEntries.getFirst()).ifPresent(url -> { | ||
externalLinkCreator.getShortScienceSearchURL(bibEntries.getFirst()).ifPresent(url -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The try block covers too many statements. It should only cover the statement that might throw an IOException to improve readability and maintainability. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The try block covers too many statements, which can make it harder to identify the exact source of an exception. It should cover as few statements as possible. |
||
try { | ||
NativeDesktop.openExternalViewer(databaseContext, preferences, url, StandardField.URL, dialogService, bibEntries.getFirst()); | ||
} catch (IOException ex) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.jabref.gui.preferences.websearch; | ||
|
||
import javafx.beans.property.SimpleStringProperty; | ||
import javafx.beans.property.StringProperty; | ||
|
||
public class SearchEngineItem { | ||
private final StringProperty name; | ||
private final StringProperty urlTemplate; | ||
|
||
public SearchEngineItem(String name, String urlTemplate) { | ||
this.name = new SimpleStringProperty(name); | ||
this.urlTemplate = new SimpleStringProperty(urlTemplate); | ||
} | ||
|
||
public StringProperty nameProperty() { | ||
return name; | ||
} | ||
|
||
public StringProperty urlTemplateProperty() { | ||
return urlTemplate; | ||
} | ||
|
||
public String getName() { | ||
return name.get(); | ||
} | ||
|
||
public String getUrlTemplate() { | ||
return urlTemplate.get(); | ||
} | ||
|
||
public void setUrlTemplate(String urlTemplate) { | ||
this.urlTemplate.set(urlTemplate); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new string 'Search Google Scholar' should be consistent with existing strings and grouped semantically with similar search actions.