Skip to content

Keyword Tooltip/Cleanup for MSC codes added to Keyword Editor #12914

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

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0f77aba
added msc codes, keyword tooltip feature
JustinHennis1 Apr 9, 2025
9cec66b
keyword tooltip feature#423, changelog updated
JustinHennis1 Apr 9, 2025
3a506b4
Merge branch 'main' into ktooltip
JustinHennis1 Apr 9, 2025
a09718f
uses getResource to find json/loadMscCodesFromJson overloaded to take…
JustinHennis1 Apr 10, 2025
1ce8ec0
Merge branch 'ktooltip' of https://github.com/JustinHennis1/jabref in…
JustinHennis1 Apr 10, 2025
92d0f60
printstacktrace removed from MscCodeUtils
JustinHennis1 Apr 10, 2025
0d57263
Switched from File to Path.of in loadMscFromJson
JustinHennis1 Apr 10, 2025
f5f16b1
Merge branch 'JabRef:main' into ktooltip
JustinHennis1 Apr 10, 2025
8d0af60
checkstyle compliance
JustinHennis1 Apr 10, 2025
6d14ec9
Merge branch 'ktooltip' of https://github.com/JustinHennis1/jabref in…
JustinHennis1 Apr 10, 2025
4fa4d10
fixed markdown check
JustinHennis1 Apr 10, 2025
24d5112
Added logic for MSC code conversion cleanup. Actual cleanup() logic s…
JustinHennis1 Apr 11, 2025
1ab572d
added secondary cleanup to convert keywords in entries to their descr…
JustinHennis1 Apr 13, 2025
a1d0c92
MSC code cleanup functional, msc_codes.json cleaned for comma delimit…
JustinHennis1 Apr 14, 2025
475c3b9
Cleaned msc json for extra commas
JustinHennis1 Apr 14, 2025
b3e11f5
Tests updated for msc code conversion
JustinHennis1 Apr 14, 2025
965a564
Passes Checkstyle and RewriteDryRun, cleanup mentioned in changelog
JustinHennis1 Apr 14, 2025
903f2e1
Markup check
JustinHennis1 Apr 14, 2025
87203b1
MSC cleanup test modified because conversion is async,Fixed syntax er…
JustinHennis1 Apr 15, 2025
53b47a6
loadMSCCodes is wrapped in Optional, Custom Exception created
JustinHennis1 Apr 15, 2025
0fca1f5
loadMSCCodeFromJson: empty optional returned, cstyle compliant
JustinHennis1 Apr 15, 2025
44bf6f0
Merge branch 'main' into ktooltip
JustinHennis1 Apr 15, 2025
339fb44
localizations added, most tests pass, javafx issue with cleanuptest s…
JustinHennis1 Apr 15, 2025
03eba4e
Merge branch 'ktooltip' of https://github.com/JustinHennis1/jabref in…
JustinHennis1 Apr 15, 2025
430c1e0
JavaFX initializes once for tests
JustinHennis1 Apr 16, 2025
30d3391
Tests Pass Local, Using Platform class to check JavaFX initialized in…
JustinHennis1 Apr 16, 2025
e3e475a
Features and Tests work, one caveat issue w/ JavaFX
JustinHennis1 Apr 16, 2025
da15de2
Merge branch 'main' into ktooltip
JustinHennis1 Apr 16, 2025
fa09a62
Merge branch 'main' into ktooltip
JustinHennis1 Apr 17, 2025
88fbaff
Language Localizations added, FF principle fixes
JustinHennis1 Apr 18, 2025
6f7ac45
Merge branch 'ktooltip' of https://github.com/JustinHennis1/jabref in…
JustinHennis1 Apr 18, 2025
019ce37
Bimap implemented, fixes unhandled except, msc codes edited
JustinHennis1 Apr 19, 2025
9f7f31d
Checkstyle fixes
JustinHennis1 Apr 20, 2025
c27e0e1
Merge branch 'main' into ktooltip
JustinHennis1 Apr 21, 2025
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv

### Added

