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

Implement journal abbreviation storage in separate directory (Closes #10557) #12036

Closed
wants to merge 8 commits into from
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,41 +64,76 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We changed instances of 'Search Selected' to 'Search Pre-configured' in Web Search Preferences UI. [#11871](https://github.com/JabRef/jabref/pull/11871)
- We added a new CSS style class `main-table` for the main table. [#11881](https://github.com/JabRef/jabref/pull/11881)
- When renaming a file, the old extension is now used if there is none provided in the new name. [#11903](https://github.com/JabRef/jabref/issues/11903)
- We added the ability for users to change the journal abbreviation directory via the preferences dialog. The chosen directory is stored as a preference. [#10557](https://github.com/JabRef/jabref/issues/10557)

### Fixed

- We fixed an issue where certain actions were not disabled when no libraries were open. [#11923](https://github.com/JabRef/jabref/issues/11923)

Copy link
Member

Choose a reason for hiding this comment

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

Please revert the changes with the spaces here

- We fixed an issue where the "Check for updates" preference was not saved. [#11485](https://github.com/JabRef/jabref/pull/11485)

- We fixed an issue where an exception was thrown after changing "show preview as a tab" in the preferences. [#11515](https://github.com/JabRef/jabref/pull/11515)

- We fixed an issue where JabRef put file paths as absolute path when an entry was created using drag and drop of a PDF file. [#11173](https://github.com/JabRef/jabref/issues/11173)

- We fixed an issue that online and offline mode for new library creation were handled incorrectly. [#11565](https://github.com/JabRef/jabref/pull/11565)

- We fixed an issue with colors in the search bar when dark theme is enabled. [#11569](https://github.com/JabRef/jabref/issues/11569)

- We fixed an issue with query transformers (JStor and others). [#11643](https://github.com/JabRef/jabref/pull/11643)

- We fixed an issue where a new unsaved library was not marked with an asterisk. [#11519](https://github.com/JabRef/jabref/pull/11519)

- We fixed an issue where JabRef starts without window decorations. [#11440](https://github.com/JabRef/jabref/pull/11440)

- We fixed an issue where the entry preview highlight was not working when searching before opening the entry editor. [#11659](https://github.com/JabRef/jabref/pull/11659)

- We fixed an issue where text in Dark mode inside "Citation information" was not readable. [#11512](https://github.com/JabRef/jabref/issues/11512)

- We fixed an issue where the selection of an entry in the table lost after searching for a group. [#3176](https://github.com/JabRef/jabref/issues/3176)

- We fixed the non-functionality of the option "Automatically sync bibliography when inserting citations" in the OpenOffice panel, when enabled in case of JStyles. [#11684](https://github.com/JabRef/jabref/issues/11684)

- We fixed an issue where the library was not marked changed after a migration. [#11542](https://github.com/JabRef/jabref/pull/11542)

- We fixed an issue where rebuilding the full-text search index was not working. [#11374](https://github.com/JabRef/jabref/issues/11374)

- We fixed an issue where the progress of indexing linked files showed an incorrect number of files. [#11378](https://github.com/JabRef/jabref/issues/11378)

- We fixed an issue where the full-text search results were incomplete. [#8626](https://github.com/JabRef/jabref/issues/8626)

- We fixed an issue where search result highlighting was incorrectly highlighting the boolean operators. [#11595](https://github.com/JabRef/jabref/issues/11595)

- We fixed an issue where search result highlighting was broken at complex searches. [#8067](https://github.com/JabRef/jabref/issues/8067)

- We fixed an exception when searching for unlinked files. [#11731](https://github.com/JabRef/jabref/issues/11731)

- We fixed an issue with the link to the full text at the BVB fetcher. [#11852](https://github.com/JabRef/jabref/pull/11852)

- We fixed an issue where two contradicting notifications were shown when cutting an entry in the main table. [#11724](https://github.com/JabRef/jabref/pull/11724)

- We fixed an issue where unescaped braces in the arXiv fetcher were not treated. [#11704](https://github.com/JabRef/jabref/issues/11704)

- We fixed an issue where HTML instead of the fulltext pdf was downloaded when importing arXiv entries. [#4913](https://github.com/JabRef/jabref/issues/4913)

- We fixed an issue where the keywords and crossref fields were not properly focused. [#11177](https://github.com/JabRef/jabref/issues/11177)

- We fixed handling of `\"` in [bracketed patterns](https://docs.jabref.org/setup/citationkeypatterns) containing a RegEx. [#11967](https://github.com/JabRef/jabref/pull/11967)

- We fixed an issue where the Undo/Redo buttons were active even when all libraries are closed. [#11837](https://github.com/JabRef/jabref/issues/11837)

- We fixed an issue where recently opened files were not displayed in the main menu properly. [#9042](https://github.com/JabRef/jabref/issues/9042)

- We fixed an issue where the DOI lookup would show an error when a DOI was found for an entry. [#11850](https://github.com/JabRef/jabref/issues/11850)

- We fixed an issue where <kbd>Tab</kbd> cannot be used to jump to next field in some single-line fields. [#11785](https://github.com/JabRef/jabref/issues/11785)

- We fixed an issue where web search preferences "Custom API key" table modifications not discarded. [#11925](https://github.com/JabRef/jabref/issues/11925)

- We fixed an issue where JabRef did not automatically create and add a `custom.csv` file to the Journal lists when it was missing from the specified directory. [#10557](https://github.com/JabRef/jabref/issues/10557)



### Removed

- We removed support for case-sensitive and exact search. [#11542](https://github.com/JabRef/jabref/pull/11542)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
</Button>
</HBox>

<HBox spacing="10.0" alignment="CENTER_LEFT">
<Button fx:id="changeDirectoryButton" onAction="#handleChangeDirectory" text="Change Directory"/>
<CustomTextField fx:id="directoryPathField" editable="false" minWidth="200"/>
</HBox>

<VBox spacing="10.0" HBox.hgrow="ALWAYS">
<CustomTextField fx:id="searchBox" promptText="%Filter" VBox.vgrow="NEVER">
<VBox.margin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public class JournalAbbreviationsTab extends AbstractPreferenceTabView<JournalAb
@FXML private Button addAbbreviationButton;
@FXML private Button removeAbbreviationListButton;

@FXML private Button changeDirectoryButton;
@FXML private CustomTextField directoryPathField;

@FXML private CustomTextField searchBox;
@FXML private CheckBox useFJournal;

Expand Down Expand Up @@ -87,6 +90,8 @@ private void initialize() {

searchBox.setPromptText(Localization.lang("Search..."));
searchBox.setLeft(IconTheme.JabRefIcons.SEARCH.getGraphicNode());

directoryPathField.textProperty().bind(viewModel.directoryPathProperty());
}

private void setUpTable() {
Expand Down Expand Up @@ -168,6 +173,11 @@ private void removeList() {
viewModel.removeCurrentFile();
}

@FXML
private void handleChangeDirectory() {
viewModel.handleChangeDirectory();
}

@FXML
private void addAbbreviation() {
if (!searchBox.getText().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;

import org.jabref.gui.DialogService;
import org.jabref.gui.preferences.PreferenceTabViewModel;
import org.jabref.gui.util.DirectoryDialogConfiguration;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.journals.Abbreviation;
import org.jabref.logic.journals.JournalAbbreviationLoader;
Expand Down Expand Up @@ -50,6 +54,8 @@ public class JournalAbbreviationsTabViewModel implements PreferenceTabViewModel
private final SimpleBooleanProperty isAbbreviationEditableAndRemovable = new SimpleBooleanProperty(false);
private final SimpleBooleanProperty useFJournal = new SimpleBooleanProperty(true);

private final StringProperty directoryPath = new SimpleStringProperty();

private final DialogService dialogService;
private final TaskExecutor taskExecutor;

Expand Down Expand Up @@ -103,6 +109,7 @@ public JournalAbbreviationsTabViewModel(JournalAbbreviationPreferences abbreviat
}
}
});
directoryPath.set(abbreviationsPreferences.getJournalAbbreviationDir().toString());
}

@Override
Expand Down Expand Up @@ -211,6 +218,39 @@ public void removeCurrentFile() {
}
}

public void handleChangeDirectory() {
DirectoryDialogConfiguration config = new DirectoryDialogConfiguration.Builder()
.withInitialDirectory(Path.of(directoryPath.get()))
.build();

Optional<Path> newDirectory = dialogService.showDirectorySelectionDialog(config);
newDirectory.ifPresent(path -> {
directoryPath.set(path.toString());
abbreviationsPreferences.setJournalAbbreviationDir(path);
updateJournalFiles();
storeSettings();
// Optionally trigger any updates needed due to directory change
});
}

private void updateJournalFiles() {
List<String> externalLists = abbreviationsPreferences.getExternalJournalLists();

// Remove files that are no longer in the external lists
journalFiles.removeIf(file -> !externalLists.contains(file.getAbsolutePath().map(Path::toString).orElse("")));

// Add new files
for (String filePath : externalLists) {
if (journalFiles.stream().noneMatch(file -> file.getAbsolutePath().map(Path::toString).orElse("").equals(filePath))) {
openFile(Path.of(filePath));
}
}
}

public StringProperty directoryPathProperty() {
return directoryPath;
}

/**
* Method to add a new abbreviation to the abbreviations list property. It also sets the currentAbbreviation
* property to the new abbreviation.
Expand Down Expand Up @@ -334,6 +374,7 @@ public void storeSettings() {
.collect(Collectors.toList());

abbreviationsPreferences.setExternalJournalLists(journalStringList);
abbreviationsPreferences.setJournalAbbreviationDir(Path.of(directoryPath.get()));
abbreviationsPreferences.setUseFJournalField(useFJournal.get());

if (shouldWriteLists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ public class JournalAbbreviationLoader {

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

public static Path ensureJournalAbbreviationFileExists(Path baseDirectory) {
try {
// Ensure the subdirectory 'journal-abbreviations' exists
Path directory = baseDirectory.resolve("journal-abbreviations");
Files.createDirectories(directory);

Path customCsvPath = directory.resolve("custom.csv");
if (!Files.exists(customCsvPath)) {
Files.createFile(customCsvPath);
LOGGER.info("Created custom.csv at {}", customCsvPath);
}
return customCsvPath;
} catch (IOException e) {
LOGGER.error("Could not initialize journal abbreviation directory or file", e);
return null;
}
}

public static Collection<Abbreviation> readAbbreviationsFromCsvFile(Path file) throws IOException {
LOGGER.debug("Reading journal list from file {}", file);
AbbreviationParser parser = new AbbreviationParser();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,75 @@
package org.jabref.logic.journals;

import java.nio.file.Path;
import java.util.List;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class JournalAbbreviationPreferences {

private final ObservableList<String> externalJournalLists;
private final BooleanProperty useFJournalField;
private final ObjectProperty<Path> journalAbbreviationDir;

public JournalAbbreviationPreferences(List<String> externalJournalLists, boolean useFJournalField) {
this(externalJournalLists, useFJournalField, getDefaultAbbreviationDir().toString());
}

public JournalAbbreviationPreferences(List<String> externalJournalLists,
boolean useFJournalField) {
boolean useFJournalField, String directory) {
this.externalJournalLists = FXCollections.observableArrayList(externalJournalLists);
this.useFJournalField = new SimpleBooleanProperty(useFJournalField);
this.journalAbbreviationDir = new SimpleObjectProperty<>(
directory != null ? Path.of(directory) : getDefaultAbbreviationDir()
);

updateCustomCsvFile(this.journalAbbreviationDir.get());

this.journalAbbreviationDir.addListener((observable, oldValue, newValue) -> {
updateCustomCsvFile(newValue);
});
}

private void updateCustomCsvFile(Path directory) {
if (directory == null) {
return;
}
Path newFilePath = JournalAbbreviationLoader.ensureJournalAbbreviationFileExists(directory);
if (newFilePath != null) {
String newFilePathString = newFilePath.toString();
// Remove old custom.csv path if it exists
externalJournalLists.removeIf(path -> path.endsWith("custom.csv"));
// Add new custom.csv path
if (!externalJournalLists.contains(newFilePathString)) {
externalJournalLists.add(newFilePathString);
}
}
}

public Path getJournalAbbreviationDir() {
Path dir = journalAbbreviationDir.get();
return dir != null ? dir : getDefaultAbbreviationDir();
}

public static Path getDefaultAbbreviationDir() {
String appData = System.getenv("APPDATA");
Copy link
Member

Choose a reason for hiding this comment

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

We have better methods for getting the AppDAta dir, see Directories class, please use that approach

if (appData == null) {
appData = System.getProperty("user.home");
}
return Path.of(appData, ".jabref", "journals");
}

public void setJournalAbbreviationDir(Path journalAbbreviationDir) {
this.journalAbbreviationDir.set(journalAbbreviationDir);
}

public ObjectProperty<Path> journalAbbreviationDirProperty() {
return journalAbbreviationDir;
}

public ObservableList<String> getExternalJournalLists() {
Expand Down