-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add fix options for integrity issues #12495
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
Draft
priyanshu16095
wants to merge
70
commits into
JabRef:main
Choose a base branch
from
priyanshu16095:integrityCheckActions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 69 commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
9b11edf
Add fix options for integrity issues
priyanshu16095 02d8e75
Fix the check
priyanshu16095 754b6ad
Add a missing entry for Localization.lang
priyanshu16095 696f904
Fix the check
priyanshu16095 4ab36a8
Refactor code
priyanshu16095 28de796
Fix the check
priyanshu16095 70ae8eb
Add a CHANGELOG.md entry
priyanshu16095 77df6ea
Refactor the code
priyanshu16095 30c81ce
Make use of IntegrityIssue enum
priyanshu16095 5b389da
Add keys in Localization.lang
priyanshu16095 3a0d9a1
Refactor the code
priyanshu16095 a04e06a
Remove use of enum
priyanshu16095 8e9341a
Remove use of enum from PageChecker class
priyanshu16095 235c74f
Add fixAll method
priyanshu16095 9839137
Add a check for fixAll and fixByType method
priyanshu16095 5754680
Fix a bug
priyanshu16095 8f7bdc2
Use dialogService.notify() to notify
priyanshu16095 f57719c
Remove unused imports
priyanshu16095 2105a13
Merge branch 'main' into integrityCheckActions
priyanshu16095 e37ba79
Merge branch 'main' into integrityCheckActions
priyanshu16095 139777e
Add tests for methods
priyanshu16095 39dbfd1
Fix the check and updates based on review
priyanshu16095 16e9817
Use enum for passing issue message
priyanshu16095 102e789
Fix the checkstyle check
priyanshu16095 2d1a5a4
Use enum in remaining checkers
priyanshu16095 361765b
Fix the check
priyanshu16095 19a7881
Revert "Fix the checkstyle check"
priyanshu16095 6a5da7a
Fix the check
priyanshu16095 1bfd407
Fix the check
priyanshu16095 fd0045f
Fix the check
priyanshu16095 9dfed1a
Fix the check
priyanshu16095 7a45ddd
Add JavaDoc comments
priyanshu16095 71efd96
Merge branch 'main' into integrityCheckActions
koppor 409797f
Add integrityIssues.bib file and renamed varibles to singular form
priyanshu16095 cb0c1be
Merge branch 'main' into integrityCheckActions
priyanshu16095 3e94343
Fix the working of button
priyanshu16095 30d4bbb
Sort the issues in alphabetical order
priyanshu16095 2990e3d
Sort the issues alphabetically and show 'No fix availalbe' in the com…
priyanshu16095 647cac8
Add method fix
priyanshu16095 225d235
Remove use of magic number
priyanshu16095 0cb580f
Some changes in integrityissues.bib
priyanshu16095 4ea6831
Make use of fail-fast principle
priyanshu16095 2302dec
Remove exclaimation mark
priyanshu16095 71a6510
Fix the issue
priyanshu16095 a608a22
Fix the checks
priyanshu16095 e52907f
Add readme.md for integrityIssues.bib file
priyanshu16095 eff137a
Change the string to 'BibTex field only'
priyanshu16095 621ebaf
Sovle the parameters issue
priyanshu16095 bcb079f
Correct the spelling of BibTeX
priyanshu16095 4861b01
Add one more issue in IntegrityIssue
priyanshu16095 e60595c
Fix the rewrite check
priyanshu16095 3cf54dd
Merge branch 'main' into integrityCheckActions
koppor a9dbf98
Revert "Correct the spelling of BibTeX"
priyanshu16095 cafaf0c
Merge remote-tracking branch 'origin/integrityCheckActions' into inte…
priyanshu16095 e11499a
Remove csl modules
priyanshu16095 157dfe8
Remove csl locales
priyanshu16095 6f86c65
Correct the spelling of BibTeX
priyanshu16095 8502e76
Try to remove diagService parameter
koppor a717a45
Fix indent
koppor ee71b7f
Remove fixes and tests
priyanshu16095 b979659
Merge branch 'main' into integrityCheckActions
priyanshu16095 0656364
Remove integrityIssues.bib file
priyanshu16095 1181dda
Ensure latest values in combo box
priyanshu16095 c9b3df2
Make the combo box real time
priyanshu16095 7973711
Fix the check
priyanshu16095 31fecf8
Fix the check again
priyanshu16095 9c2a7eb
Merge branch 'main' into integrityCheckActions
priyanshu16095 fcdeea2
Remove updateItems() method
priyanshu16095 c60042f
Add new constructor for IntegrityMessage
priyanshu16095 1f08cfa
Rename variable
priyanshu16095 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,23 @@ | ||
package org.jabref.gui.integrity; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.function.Function; | ||
|
||
import javafx.application.Platform; | ||
import javafx.beans.property.ReadOnlyStringWrapper; | ||
import javafx.fxml.FXML; | ||
import javafx.scene.control.Button; | ||
import javafx.scene.control.ComboBox; | ||
import javafx.scene.control.ContextMenu; | ||
import javafx.scene.control.Label; | ||
import javafx.scene.control.MenuButton; | ||
import javafx.scene.control.TableCell; | ||
import javafx.scene.control.TableColumn; | ||
import javafx.scene.control.TableView; | ||
import javafx.scene.input.MouseButton; | ||
|
@@ -18,8 +29,10 @@ | |
import org.jabref.gui.util.BaseDialog; | ||
import org.jabref.gui.util.ValueTableCellFactory; | ||
import org.jabref.gui.util.ViewModelTableRowFactory; | ||
import org.jabref.logic.integrity.IntegrityIssue; | ||
import org.jabref.logic.integrity.IntegrityMessage; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.util.NotificationService; | ||
|
||
import com.airhacks.afterburner.views.ViewLoader; | ||
import jakarta.inject.Inject; | ||
|
@@ -31,20 +44,28 @@ public class IntegrityCheckDialog extends BaseDialog<Void> { | |
@FXML private TableColumn<IntegrityMessage, String> keyColumn; | ||
@FXML private TableColumn<IntegrityMessage, String> fieldColumn; | ||
@FXML private TableColumn<IntegrityMessage, String> messageColumn; | ||
@FXML private TableColumn<IntegrityMessage, String> fixesColumn; | ||
@FXML private MenuButton keyFilterButton; | ||
@FXML private MenuButton fieldFilterButton; | ||
@FXML private MenuButton messageFilterButton; | ||
@FXML private ComboBox<String> entryTypeCombo; | ||
|
||
@Inject private ThemeManager themeManager; | ||
@Inject private NotificationService notificationService; | ||
|
||
private final List<IntegrityMessage> messages; | ||
private final LibraryTab libraryTab; | ||
|
||
private IntegrityCheckDialogViewModel viewModel; | ||
private TableFilter<IntegrityMessage> tableFilter; | ||
|
||
public IntegrityCheckDialog(List<IntegrityMessage> messages, LibraryTab libraryTab) { | ||
private final double FIX_BUTTON_HEIGHT = 20.0; | ||
|
||
public IntegrityCheckDialog(List<IntegrityMessage> messages, | ||
LibraryTab libraryTab) { | ||
this.messages = messages; | ||
this.libraryTab = libraryTab; | ||
|
||
this.setTitle(Localization.lang("Check integrity")); | ||
this.initModality(Modality.NONE); | ||
|
||
|
@@ -76,10 +97,49 @@ private void initialize() { | |
.withOnMouseClickedEvent(this::handleRowClick) | ||
.install(messagesTable); | ||
messagesTable.setItems(viewModel.getMessages()); | ||
updateEntryTypeCombo(); | ||
keyColumn.setCellValueFactory(row -> new ReadOnlyStringWrapper(row.getValue().entry().getCitationKey().orElse(""))); | ||
fieldColumn.setCellValueFactory(row -> new ReadOnlyStringWrapper(row.getValue().field().getDisplayName())); | ||
messageColumn.setCellValueFactory(row -> new ReadOnlyStringWrapper(row.getValue().message())); | ||
|
||
fixesColumn.setCellFactory(row -> new TableCell<>() { | ||
private final Button button = new Button(); | ||
|
||
@Override | ||
protected void updateItem(String item, boolean empty) { | ||
super.updateItem(item, empty); | ||
setGraphic(null); | ||
button.setOnAction(null); | ||
|
||
if (empty || getTableRow() == null || getTableRow().getItem() == null) { | ||
return; | ||
} | ||
calixtus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
IntegrityMessage rowData = getTableRow().getItem(); | ||
Optional<IntegrityIssue> issue = IntegrityIssue.fromMessage(rowData); | ||
|
||
if (issue.isEmpty()) { | ||
return; | ||
} | ||
|
||
if (issue.get().getFix().isEmpty()) { | ||
setGraphic(new Label(Localization.lang("No fix available"))); | ||
} else { | ||
configureButton(issue.get().getFix().get(), () -> { | ||
viewModel.fix(issue.get(), rowData); | ||
removeRow(rowData); | ||
}); | ||
setGraphic(button); | ||
} | ||
} | ||
|
||
private void configureButton(String text, Runnable action) { | ||
button.setText(text); | ||
button.setPrefHeight(FIX_BUTTON_HEIGHT); | ||
button.setOnAction(event -> action.run()); | ||
} | ||
}); | ||
|
||
new ValueTableCellFactory<IntegrityMessage, String>() | ||
.withText(Function.identity()) | ||
.withTooltip(Function.identity()) | ||
|
@@ -91,6 +151,8 @@ private void initialize() { | |
addMessageColumnFilter(keyColumn, keyFilterButton); | ||
addMessageColumnFilter(fieldColumn, fieldFilterButton); | ||
addMessageColumnFilter(messageColumn, messageFilterButton); | ||
|
||
messagesTable.itemsProperty().bind(viewModel.columnsListProperty()); | ||
} | ||
|
||
private void addMessageColumnFilter(TableColumn<IntegrityMessage, String> messageColumn, MenuButton messageFilterButton) { | ||
|
@@ -121,4 +183,95 @@ public void clearFilters() { | |
}); | ||
} | ||
} | ||
|
||
private void updateEntryTypeCombo() { | ||
Set<String> entryTypes = new HashSet<>(viewModel.issueListProperty()); | ||
Set<String> uniqueTexts = new HashSet<>(); | ||
entryTypeCombo.getItems().clear(); | ||
|
||
Arrays.stream(IntegrityIssue.values()) | ||
.filter(issue -> issue.getFix().isPresent()) | ||
.filter(issue -> entryTypes.contains(issue.getText())) | ||
.filter(issue -> uniqueTexts.add(issue.getText())) | ||
.forEach(issue -> entryTypeCombo.getItems().add(issue.getText())); | ||
|
||
if (entryTypeCombo.getItems().isEmpty()) { | ||
entryTypeCombo.getItems().add(Localization.lang("No fix available")); | ||
} | ||
entryTypeCombo.getSelectionModel().selectFirst(); | ||
} | ||
|
||
public void fix(IntegrityIssue issue, IntegrityMessage message) { | ||
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. Fix seems a bit slang. "resolveIssue" maybe? |
||
viewModel.fix(issue, message); | ||
removeRow(message); | ||
} | ||
|
||
public void removeRow(IntegrityMessage message) { | ||
Platform.runLater(() -> | ||
viewModel.columnsListProperty().getValue().removeIf(column -> | ||
Objects.equals(column.entry().getCitationKey().get(), message.entry().getCitationKey().get()) && | ||
Objects.equals(column.message(), message.message()) | ||
) | ||
); | ||
Platform.runLater(() -> viewModel.issueListProperty().removeIf(issue -> Objects.equals(issue, message.message()))); | ||
updateEntryTypeCombo(); | ||
} | ||
|
||
/** | ||
* Checks if a given {@link IntegrityMessage} has a fix available. | ||
* | ||
* @param message the {@link IntegrityMessage} to check | ||
* @return {@code true} if a fix is available, {@code false} otherwise | ||
*/ | ||
private boolean hasFix(IntegrityMessage message) { | ||
return message != null && message.field() != null && IntegrityIssue.fromMessage(message) | ||
.map(issue -> issue.getFix().isPresent()) | ||
.orElse(false); | ||
} | ||
|
||
/** | ||
* Attempts to fix all {@link IntegrityMessage} objects of the selected type. | ||
* If fixes are available, they are applied, and the fixed messages are removed. | ||
* A notification is shown to indicate success or failure. | ||
*/ | ||
@FXML | ||
private void fixByType() { | ||
AtomicBoolean fixed = new AtomicBoolean(false); | ||
|
||
String selectedType = entryTypeCombo.getSelectionModel().getSelectedItem(); | ||
Optional<IntegrityIssue> selectedIssue = Arrays.stream(IntegrityIssue.values()) | ||
.filter(issue -> issue.getText().equals(selectedType)) | ||
.findFirst(); | ||
|
||
selectedIssue.ifPresent(issue -> { | ||
messagesTable.getItems().stream() | ||
// Filter messages matching the selected issue type and have a fix | ||
.filter(message -> message.message().equals(issue.getText()) && hasFix(message)) | ||
.forEach(message -> { | ||
fix(issue, message); | ||
fixed.set(true); | ||
}); | ||
}); | ||
|
||
updateEntryTypeCombo(); | ||
|
||
if (fixed.get()) { | ||
notificationService.notify(Localization.lang("Fixed successfully.")); | ||
} else { | ||
notificationService.notify(Localization.lang("No fixes available.")); | ||
} | ||
} | ||
|
||
/** | ||
* Attempts to fix all {@link IntegrityMessage} objects that have a fix available. | ||
* Messages with applicable fixes are processed, and the corresponding UI elements are updated. | ||
*/ | ||
@FXML | ||
private void fixAll() { | ||
messagesTable.getItems().stream() | ||
.filter(this::hasFix) // Filter all messages that have a fix | ||
.forEach(message -> IntegrityIssue.fromMessage(message).ifPresent(issue -> fix(issue, message))); | ||
|
||
updateEntryTypeCombo(); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/org/jabref/gui/integrity/IntegrityCheckDialogViewModel.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,47 @@ | ||
package org.jabref.gui.integrity; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import javafx.beans.property.ListProperty; | ||
import javafx.beans.property.SimpleListProperty; | ||
import javafx.collections.FXCollections; | ||
import javafx.collections.ObservableList; | ||
|
||
import org.jabref.gui.AbstractViewModel; | ||
import org.jabref.logic.integrity.IntegrityIssue; | ||
import org.jabref.logic.integrity.IntegrityMessage; | ||
|
||
public class IntegrityCheckDialogViewModel extends AbstractViewModel { | ||
|
||
private final ListProperty<IntegrityMessage> columnsListProperty; | ||
private final ObservableList<String> issuesListProperty; | ||
private final ObservableList<IntegrityMessage> messages; | ||
|
||
public IntegrityCheckDialogViewModel(List<IntegrityMessage> messages) { | ||
this.messages = FXCollections.observableArrayList(messages); | ||
|
||
List<String> issuesList = messages.stream() | ||
.map(IntegrityMessage::message) | ||
.collect(Collectors.toList()); | ||
this.issuesListProperty = FXCollections.observableArrayList(issuesList); | ||
|
||
this.columnsListProperty = new SimpleListProperty<>(FXCollections.observableArrayList(messages)); | ||
} | ||
|
||
public ObservableList<String> issueListProperty() { | ||
return issuesListProperty; | ||
} | ||
|
||
public ListProperty<IntegrityMessage> columnsListProperty() { | ||
return this.columnsListProperty; | ||
} | ||
|
||
public ObservableList<IntegrityMessage> getMessages() { | ||
return messages; | ||
} | ||
|
||
public void fix(IntegrityIssue issue, IntegrityMessage message) { | ||
// fixes | ||
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. fixes,,,? |
||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.