-
-
Couldn't load subscription status.
- Fork 3k
Add support for loading .blg warnings in Integrity Check Dialog #12866
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
aab2f21
a4b657f
d1e4eb1
753cadc
a3b6847
6760ced
b694915
f86643b
64301be
6f2aab3
907fb0c
32dd199
2f5ec93
eb33f20
05d2cd3
f21199c
cf93fc1
a75431b
a629dbb
b1ae65b
19a7c5f
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 |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
|
|
||
| <?import javafx.scene.control.Button?> | ||
| <?import javafx.scene.control.Label?> | ||
| <?import javafx.scene.control.TextField?> | ||
| <?import javafx.scene.layout.HBox?> | ||
|
|
||
| <HBox xmlns="http://javafx.com/javafx" | ||
| xmlns:fx="http://javafx.com/fxml" | ||
| spacing="10" | ||
| alignment="CENTER_LEFT" | ||
| fx:controller="org.jabref.gui.integrity.BibLogSettingsPane" | ||
| fx:id="bibLogSettingsPane"> | ||
| <Label text="BibTeX log (.blg) file:"/> | ||
| <TextField fx:id="pathField" prefWidth="300"/> | ||
| <Button onAction="#onBrowse" text="Browse..."/> | ||
| <Button onAction="#onReset" text="Reset"/> | ||
| </HBox> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| package org.jabref.gui.integrity; | ||
|
|
||
| import java.nio.file.Path; | ||
|
|
||
| import javafx.collections.ObservableList; | ||
| import javafx.fxml.FXML; | ||
| import javafx.scene.control.TextField; | ||
|
|
||
| import org.jabref.gui.DialogService; | ||
| import org.jabref.gui.util.FileDialogConfiguration; | ||
| import org.jabref.logic.JabRefException; | ||
| import org.jabref.logic.integrity.IntegrityMessage; | ||
| import org.jabref.logic.l10n.Localization; | ||
| import org.jabref.logic.util.StandardFileType; | ||
| import org.jabref.model.database.BibDatabaseContext; | ||
|
|
||
| import jakarta.inject.Inject; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Controller for the .blg file settings panel. | ||
| * | ||
| * Binds the path text field to the ViewModel, | ||
| * and handles browse/reset button actions. | ||
| */ | ||
| public class BibLogSettingsPane { | ||
| private static final Logger LOGGER = LoggerFactory.getLogger(BibLogSettingsPane.class); | ||
| @FXML | ||
| private TextField pathField; | ||
InAnYan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private BibLogSettingsViewModel viewModel; | ||
| @Inject private DialogService dialogService; | ||
| private Runnable onBlgPathChanged; | ||
|
|
||
| public void initializeViewModel(BibDatabaseContext context, Runnable onBlgPathChanged) throws JabRefException { | ||
| this.onBlgPathChanged = onBlgPathChanged; | ||
| this.viewModel = new BibLogSettingsViewModel(context.getMetaData(), context.getDatabasePath()); | ||
| pathField.textProperty().bindBidirectional(viewModel.pathProperty()); | ||
| viewModel.getBlgWarnings(context); | ||
| } | ||
|
|
||
| public ObservableList<IntegrityMessage> getBlgWarnings() { | ||
InAnYan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return viewModel.getBlgWarningsObservable(); | ||
| } | ||
|
|
||
| public void refreshWarnings(BibDatabaseContext context) throws JabRefException { | ||
| viewModel.getBlgWarnings(context); | ||
| } | ||
|
|
||
| @FXML | ||
| private void onBrowse() { | ||
| FileDialogConfiguration fileDialogConfiguration = createBlgFileDialogConfig(); | ||
| dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(path -> { | ||
| viewModel.setBlgFilePath(path); | ||
| notifyPathChanged(); | ||
| }); | ||
| } | ||
|
|
||
| @FXML | ||
| private void onReset() { | ||
| viewModel.resetBlgFilePath(); | ||
| notifyPathChanged(); | ||
| } | ||
|
|
||
| private void notifyPathChanged() { | ||
| if (onBlgPathChanged != null) { | ||
| onBlgPathChanged.run(); | ||
| } | ||
| } | ||
|
|
||
| public BibLogSettingsViewModel getViewModel() { | ||
| return viewModel; | ||
| } | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private FileDialogConfiguration createBlgFileDialogConfig() { | ||
| Path initialDir = viewModel.getInitialDirectory(); | ||
| FileDialogConfiguration config = new FileDialogConfiguration.Builder() | ||
InAnYan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .addExtensionFilter(Localization.lang("BibTeX log files"), StandardFileType.BLG) | ||
InAnYan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .withDefaultExtension(Localization.lang("BibTeX log files"), StandardFileType.BLG) | ||
| .withInitialDirectory(viewModel.getInitialDirectory()) | ||
| .build(); | ||
| return config; | ||
| } | ||
|
|
||
| public boolean wasBlgFileManuallySelected() { | ||
| return viewModel.wasBlgFileManuallySelected(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| package org.jabref.gui.integrity; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| import javafx.beans.property.SimpleStringProperty; | ||
| import javafx.beans.property.StringProperty; | ||
| import javafx.collections.FXCollections; | ||
| import javafx.collections.ObservableList; | ||
|
|
||
| import org.jabref.gui.AbstractViewModel; | ||
| import org.jabref.logic.JabRefException; | ||
| import org.jabref.logic.biblog.BibLogPathResolver; | ||
| import org.jabref.logic.biblog.BibWarningToIntegrityMessageConverter; | ||
| import org.jabref.logic.biblog.BibtexLogParser; | ||
| import org.jabref.logic.integrity.IntegrityMessage; | ||
| import org.jabref.logic.l10n.Localization; | ||
| import org.jabref.model.biblog.BibWarning; | ||
| import org.jabref.model.database.BibDatabaseContext; | ||
| import org.jabref.model.metadata.MetaData; | ||
|
|
||
| /// 1. Connects MetaData with the view. | ||
| /// 2. Wraps .blg warnings as IntegrityMessages. | ||
| /// 3. Supports file browsing and reset actions. | ||
| public class BibLogSettingsViewModel extends AbstractViewModel { | ||
| private final ObservableList<IntegrityMessage> blgWarnings = FXCollections.observableArrayList(); | ||
| private final StringProperty path = new SimpleStringProperty(""); | ||
| private final MetaData metaData; | ||
| private final Optional<Path> bibPath; | ||
| private final String user; | ||
| private Optional<Path> lastResolvedBlgPath = Optional.empty(); | ||
| private boolean userManuallySelectedBlgFile = false; | ||
|
|
||
| public BibLogSettingsViewModel(MetaData metaData, Optional<Path> bibPath) { | ||
| this.metaData = metaData; | ||
| this.bibPath = bibPath; | ||
| this.user = System.getProperty("user.name"); | ||
|
|
||
| BibLogPathResolver.resolve(metaData, bibPath, user) | ||
| .ifPresent(resolvedPath -> { | ||
| this.path.set(resolvedPath.toString()); | ||
| if (metaData.getBlgFilePath(user).isEmpty()) { | ||
| metaData.setBlgFilePath(user, resolvedPath); | ||
| this.lastResolvedBlgPath = Optional.of(resolvedPath); | ||
| } | ||
| }); | ||
|
Comment on lines
+42
to
+49
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 code does not follow the fail-fast principle. It should return early if the condition is not met, instead of nesting logic inside an if statement. |
||
| } | ||
|
|
||
| /** | ||
| * Parses the .blg file (if it exists) into the observable list. | ||
| * | ||
| * @param databaseContext the current database context used to resolve citation keys in warnings. | ||
| * @return An Optional containing the list of integrity messages if the file exists and can be parsed, | ||
| * or an empty Optional if the file does not exist. | ||
| * @throws JabRefException if the .blg file cannot be parsed or read | ||
| */ | ||
| public Optional<List<IntegrityMessage>> getBlgWarnings(BibDatabaseContext databaseContext) throws JabRefException { | ||
| Optional<Path> resolved = getResolvedBlgPath(); | ||
InAnYan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (resolved.isEmpty()) { | ||
| blgWarnings.clear(); | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| Path path = resolved.get(); | ||
|
|
||
| this.lastResolvedBlgPath = Optional.of(path); | ||
| try { | ||
| BibtexLogParser parser = new BibtexLogParser(); | ||
| List<BibWarning> warnings = parser.parseBiblog(path); | ||
| List<IntegrityMessage> newWarnings = BibWarningToIntegrityMessageConverter.convert(warnings, databaseContext); | ||
| blgWarnings.setAll(newWarnings); | ||
| return Optional.of(newWarnings); | ||
| } catch (IOException e) { | ||
| blgWarnings.clear(); | ||
| throw new JabRefException( | ||
| "Failed to parse .blg file", | ||
| Localization.lang("Could not read BibTeX log file. Please check the file path and try again."), | ||
| e | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| public ObservableList<IntegrityMessage> getBlgWarningsObservable() { | ||
| return blgWarnings; | ||
| } | ||
|
|
||
| public StringProperty pathProperty() { | ||
| return path; | ||
| } | ||
|
|
||
| public void setBlgFilePath(Path path) { | ||
| metaData.setBlgFilePath(user, path); | ||
| this.path.set(path.toString()); | ||
| this.lastResolvedBlgPath = Optional.of(path); | ||
| this.userManuallySelectedBlgFile = true; | ||
| } | ||
|
|
||
| public void resetBlgFilePath() { | ||
| metaData.clearBlgFilePath(user); | ||
| userManuallySelectedBlgFile = false; | ||
| Optional<Path> resolved = BibLogPathResolver.resolve(metaData, bibPath, user); | ||
| if (resolved.isEmpty()) { | ||
| path.set(""); | ||
| lastResolvedBlgPath = Optional.empty(); | ||
| return; | ||
| } | ||
|
|
||
| Path resolvedPath = resolved.get(); | ||
| path.set(resolvedPath.toString()); | ||
| lastResolvedBlgPath = Optional.of(resolvedPath); | ||
| } | ||
|
Comment on lines
+101
to
+114
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 does not follow the fail-fast principle. It should return early if the condition is not met, instead of nesting logic inside an if statement. |
||
|
|
||
| public Optional<Path> getResolvedBlgPath() { | ||
| return BibLogPathResolver.resolve(metaData, bibPath, user) | ||
| .filter(Files::exists); | ||
| } | ||
|
|
||
| public Path getInitialDirectory() { | ||
| return bibPath.flatMap(path -> Optional.ofNullable(path.getParent())) | ||
| .orElse(Path.of(System.getProperty("user.home"))); | ||
|
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. Is this cross-platform ( 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. Not on Windows XP, but this is acceptable: https://stackoverflow.com/q/585534/873282 |
||
| } | ||
|
|
||
| public boolean wasBlgFileManuallySelected() { | ||
| return userManuallySelectedBlgFile; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.