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

GUI for consistency check #12433

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 12 commits
Commits
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 @@ -11,6 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv

### Added

- We added a GUI for bibliography consistency check. [#11950](https://github.com/JabRef/jabref/issues/11950)
- We added a feature for copying entries to libraries, available via the context menu, with an option to include cross-references. [#12374](https://github.com/JabRef/jabref/pull/12374)

### Changed
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jabref/gui/actions/StandardActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public enum StandardActions implements Action {
MERGE_ENTRIES(Localization.lang("Merge entries"), IconTheme.JabRefIcons.MERGE_ENTRIES, KeyBinding.MERGE_ENTRIES),
RESOLVE_DUPLICATE_KEYS(Localization.lang("Resolve duplicate citation keys"), Localization.lang("Find and remove duplicate citation keys"), KeyBinding.RESOLVE_DUPLICATE_CITATION_KEYS),
CHECK_INTEGRITY(Localization.lang("Check integrity"), KeyBinding.CHECK_INTEGRITY),
CHECK_CONSISTENCY(Localization.lang("Check consistency"), KeyBinding.CHECK_CONSISTENCY),
FIND_UNLINKED_FILES(Localization.lang("Search for unlinked local files"), IconTheme.JabRefIcons.SEARCH, KeyBinding.FIND_UNLINKED_FILES),
AUTO_LINK_FILES(Localization.lang("Automatically set file links"), IconTheme.JabRefIcons.AUTO_FILE_LINK, KeyBinding.AUTOMATICALLY_LINK_FILES),
LOOKUP_DOC_IDENTIFIER(Localization.lang("Search document identifier online")),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.jabref.gui.consistency;

import java.util.List;

import javafx.concurrent.Task;

import org.jabref.gui.DialogService;
import org.jabref.gui.StateManager;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.util.UiTaskExecutor;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.quality.consistency.BibliographyConsistencyCheck;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryTypesManager;

import static org.jabref.gui.actions.ActionHelper.needsDatabase;

public class ConsistencyCheckAction extends SimpleCommand {

private final DialogService dialogService;
private final StateManager stateManager;
private final GuiPreferences preferences;
private final BibEntryTypesManager entryTypesManager;
private final UiTaskExecutor taskExecutor;

public ConsistencyCheckAction(DialogService dialogService,
StateManager stateManager,
GuiPreferences preferences,
BibEntryTypesManager entryTypesManager,
UiTaskExecutor taskExecutor) {
this.dialogService = dialogService;
this.stateManager = stateManager;
this.preferences = preferences;
priyanshu16095 marked this conversation as resolved.
Show resolved Hide resolved
this.entryTypesManager = entryTypesManager;
this.taskExecutor = taskExecutor;

this.executable.bind(needsDatabase(stateManager));
}

@Override
public void execute() {
Task<BibliographyConsistencyCheck.Result> task = new Task<>() {
priyanshu16095 marked this conversation as resolved.
Show resolved Hide resolved
@Override
protected BibliographyConsistencyCheck.Result call() {
BibDatabaseContext databaseContext = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null"));
List<BibEntry> entries = databaseContext.getDatabase().getEntries();

BibliographyConsistencyCheck consistencyCheck = new BibliographyConsistencyCheck();
BibliographyConsistencyCheck.Result result = consistencyCheck.check(entries);

return result;
}
};
task.setOnSucceeded(value -> {
BibliographyConsistencyCheck.Result result = task.getValue();
if (result.entryTypeToResultMap().isEmpty()) {
dialogService.notify(Localization.lang("No problems found."));
} else {
dialogService.showCustomDialogAndWait(new ConsistencyCheckDialog(dialogService, preferences, entryTypesManager, result));
}
});
task.setOnFailed(event -> dialogService.showErrorDialogAndWait(Localization.lang("Consistency check failed."), task.getException()));

dialogService.showProgressDialog(
Localization.lang("Checking consistency..."),
Localization.lang("Checking consistency..."),
task);
taskExecutor.execute(task);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonType?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<DialogPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="600.0" prefWidth="1200.0"
xmlns="http://javafx.com/javafx/8.0.121" fx:controller="org.jabref.gui.consistency.ConsistencyCheckDialog">
<content>
<VBox spacing="10.0">
<TableView fx:id="tableView" prefHeight="550" prefWidth="1200.0" VBox.vgrow="ALWAYS" HBox.hgrow="ALWAYS">
<columns>
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN"/>
</columnResizePolicy>
</TableView>
<HBox spacing="4.0" alignment="CENTER">
<Label text="%Entry type"/>
<ComboBox fx:id="entryTypeCombo" maxWidth="Infinity" HBox.hgrow="ALWAYS" />
<Button onAction="#selectEntry" text="%Select">
<tooltip>
<Tooltip text="%Shows results for the selected entry type."/>
</tooltip>
</Button>
</HBox>
<HBox spacing="4.0">
<Button onAction="#exportAsCsv" text="%Export as csv file" />
<Button onAction="#exportAsTxt" text="%Export as txt file" alignment="CENTER_LEFT" />
</HBox>
</VBox>
</content>
<ButtonType fx:constant="CLOSE"/>
</DialogPane>
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.jabref.gui.consistency;

import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Modality;

import org.jabref.gui.DialogService;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.util.BaseDialog;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.quality.consistency.BibliographyConsistencyCheck;
import org.jabref.logic.quality.consistency.ConsistencyMessage;
import org.jabref.model.entry.BibEntryTypesManager;

import com.airhacks.afterburner.views.ViewLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConsistencyCheckDialog extends BaseDialog<Void> {

private final Logger LOGGER = LoggerFactory.getLogger(ConsistencyCheckDialog.class);

@FXML private TableView<ConsistencyMessage> tableView;
@FXML private ComboBox<String> entryTypeCombo;
private final StringProperty selectedEntry = new SimpleStringProperty();

private final DialogService dialogService;
private final GuiPreferences preferences;
private final BibEntryTypesManager entryTypesManager;
private final BibliographyConsistencyCheck.Result result;

private ConsistencyCheckDialogViewModel viewModel;

public ConsistencyCheckDialog(DialogService dialogService,
GuiPreferences preferences,
BibEntryTypesManager entryTypesManager,
BibliographyConsistencyCheck.Result result) {
this.dialogService = dialogService;
this.preferences = preferences;
this.entryTypesManager = entryTypesManager;
this.result = result;

this.setTitle(Localization.lang("Check consistency"));
this.initModality(Modality.NONE);
priyanshu16095 marked this conversation as resolved.
Show resolved Hide resolved

ViewLoader.view(this)
.load()
.setAsDialogPane(this);
}

public ConsistencyCheckDialogViewModel getViewModel() {
return viewModel;
}

@FXML
public void initialize() {
viewModel = new ConsistencyCheckDialogViewModel(dialogService, preferences, entryTypesManager, result);

selectedEntry.set(viewModel.getEntryTypes().getFirst());

entryTypeCombo.getItems().addAll(viewModel.getEntryTypes());
entryTypeCombo.getSelectionModel().select(selectedEntry.getValue());

tableView.setItems(viewModel.getTableData());

for (int i = 0; i < viewModel.getColumnNames().size(); i++) {
int columnIndex = i;
TableColumn<ConsistencyMessage, String> tableColumn = new TableColumn<>(viewModel.getColumnNames().get(i));
tableColumn.setCellValueFactory(row -> {
String[] message = row.getValue().message().split("\\s+");
LOGGER.info("info: " + message[columnIndex]);
return new ReadOnlyStringWrapper(message[columnIndex]);
});
tableView.getColumns().add(tableColumn);
}
}

@FXML
private void selectEntry() {
selectedEntry.set(entryTypeCombo.getSelectionModel().getSelectedItem());
}

@FXML
private void exportAsCsv() {
viewModel.startExportAsCsv();
}

@FXML
private void exportAsTxt() {
viewModel.startExportAsTxt();
}
}
Loading
Loading