- We added a feature to convert keywords that resemble MSC codes to their descriptions. [#12944](https://github.com/JabRef/jabref/issues/12944)
- We added a tooltip to keywords that resemble Math Subject Classification(MSC) codes. [#12944](https://github.com/JabRef/jabref/issues/12944)
- We added a button in Privacy notice and Mr. DLib Privacy settings notice for hiding related tabs. [#11707](https://github.com/JabRef/jabref/issues/11707)
- We added buttons "Add example entry" and "Import existing PDFs" when a library is empty, making it easier for new users to get started. [#12662](https://github.com/JabRef/jabref/issues/12662)
- In the Open/LibreOffice integration, we added the provision to modify the bibliography title and its format for CSL styles, in the "Select style" dialog. [#12663](https://github.com/JabRef/jabref/issues/12663)
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/jabref/gui/cleanup/CleanupAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ private boolean doCleanup(BibDatabaseContext databaseContext, CleanupPreferences
CleanupWorker cleaner = new CleanupWorker(
databaseContext,
preferences.getFilePreferences(),
preferences.getTimestampPreferences()
preferences.getTimestampPreferences(),
preferences.getBibEntryPreferences()
Copy link

Choose a reason for hiding this comment

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

The addition of preferences.getBibEntryPreferences() to the CleanupWorker constructor requires updating the JavaDoc for doCleanup method to reflect this change in parameters.

);

List<FieldChange> changes = cleaner.cleanup(preset, entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<CheckBox fx:id="cleanUpBibtex" text="%Convert to BibTeX format (e.g., store publication date in year and month fields)" />
<CheckBox fx:id="cleanUpTimestampToCreationDate" text="%Convert timestamp field to field 'creationdate'" />
<CheckBox fx:id="cleanUpTimestampToModificationDate" text="%Convert timestamp field to field 'modificationdate'" />
<CheckBox fx:id="cleanUpConvertMSCcodes" text="%Convert MSC Keyword codes to their respective descriptions." />
</VBox>

<Label text="%File-related" />
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jabref.gui.commonfxcontrols.FieldFormatterCleanupsPanel;
import org.jabref.logic.FilePreferences;
import org.jabref.logic.cleanup.CleanupPreferences;
import org.jabref.logic.cleanup.ConvertMSCCodesCleanup;
import org.jabref.logic.cleanup.FieldFormatterCleanups;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
Expand All @@ -39,6 +40,7 @@ public class CleanupPresetPanel extends VBox {
@FXML private CheckBox cleanUpBibtex;
@FXML private CheckBox cleanUpTimestampToCreationDate;
@FXML private CheckBox cleanUpTimestampToModificationDate;
@FXML private CheckBox cleanUpConvertMSCcodes;
@FXML private FieldFormatterCleanupsPanel formatterCleanupsPanel;

public CleanupPresetPanel(BibDatabaseContext databaseContext, CleanupPreferences cleanupPreferences, FilePreferences filePreferences) {
Expand All @@ -64,6 +66,14 @@ private void init(CleanupPreferences cleanupPreferences, FilePreferences filePre
cleanUpMovePDF.setSelected(false);
}

if (!ConvertMSCCodesCleanup.isConversionPossible()) {
cleanUpConvertMSCcodes.setDisable(true);
cleanUpConvertMSCcodes.setSelected(false);
}

cleanUpConvertMSCcodes.setText(Localization.lang("Convert MSC Keyword codes to their respective descriptions."));
cleanUpConvertMSCcodes.setSelected(false);

cleanUpRenamePDFonlyRelativePaths.disableProperty().bind(cleanUpRenamePDF.selectedProperty().not());

cleanUpUpgradeExternalLinks.setText(Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", StandardField.FILE.getDisplayName()));
Expand All @@ -84,6 +94,7 @@ private void init(CleanupPreferences cleanupPreferences, FilePreferences filePre
cleanUpBibtex.selectedProperty().setValue(false);
}
});

cleanUpTimestampToCreationDate.selectedProperty().addListener(
(observable, oldValue, newValue) -> {
if (newValue) {
Expand Down Expand Up @@ -113,6 +124,7 @@ private void updateDisplay(CleanupPreferences preset) {
cleanUpDeletedFiles.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CLEAN_UP_DELETED_LINKED_FILES));
cleanUpBiblatex.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CONVERT_TO_BIBLATEX));
cleanUpBibtex.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CONVERT_TO_BIBTEX));
cleanUpConvertMSCcodes.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CONVERT_MSC_CODES));
cleanUpTimestampToCreationDate.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CONVERT_TIMESTAMP_TO_CREATIONDATE));
cleanUpTimestampToModificationDate.setSelected(preset.isActive(CleanupPreferences.CleanupStep.CONVERT_TIMESTAMP_TO_MODIFICATIONDATE));
cleanUpTimestampToModificationDate.setSelected(preset.isActive(CleanupPreferences.CleanupStep.DO_NOT_CONVERT_TIMESTAMP));
Expand All @@ -139,6 +151,9 @@ public CleanupPreferences getCleanupPreset() {
if (cleanUpISSN.isSelected()) {
activeJobs.add(CleanupPreferences.CleanupStep.CLEAN_UP_ISSN);
}
if (cleanUpConvertMSCcodes.isSelected()) {
activeJobs.add(CleanupPreferences.CleanupStep.CONVERT_MSC_CODES);
}
if (cleanUpMakePathsRelative.isSelected()) {
activeJobs.add(CleanupPreferences.CleanupStep.MAKE_PATHS_RELATIVE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ private void doCleanup(BibDatabaseContext databaseContext, CleanupPreferences pr
CleanupWorker cleaner = new CleanupWorker(
databaseContext,
preferences.getFilePreferences(),
preferences.getTimestampPreferences()
preferences.getTimestampPreferences(),
preferences.getBibEntryPreferences()
Comment on lines +87 to +88
Copy link

Choose a reason for hiding this comment

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

The addition of preferences.getBibEntryPreferences() to the CleanupWorker constructor changes the method signature, which requires updating the JavaDoc to reflect this change.

);

List<FieldChange> changes = cleaner.cleanup(preset, entry);
Expand Down
50 changes: 49 additions & 1 deletion src/main/java/org/jabref/gui/fieldeditors/KeywordsEditor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jabref.gui.fieldeditors;

import java.net.URL;
import java.util.Comparator;
import java.util.Optional;

Expand All @@ -13,6 +14,7 @@
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
Expand All @@ -32,6 +34,8 @@
import org.jabref.gui.util.ViewModelListCellFactory;
import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.msc.MscCodeLoadingException;
import org.jabref.logic.msc.MscCodeUtils;
import org.jabref.logic.preferences.CliPreferences;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.Keyword;
Expand All @@ -42,6 +46,7 @@
import com.airhacks.afterburner.views.ViewLoader;
import com.dlsc.gemsfx.TagsField;
import com.google.common.collect.Comparators;
import com.google.common.collect.HashBiMap;
import jakarta.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -50,6 +55,32 @@ public class KeywordsEditor extends HBox implements FieldEditorFX {
private static final Logger LOGGER = LoggerFactory.getLogger(KeywordsEditor.class);
private static final PseudoClass FOCUSED = PseudoClass.getPseudoClass("focused");

private static HashBiMap<String, String> mscmap;

static {
URL resourceUrl = KeywordsEditor.class.getClassLoader().getResource("msc_codes.json");

if (resourceUrl == null) {
LOGGER.error(Localization.lang("Resource not found: msc_codes.json"));
mscmap = HashBiMap.create();
}

try {
Optional<HashBiMap<String, String>> optionalMscCodes = MscCodeUtils.loadMscCodesFromJson(resourceUrl);

if (optionalMscCodes.isPresent()) {
mscmap = optionalMscCodes.get(); // Unwrap the map if present
} else {
LOGGER.warn(Localization.lang("Resource not found: msc_codes.json"));
mscmap = HashBiMap.create();
}
} catch (MscCodeLoadingException e) {
LOGGER.error(Localization.lang("Error loading MSC codes:", e));
mscmap = HashBiMap.create();
}
}


@FXML private KeywordsEditorViewModel viewModel;
@FXML private TagsField<Keyword> keywordTagsField;

Expand Down Expand Up @@ -123,7 +154,7 @@ public KeywordsEditor(Field field,
}
});

Bindings.bindContentBidirectional(keywordTagsField.getTags(), viewModel.keywordListProperty());
Bindings.bindContentBidirectional(keywordTagsField.getTags(), viewModel.keywordListProperty());
}

private Node createTag(Keyword keyword) {
Expand Down Expand Up @@ -153,6 +184,23 @@ private Node createTag(Keyword keyword) {
}
event.consume();
});

// Checks Keyword for MSC code and displays tooltip with corresponding description
if (mscmap.containsKey(tagLabel.getText())) {
String mscClassification = mscmap.get(tagLabel.getText());
Tooltip tooltip = new Tooltip(mscClassification);

tagLabel.setOnMouseEntered(event -> {
// Show tooltip when mouse enters
Tooltip.install(tagLabel, tooltip);
});

tagLabel.setOnMouseExited(event -> {
// Uninstall tooltip when mouse exits
Tooltip.uninstall(tagLabel, tooltip);
});
}

tagLabel.setOnDragDetected(event -> {
Dragboard db = tagLabel.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ public enum CleanupStep {
DO_NOT_CONVERT_TIMESTAMP,
MOVE_PDF,
FIX_FILE_LINKS,
CLEAN_UP_ISSN
CLEAN_UP_ISSN,
/*
* Converts Math Subject Classification Codes presented in Keywords into their Descriptions
*/
CONVERT_MSC_CODES
}
}
26 changes: 22 additions & 4 deletions src/main/java/org/jabref/logic/cleanup/CleanupWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,25 @@
import org.jabref.model.FieldChange;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryPreferences;

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

public class CleanupWorker {

private static final Logger LOGGER = LoggerFactory.getLogger(CleanupWorker.class);
private final BibDatabaseContext databaseContext;
private final FilePreferences filePreferences;
private final TimestampPreferences timestampPreferences;
private final BibEntryPreferences bibEntryPreferences;
private final List<JabRefException> failures;

public CleanupWorker(BibDatabaseContext databaseContext, FilePreferences filePreferences, TimestampPreferences timestampPreferences) {
public CleanupWorker(BibDatabaseContext databaseContext, FilePreferences filePreferences, TimestampPreferences timestampPreferences, BibEntryPreferences bibEntryPreferences) {
this.databaseContext = databaseContext;
this.filePreferences = filePreferences;
this.timestampPreferences = timestampPreferences;
this.bibEntryPreferences = bibEntryPreferences;
this.failures = new ArrayList<>();
}

Expand All @@ -31,8 +38,9 @@ public List<FieldChange> cleanup(CleanupPreferences preset, BibEntry entry) {

List<CleanupJob> jobs = determineCleanupActions(preset);
List<FieldChange> changes = new ArrayList<>();
for (CleanupJob job : jobs) {
for (CleanupJob job : jobs) {
changes.addAll(job.cleanup(entry));

if (job instanceof MoveFilesCleanup cleanup) {
failures.addAll(cleanup.getIoExceptions());
}
Expand All @@ -44,8 +52,18 @@ public List<FieldChange> cleanup(CleanupPreferences preset, BibEntry entry) {
private List<CleanupJob> determineCleanupActions(CleanupPreferences preset) {
List<CleanupJob> jobs = new ArrayList<>();

// Special handling for MSC code conversion
if (preset.isActive(CleanupPreferences.CleanupStep.CONVERT_MSC_CODES)) {
jobs.add(new ConvertMSCCodesCleanup(bibEntryPreferences, true));
} else {
jobs.add(new ConvertMSCCodesCleanup(bibEntryPreferences, false));
}

// Handle all other cleanup actions
for (CleanupPreferences.CleanupStep action : preset.getActiveJobs()) {
jobs.add(toJob(action));
if (action != CleanupPreferences.CleanupStep.CONVERT_MSC_CODES) {
jobs.add(toJob(action));
}
}

if (preset.getFieldFormatterCleanups().isEnabled()) {
Expand Down
Loading
Loading