From e8f4f4fc701e4055990aa51faa08cb9568eaead5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Thu, 1 Aug 2019 16:45:37 +0200 Subject: [PATCH 1/7] Update for adding latest changes (no final version) --- .../jabref/gui/entryeditor/EntryEditor.java | 2 +- .../gui/entryeditor/LatexCitationsTab.java | 44 +++++++++++--- .../LatexCitationsTabViewModel.java | 59 +++++++++++++------ .../texparser/ParseTexDialogViewModel.java | 6 +- .../logic/texparser/DefaultTexParser.java | 9 ++- 5 files changed, 90 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 37a77ac9aee..1d5688e5f7d 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -291,7 +291,7 @@ private List createTabs() { tabs.add(sourceTab); // LaTeX citations tab - tabs.add(new LatexCitationsTab(databaseContext, preferencesService, taskExecutor)); + tabs.add(new LatexCitationsTab(databaseContext, preferencesService, taskExecutor, dialogService)); return tabs; } diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java index 1e36be7b54a..861db831c1b 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java @@ -1,17 +1,23 @@ package org.jabref.gui.entryeditor; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Optional; import java.util.stream.Collectors; +import javafx.scene.control.Button; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ScrollPane; import javafx.scene.control.Tooltip; +import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.text.Text; +import org.jabref.gui.Dialog; +import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; @@ -22,12 +28,18 @@ public class LatexCitationsTab extends EntryEditorTab { + private final BibDatabaseContext databaseContext; + private final PreferencesService preferencesService; + private final DialogService dialogService; private final LatexCitationsTabViewModel viewModel; private final StackPane searchPane; private final ProgressIndicator progressIndicator; public LatexCitationsTab(BibDatabaseContext databaseContext, PreferencesService preferencesService, - TaskExecutor taskExecutor) { + TaskExecutor taskExecutor, DialogService dialogService) { + this.databaseContext = databaseContext; + this.preferencesService = preferencesService; + this.dialogService = dialogService; this.viewModel = new LatexCitationsTabViewModel(databaseContext, preferencesService, taskExecutor); this.searchPane = new StackPane(); this.progressIndicator = new ProgressIndicator(); @@ -62,6 +74,26 @@ private void setSearchPane() { }); } + private VBox getLatexDirBox() { + Path basePath = viewModel.directoryProperty().get(); + Text latexDirText = new Text(String.format("Current LaTeX file directory: %s", basePath)); + Button latexDirButton = new Button("Set LaTeX file directory"); + latexDirButton.setOnAction(e -> browseButtonClicked()); + return new VBox(latexDirText, latexDirButton); + } + + private void browseButtonClicked() { + Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) + .orElseGet(preferencesService::getWorkingDir); + + DirectoryDialogConfiguration directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() + .withInitialDirectory(newDirectory).build(); + + dialogService.showDirectorySelectionDialog(directoryDialogConfiguration).ifPresent(selectedDirectory -> { + databaseContext.getMetaData().setLaTexFileDirectory(preferencesService.getUser(), selectedDirectory.toAbsolutePath()); + }); + } + private ScrollPane getCitationsPane() { Text titleText = new Text(Localization.lang("Citations found")); titleText.getStyleClass().add("recommendation-heading"); @@ -71,6 +103,8 @@ private ScrollPane getCitationsPane() { citationsBox.getChildren().addAll(viewModel.getCitationList().stream().map( citation -> citation.getDisplayGraphic(basePath, Optional.empty())).collect(Collectors.toList())); + citationsBox.getChildren().add(getLatexDirBox()); + ScrollPane citationsPane = new ScrollPane(); citationsPane.setContent(citationsBox); @@ -84,11 +118,7 @@ private ScrollPane getNotFoundPane() { Text notFoundText = new Text(Localization.lang("No LaTeX files containing this entry were found.")); notFoundText.setStyle("-fx-font-size: 110%"); - Text notFoundAdviceText = new Text(Localization.lang( - "You can set the LaTeX file directory in the 'Library properties' dialog.")); - notFoundAdviceText.setStyle("-fx-font-weight: bold;"); - - VBox notFoundBox = new VBox(20, notFoundTitleText, notFoundText, notFoundAdviceText); + VBox notFoundBox = new VBox(20, notFoundTitleText, notFoundText, getLatexDirBox()); ScrollPane notFoundPane = new ScrollPane(); notFoundPane.setContent(notFoundBox); @@ -103,7 +133,7 @@ private ScrollPane getErrorPane() { Text errorMessageText = new Text(viewModel.searchErrorProperty().get()); errorMessageText.setStyle("-fx-font-family: monospace;-fx-font-size: 120%;"); - VBox errorBox = new VBox(20, errorTitleText, errorMessageText); + VBox errorBox = new VBox(20, errorTitleText, errorMessageText, getLatexDirBox()); ScrollPane errorPane = new ScrollPane(); errorPane.setContent(errorBox); diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 239027f68cf..4110e989dba 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -3,7 +3,9 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.concurrent.Future; import java.util.stream.Collectors; @@ -33,13 +35,6 @@ public class LatexCitationsTabViewModel extends AbstractViewModel { - enum Status { - IN_PROGRESS, - CITATIONS_FOUND, - NO_RESULTS, - ERROR - } - private static final Logger LOGGER = LoggerFactory.getLogger(LatexCitationsTabViewModel.class); private static final String TEX_EXT = ".tex"; private final BibDatabaseContext databaseContext; @@ -50,6 +45,8 @@ enum Status { private final ObjectProperty status; private final StringProperty searchError; private Future searchTask; + private TexParserResult texParserResult; + private List texFiles; public LatexCitationsTabViewModel(BibDatabaseContext databaseContext, PreferencesService preferencesService, TaskExecutor taskExecutor) { @@ -110,25 +107,51 @@ private void cancelSearch() { searchTask.cancel(true); } - private Status searchAndParse(String citeKey) throws IOException { - directory.set(databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) - .orElseGet(preferencesService::getWorkingDir)); - List texFiles; - try (Stream filesStream = Files.walk(directory.get())) { - texFiles = filesStream.filter(path -> path.toFile().isFile() && path.toString().endsWith(TEX_EXT)) - .collect(Collectors.toList()); + private Status searchAndParse(String citeKey) { + Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) + .orElseGet(preferencesService::getWorkingDir); + + if (texParserResult == null || !newDirectory.equals(directory.get())) { + directory.set(newDirectory); + texFiles = new ArrayList<>(); + search(newDirectory); + texParserResult = new DefaultTexParser().parse(texFiles); + } + + citationList.setAll(texParserResult.getCitationsByKey(citeKey).stream().map(CitationViewModel::new).collect(Collectors.toList())); + + return citationList.isEmpty() ? Status.NO_RESULTS : Status.CITATIONS_FOUND; + } + + private void search(Path directory) { + Map> fileListPartition; + try (Stream filesStream = Files.list(directory)) { + fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { LOGGER.error("Error searching files", e); - throw new IOException("Error searching files", e); + return; } - TexParserResult texParserResult = new DefaultTexParser().parse(citeKey, texFiles); - citationList.setAll(texParserResult.getCitations().values().stream().map(CitationViewModel::new).collect(Collectors.toList())); + List subDirectories = fileListPartition.get(true); + List files = fileListPartition.get(false) + .stream() + .filter(path -> path.toString().endsWith(TEX_EXT)) + .collect(Collectors.toList()); + texFiles.addAll(files); - return citationList.isEmpty() ? Status.NO_RESULTS : Status.CITATIONS_FOUND; + for (Path subDirectory : subDirectories) { + search(subDirectory); + } } public boolean shouldShow() { return preferencesService.getEntryEditorPreferences().shouldShowLatexCitationsTab(); } + + enum Status { + IN_PROGRESS, + CITATIONS_FOUND, + NO_RESULTS, + ERROR + } } diff --git a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java index ef6b25f06f8..50ac7b2025b 100644 --- a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java +++ b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java @@ -34,9 +34,12 @@ import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator; import de.saxsys.mvvmfx.utils.validation.ValidationMessage; import de.saxsys.mvvmfx.utils.validation.ValidationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ParseTexDialogViewModel extends AbstractViewModel { + private static final Logger LOGGER = LoggerFactory.getLogger(ParseTexDialogViewModel.class); private static final String TEX_EXT = ".tex"; private final DialogService dialogService; private final TaskExecutor taskExecutor; @@ -140,7 +143,8 @@ private FileNodeViewModel searchDirectory(Path directory) throws IOException { try (Stream filesStream = Files.list(directory)) { fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { - throw new IOException("Error searching files", e); + LOGGER.warn("Error searching files", e); + return parent; } List subDirectories = fileListPartition.get(true); diff --git a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java index c7dcc0d5327..3486112e0ab 100644 --- a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java +++ b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.LineNumberReader; +import java.io.UncheckedIOException; import java.nio.channels.ClosedChannelException; import java.nio.file.Files; import java.nio.file.Path; @@ -98,10 +99,12 @@ public TexParserResult parse(String entryKey, List texFiles) { matchNestedFile(file, texFiles, referencedFiles, line); } } catch (ClosedChannelException e) { - LOGGER.info("Parsing has been interrupted"); - return texParserResult; + LOGGER.error("Parsing has been interrupted"); + return null; } catch (IOException e) { - LOGGER.error("Error opening a TEX file", e); + LOGGER.error("Error opening a TEX file: IOException"); + } catch (UncheckedIOException e) { + LOGGER.error("Error searching files: UncheckedIOException"); } } From e931f3ea775a2b4d5922031a85deef582ebcdc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Thu, 1 Aug 2019 17:07:51 +0200 Subject: [PATCH 2/7] Fix small issues --- .../gui/entryeditor/LatexCitationsTab.java | 3 --- .../logic/texparser/DefaultTexParser.java | 19 ++++++++++--------- src/main/resources/l10n/JabRef_en.properties | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java index 861db831c1b..a1486b7410c 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java @@ -1,7 +1,6 @@ package org.jabref.gui.entryeditor; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; import java.util.stream.Collectors; @@ -9,12 +8,10 @@ import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ScrollPane; import javafx.scene.control.Tooltip; -import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.text.Text; -import org.jabref.gui.Dialog; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.util.DirectoryDialogConfiguration; diff --git a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java index 3486112e0ab..99f541fa4f9 100644 --- a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java +++ b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java @@ -86,6 +86,11 @@ public TexParserResult parse(String entryKey, List texFiles) { List referencedFiles = new ArrayList<>(); for (Path file : texFiles) { + if (!Files.exists(file)) { + LOGGER.error("File does not exist: " + file.toString()); + continue; + } + try (LineNumberReader lineNumberReader = new LineNumberReader(Files.newBufferedReader(file))) { for (String line = lineNumberReader.readLine(); line != null; line = lineNumberReader.readLine()) { // Skip comments and blank lines. @@ -136,16 +141,12 @@ private void matchNestedFile(Path file, List texFiles, List referenc Matcher includeMatch = INCLUDE_PATTERN.matcher(line); while (includeMatch.find()) { - StringBuilder include = new StringBuilder(includeMatch.group(INCLUDE_GROUP)); - - if (!include.toString().endsWith(TEX_EXT)) { - include.append(TEX_EXT); - } + String include = includeMatch.group(INCLUDE_GROUP); - Path folder = file.getParent(); - Path inputFile = (folder == null) - ? Paths.get(include.toString()) - : folder.resolve(include.toString()); + Path inputFile = file.toAbsolutePath().getParent().resolve( + include.endsWith(TEX_EXT) + ? include + : String.format("%s%s", include, TEX_EXT)); if (!texFiles.contains(inputFile)) { referencedFiles.add(inputFile); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index d7c11a32df4..4c4151232fd 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2120,5 +2120,4 @@ Search\ citations\ for\ this\ entry\ in\ LaTeX\ files=Search citations for this Citations\ found=Citations found No\ citations\ found=No citations found No\ LaTeX\ files\ containing\ this\ entry\ were\ found.=No LaTeX files containing this entry were found. -You\ can\ set\ the\ LaTeX\ file\ directory\ in\ the\ 'Library\ properties'\ dialog.=You can set the LaTeX file directory in the 'Library properties' dialog. Selected\ entry\ does\ not\ have\ an\ associated\ BibTeX\ key.=Selected entry does not have an associated BibTeX key. From 387aeeb4fc683b93f3da0a80ae73437e467bedb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Fri, 2 Aug 2019 00:29:00 +0200 Subject: [PATCH 3/7] Update for improving code --- .../gui/entryeditor/LatexCitationsTab.java | 39 ++++------------ .../LatexCitationsTabViewModel.java | 44 ++++++++++++------- .../texparser/ParseTexDialogViewModel.java | 2 +- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java index a1486b7410c..975a29d09d2 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java @@ -1,6 +1,5 @@ package org.jabref.gui.entryeditor; -import java.nio.file.Path; import java.util.Optional; import java.util.stream.Collectors; @@ -14,7 +13,6 @@ import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; -import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; @@ -25,19 +23,13 @@ public class LatexCitationsTab extends EntryEditorTab { - private final BibDatabaseContext databaseContext; - private final PreferencesService preferencesService; - private final DialogService dialogService; private final LatexCitationsTabViewModel viewModel; private final StackPane searchPane; private final ProgressIndicator progressIndicator; public LatexCitationsTab(BibDatabaseContext databaseContext, PreferencesService preferencesService, TaskExecutor taskExecutor, DialogService dialogService) { - this.databaseContext = databaseContext; - this.preferencesService = preferencesService; - this.dialogService = dialogService; - this.viewModel = new LatexCitationsTabViewModel(databaseContext, preferencesService, taskExecutor); + this.viewModel = new LatexCitationsTabViewModel(databaseContext, preferencesService, taskExecutor, dialogService); this.searchPane = new StackPane(); this.progressIndicator = new ProgressIndicator(); @@ -71,36 +63,23 @@ private void setSearchPane() { }); } - private VBox getLatexDirBox() { - Path basePath = viewModel.directoryProperty().get(); - Text latexDirText = new Text(String.format("Current LaTeX file directory: %s", basePath)); + // TODO: Localization + private VBox getLatexDirectoryBox() { + Text latexDirText = new Text(String.format("Current LaTeX file directory: %s", viewModel.directoryProperty().get())); Button latexDirButton = new Button("Set LaTeX file directory"); - latexDirButton.setOnAction(e -> browseButtonClicked()); + latexDirButton.setOnAction(event -> viewModel.setLatexDirectory()); return new VBox(latexDirText, latexDirButton); } - private void browseButtonClicked() { - Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) - .orElseGet(preferencesService::getWorkingDir); - - DirectoryDialogConfiguration directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() - .withInitialDirectory(newDirectory).build(); - - dialogService.showDirectorySelectionDialog(directoryDialogConfiguration).ifPresent(selectedDirectory -> { - databaseContext.getMetaData().setLaTexFileDirectory(preferencesService.getUser(), selectedDirectory.toAbsolutePath()); - }); - } - private ScrollPane getCitationsPane() { Text titleText = new Text(Localization.lang("Citations found")); titleText.getStyleClass().add("recommendation-heading"); VBox citationsBox = new VBox(20, titleText); - Path basePath = viewModel.directoryProperty().get(); citationsBox.getChildren().addAll(viewModel.getCitationList().stream().map( - citation -> citation.getDisplayGraphic(basePath, Optional.empty())).collect(Collectors.toList())); + citation -> citation.getDisplayGraphic(viewModel.directoryProperty().get(), Optional.empty())).collect(Collectors.toList())); - citationsBox.getChildren().add(getLatexDirBox()); + citationsBox.getChildren().add(getLatexDirectoryBox()); ScrollPane citationsPane = new ScrollPane(); citationsPane.setContent(citationsBox); @@ -115,7 +94,7 @@ private ScrollPane getNotFoundPane() { Text notFoundText = new Text(Localization.lang("No LaTeX files containing this entry were found.")); notFoundText.setStyle("-fx-font-size: 110%"); - VBox notFoundBox = new VBox(20, notFoundTitleText, notFoundText, getLatexDirBox()); + VBox notFoundBox = new VBox(20, notFoundTitleText, notFoundText, getLatexDirectoryBox()); ScrollPane notFoundPane = new ScrollPane(); notFoundPane.setContent(notFoundBox); @@ -130,7 +109,7 @@ private ScrollPane getErrorPane() { Text errorMessageText = new Text(viewModel.searchErrorProperty().get()); errorMessageText.setStyle("-fx-font-family: monospace;-fx-font-size: 120%;"); - VBox errorBox = new VBox(20, errorTitleText, errorMessageText, getLatexDirBox()); + VBox errorBox = new VBox(20, errorTitleText, errorMessageText, getLatexDirectoryBox()); ScrollPane errorPane = new ScrollPane(); errorPane.setContent(errorBox); diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 4110e989dba..83b459dffca 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -20,8 +20,10 @@ import javafx.collections.ObservableList; import org.jabref.gui.AbstractViewModel; +import org.jabref.gui.DialogService; import org.jabref.gui.texparser.CitationViewModel; import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.texparser.DefaultTexParser; @@ -35,24 +37,32 @@ public class LatexCitationsTabViewModel extends AbstractViewModel { + enum Status { + IN_PROGRESS, + CITATIONS_FOUND, + NO_RESULTS, + ERROR + } + private static final Logger LOGGER = LoggerFactory.getLogger(LatexCitationsTabViewModel.class); private static final String TEX_EXT = ".tex"; private final BibDatabaseContext databaseContext; private final PreferencesService preferencesService; private final TaskExecutor taskExecutor; + private final DialogService dialogService; private final ObjectProperty directory; private final ObservableList citationList; private final ObjectProperty status; private final StringProperty searchError; private Future searchTask; private TexParserResult texParserResult; - private List texFiles; public LatexCitationsTabViewModel(BibDatabaseContext databaseContext, PreferencesService preferencesService, - TaskExecutor taskExecutor) { + TaskExecutor taskExecutor, DialogService dialogService) { this.databaseContext = databaseContext; this.preferencesService = preferencesService; this.taskExecutor = taskExecutor; + this.dialogService = dialogService; this.directory = new SimpleObjectProperty<>(null); this.citationList = FXCollections.observableArrayList(); this.status = new SimpleObjectProperty<>(Status.IN_PROGRESS); @@ -113,8 +123,7 @@ private Status searchAndParse(String citeKey) { if (texParserResult == null || !newDirectory.equals(directory.get())) { directory.set(newDirectory); - texFiles = new ArrayList<>(); - search(newDirectory); + List texFiles = searchDirectory(newDirectory, new ArrayList<>()); texParserResult = new DefaultTexParser().parse(texFiles); } @@ -123,13 +132,13 @@ private Status searchAndParse(String citeKey) { return citationList.isEmpty() ? Status.NO_RESULTS : Status.CITATIONS_FOUND; } - private void search(Path directory) { + private List searchDirectory(Path directory, List texFiles) { Map> fileListPartition; try (Stream filesStream = Files.list(directory)) { fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { LOGGER.error("Error searching files", e); - return; + return texFiles; } List subDirectories = fileListPartition.get(true); @@ -138,20 +147,23 @@ private void search(Path directory) { .filter(path -> path.toString().endsWith(TEX_EXT)) .collect(Collectors.toList()); texFiles.addAll(files); + subDirectories.forEach(subDirectory -> searchDirectory(subDirectory, texFiles)); - for (Path subDirectory : subDirectories) { - search(subDirectory); - } + return texFiles; } - public boolean shouldShow() { - return preferencesService.getEntryEditorPreferences().shouldShowLatexCitationsTab(); + public void setLatexDirectory() { + Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) + .orElseGet(preferencesService::getWorkingDir); + + DirectoryDialogConfiguration directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() + .withInitialDirectory(newDirectory).build(); + + dialogService.showDirectorySelectionDialog(directoryDialogConfiguration).ifPresent(selectedDirectory -> + databaseContext.getMetaData().setLaTexFileDirectory(preferencesService.getUser(), selectedDirectory.toAbsolutePath())); } - enum Status { - IN_PROGRESS, - CITATIONS_FOUND, - NO_RESULTS, - ERROR + public boolean shouldShow() { + return preferencesService.getEntryEditorPreferences().shouldShowLatexCitationsTab(); } } diff --git a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java index 50ac7b2025b..6365b529202 100644 --- a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java +++ b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java @@ -143,7 +143,7 @@ private FileNodeViewModel searchDirectory(Path directory) throws IOException { try (Stream filesStream = Files.list(directory)) { fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { - LOGGER.warn("Error searching files", e); + LOGGER.error("Error searching files", e); return parent; } From 1bb8356d9486cbcbb9bec8bc55f8c06389a95aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Fri, 2 Aug 2019 00:46:42 +0200 Subject: [PATCH 4/7] Add localization keys --- .../org/jabref/gui/entryeditor/LatexCitationsTab.java | 10 +++++----- .../gui/entryeditor/LatexCitationsTabViewModel.java | 5 +---- src/main/resources/l10n/JabRef_en.properties | 2 ++ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java index 975a29d09d2..396351e85d8 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java @@ -63,12 +63,12 @@ private void setSearchPane() { }); } - // TODO: Localization private VBox getLatexDirectoryBox() { - Text latexDirText = new Text(String.format("Current LaTeX file directory: %s", viewModel.directoryProperty().get())); - Button latexDirButton = new Button("Set LaTeX file directory"); - latexDirButton.setOnAction(event -> viewModel.setLatexDirectory()); - return new VBox(latexDirText, latexDirButton); + Text latexDirectoryText = new Text(String.format("%s: %s", Localization.lang("Current search directory"), + viewModel.directoryProperty().get())); + Button latexDirectoryButton = new Button(Localization.lang("Set LaTeX file directory")); + latexDirectoryButton.setOnAction(event -> viewModel.setLatexDirectory()); + return new VBox(15, latexDirectoryText, latexDirectoryButton); } private ScrollPane getCitationsPane() { diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 83b459dffca..0508b4b9e36 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -153,11 +153,8 @@ private List searchDirectory(Path directory, List texFiles) { } public void setLatexDirectory() { - Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) - .orElseGet(preferencesService::getWorkingDir); - DirectoryDialogConfiguration directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() - .withInitialDirectory(newDirectory).build(); + .withInitialDirectory(directory.get()).build(); dialogService.showDirectorySelectionDialog(directoryDialogConfiguration).ifPresent(selectedDirectory -> databaseContext.getMetaData().setLaTexFileDirectory(preferencesService.getUser(), selectedDirectory.toAbsolutePath())); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 4c4151232fd..09a848eedb2 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2121,3 +2121,5 @@ Citations\ found=Citations found No\ citations\ found=No citations found No\ LaTeX\ files\ containing\ this\ entry\ were\ found.=No LaTeX files containing this entry were found. Selected\ entry\ does\ not\ have\ an\ associated\ BibTeX\ key.=Selected entry does not have an associated BibTeX key. +Current\ search\ directory=Current search directory +Set\ LaTeX\ file\ directory=Set LaTeX file directory From e1420b63505e9d6f7b6d356c4a55c52eacc3a47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Fri, 2 Aug 2019 00:59:49 +0200 Subject: [PATCH 5/7] Update styles --- .../java/org/jabref/gui/entryeditor/LatexCitationsTab.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java index 396351e85d8..a1bb0fa7869 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTab.java @@ -64,10 +64,12 @@ private void setSearchPane() { } private VBox getLatexDirectoryBox() { - Text latexDirectoryText = new Text(String.format("%s: %s", Localization.lang("Current search directory"), + Text latexDirectoryText = new Text(String.format("%n%n%s: %s", Localization.lang("Current search directory"), viewModel.directoryProperty().get())); + latexDirectoryText.setStyle("-fx-font-weight: bold;"); Button latexDirectoryButton = new Button(Localization.lang("Set LaTeX file directory")); latexDirectoryButton.setOnAction(event -> viewModel.setLatexDirectory()); + return new VBox(15, latexDirectoryText, latexDirectoryButton); } @@ -92,7 +94,7 @@ private ScrollPane getNotFoundPane() { notFoundTitleText.getStyleClass().add("recommendation-heading"); Text notFoundText = new Text(Localization.lang("No LaTeX files containing this entry were found.")); - notFoundText.setStyle("-fx-font-size: 110%"); + notFoundText.setStyle("-fx-font-size: 110%;"); VBox notFoundBox = new VBox(20, notFoundTitleText, notFoundText, getLatexDirectoryBox()); ScrollPane notFoundPane = new ScrollPane(); From 269e79ce176faf1b3773ed2ac26bde3a29772ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Fri, 2 Aug 2019 01:15:00 +0200 Subject: [PATCH 6/7] Remove unused code and improve exceptions handling --- .../LatexCitationsTabViewModel.java | 2 +- .../texparser/ParseTexDialogViewModel.java | 4 +-- .../logic/texparser/DefaultTexParser.java | 33 +++++-------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 0508b4b9e36..eeccb4c4618 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -137,7 +137,7 @@ private List searchDirectory(Path directory, List texFiles) { try (Stream filesStream = Files.list(directory)) { fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { - LOGGER.error("Error searching files", e); + LOGGER.error(String.format("Error searching files: %s", e.getMessage())); return texFiles; } diff --git a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java index 6365b529202..7fd3b6eb3a4 100644 --- a/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java +++ b/src/main/java/org/jabref/gui/texparser/ParseTexDialogViewModel.java @@ -134,7 +134,7 @@ public void searchButtonClicked() { private FileNodeViewModel searchDirectory(Path directory) throws IOException { if (directory == null || !directory.toFile().exists() || !directory.toFile().isDirectory()) { - throw new IOException("Error searching an invalid directory"); + throw new IOException(String.format("Error searching files: %s", directory)); } FileNodeViewModel parent = new FileNodeViewModel(directory); @@ -143,7 +143,7 @@ private FileNodeViewModel searchDirectory(Path directory) throws IOException { try (Stream filesStream = Files.list(directory)) { fileListPartition = filesStream.collect(Collectors.partitioningBy(path -> path.toFile().isDirectory())); } catch (IOException e) { - LOGGER.error("Error searching files", e); + LOGGER.error(String.format("Error searching files: %s", e.getMessage())); return parent; } diff --git a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java index 99f541fa4f9..cc6e548e278 100644 --- a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java +++ b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java @@ -59,35 +59,24 @@ public TexParserResult getTexParserResult() { @Override public TexParserResult parse(String citeString) { - matchCitation(null, Paths.get(""), 1, citeString); + matchCitation(Paths.get(""), 1, citeString); return texParserResult; } @Override public TexParserResult parse(Path texFile) { - return parse(null, Collections.singletonList(texFile)); + return parse(Collections.singletonList(texFile)); } @Override public TexParserResult parse(List texFiles) { - return parse(null, texFiles); - } - - /** - * Parse a list of TEX files for searching a given entry. - * - * @param entryKey String that contains the entry key we are searching (null for all entries) - * @param texFiles List of Path objects linked to a TEX file - * @return a TexParserResult, which contains all data related to the bibliographic entries - */ - public TexParserResult parse(String entryKey, List texFiles) { texParserResult.addFiles(texFiles); List referencedFiles = new ArrayList<>(); for (Path file : texFiles) { if (!Files.exists(file)) { - LOGGER.error("File does not exist: " + file.toString()); + LOGGER.error(String.format("File does not exist: %s", file)); continue; } @@ -97,25 +86,20 @@ public TexParserResult parse(String entryKey, List texFiles) { if (line.isEmpty() || line.charAt(0) == '%') { continue; } - // Skip the citation matching if the line does not contain the given entry to speed up the parsing. - if (entryKey == null || line.contains(entryKey)) { - matchCitation(entryKey, file, lineNumberReader.getLineNumber(), line); - } + matchCitation(file, lineNumberReader.getLineNumber(), line); matchNestedFile(file, texFiles, referencedFiles, line); } } catch (ClosedChannelException e) { LOGGER.error("Parsing has been interrupted"); return null; - } catch (IOException e) { - LOGGER.error("Error opening a TEX file: IOException"); - } catch (UncheckedIOException e) { - LOGGER.error("Error searching files: UncheckedIOException"); + } catch (IOException | UncheckedIOException e) { + LOGGER.error(String.format("Error searching files: %s", e.getMessage())); } } // Parse all files referenced by TEX files, recursively. if (!referencedFiles.isEmpty()) { - parse(entryKey, referencedFiles); + parse(referencedFiles); } return texParserResult; @@ -124,12 +108,11 @@ public TexParserResult parse(String entryKey, List texFiles) { /** * Find cites along a specific line and store them. */ - private void matchCitation(String entryKey, Path file, int lineNumber, String line) { + private void matchCitation(Path file, int lineNumber, String line) { Matcher citeMatch = CITE_PATTERN.matcher(line); while (citeMatch.find()) { Arrays.stream(citeMatch.group(CITE_GROUP).split(",")) - .filter(key -> entryKey == null || key.equals(entryKey)) .forEach(key -> texParserResult.addKey(key, file, lineNumber, citeMatch.start(), citeMatch.end(), line)); } } From cf96f76873dfc5c45d9f9ba00d406a83953e3710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=A9ndez?= Date: Fri, 2 Aug 2019 01:37:59 +0200 Subject: [PATCH 7/7] Add latest improvements --- .../gui/entryeditor/LatexCitationsTabViewModel.java | 9 +++++++-- .../org/jabref/logic/texparser/DefaultTexParser.java | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index eeccb4c4618..f0bfedd16d3 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -102,7 +102,7 @@ private void startSearch(String citeKey) { .onRunning(() -> status.set(Status.IN_PROGRESS)) .onSuccess(status::set) .onFailure(error -> { - searchError.set(String.format("%s%n%n%s", error.getMessage(), error.getCause())); + searchError.set(error.getMessage()); status.set(Status.ERROR); }) .executeWith(taskExecutor); @@ -117,12 +117,17 @@ private void cancelSearch() { searchTask.cancel(true); } - private Status searchAndParse(String citeKey) { + private Status searchAndParse(String citeKey) throws IOException { Path newDirectory = databaseContext.getMetaData().getLaTexFileDirectory(preferencesService.getUser()) .orElseGet(preferencesService::getWorkingDir); if (texParserResult == null || !newDirectory.equals(directory.get())) { directory.set(newDirectory); + + if (Files.notExists(newDirectory)) { + throw new IOException(String.format("Current search directory does not exist: %s", newDirectory)); + } + List texFiles = searchDirectory(newDirectory, new ArrayList<>()); texParserResult = new DefaultTexParser().parse(texFiles); } diff --git a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java index cc6e548e278..2bd0d6f1bcf 100644 --- a/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java +++ b/src/main/java/org/jabref/logic/texparser/DefaultTexParser.java @@ -75,7 +75,7 @@ public TexParserResult parse(List texFiles) { List referencedFiles = new ArrayList<>(); for (Path file : texFiles) { - if (!Files.exists(file)) { + if (Files.notExists(file)) { LOGGER.error(String.format("File does not exist: %s", file)); continue; }