Skip to content

Commit

Permalink
Merge pull request #10525 from caitlinlilley/main
Browse files Browse the repository at this point in the history
Add library selection to "Aux file import"
  • Loading branch information
Siedlerchr authored Oct 23, 2023
2 parents 6c1b7a3 + fb0e026 commit febc379
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv

### Added

- We added a dropdown menu to let users change the reference library during AUX file import. [#10472](https://github.com/JabRef/jabref/issues/10472)

### Changed

- We changed the setting of the keyword separator to accept a single character only. [#177](https://github.com/koppor/jabref/issues/177)
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/jabref/gui/LibraryTabContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;

import org.jabref.model.database.BibDatabaseContext;

public interface LibraryTabContainer {
LibraryTab getLibraryTabAt(int i);

Expand All @@ -13,6 +15,8 @@ public interface LibraryTabContainer {

void addTab(LibraryTab libraryTab, boolean raisePanel);

void addTab(BibDatabaseContext bibDatabaseContext, boolean raisePanel);

void closeTab(LibraryTab libraryTab);

void closeCurrentTab();
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/jabref/gui/auximport/FromAuxDialog.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<?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.ListView?>
Expand All @@ -12,7 +13,6 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import org.jabref.gui.icon.JabRefIconView?>

<DialogPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="650.0" prefWidth="500.0"
xmlns="http://javafx.com/javafx/8.0.121" fx:controller="org.jabref.gui.auximport.FromAuxDialog">
<content>
Expand Down Expand Up @@ -43,6 +43,12 @@
<TextArea fx:id="statusInfos" editable="false" prefHeight="300.0" wrapText="true"/>
<Label text="%Unknown BibTeX entries:"/>
<ListView fx:id="notFoundList" prefHeight="200"/>
<VBox spacing="10">
<HBox spacing="4" alignment="CENTER_LEFT">
<Label text="%Select library"/>
<ComboBox fx:id="libraryListView" layoutX="16.0" layoutY="52.0"/>
</HBox>
</VBox>
</VBox>
</VBox>
</content>
Expand Down
78 changes: 33 additions & 45 deletions src/main/java/org/jabref/gui/auximport/FromAuxDialog.java
Original file line number Diff line number Diff line change
@@ -1,64 +1,59 @@
package org.jabref.gui.auximport;

import java.nio.file.Path;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;

import org.jabref.gui.DialogService;
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.LibraryTab;
import org.jabref.gui.LibraryTabContainer;
import org.jabref.gui.StateManager;
import org.jabref.gui.theme.ThemeManager;
import org.jabref.gui.util.BaseDialog;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.auxparser.AuxParser;
import org.jabref.logic.auxparser.AuxParserResult;
import org.jabref.logic.auxparser.DefaultAuxParser;
import org.jabref.gui.util.ViewModelListCellFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.StandardFileType;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.preferences.PreferencesService;

import com.airhacks.afterburner.views.ViewLoader;
import com.tobiasdiez.easybind.EasyBind;
import jakarta.inject.Inject;

/**
* A wizard dialog for generating a new sub database from existing TeX AUX file
*/
public class FromAuxDialog extends BaseDialog<Void> {

private final LibraryTab libraryTab;
@FXML private ButtonType generateButtonType;
private final Button generateButton;
@FXML private TextField auxFileField;
@FXML private ListView<String> notFoundList;
@FXML private TextArea statusInfos;
private AuxParserResult auxParserResult;
@FXML private ComboBox<BibDatabaseContext> libraryListView;

@Inject private PreferencesService preferences;
@Inject private DialogService dialogService;
@Inject private ThemeManager themeManager;
@Inject private StateManager stateManager;

private final LibraryTabContainer tabContainer;
private FromAuxDialogViewModel viewModel;

public FromAuxDialog(JabRefFrame frame) {
libraryTab = frame.getCurrentLibraryTab();
public FromAuxDialog(LibraryTabContainer tabContainer) {
this.tabContainer = tabContainer;
this.setTitle(Localization.lang("AUX file import"));

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

generateButton = (Button) this.getDialogPane().lookupButton(generateButtonType);
generateButton.setDisable(true);
Button generateButton = (Button) this.getDialogPane().lookupButton(generateButtonType);
generateButton.disableProperty().bind(viewModel.parseFailedProperty().or(viewModel.notFoundList().emptyProperty().not()));
generateButton.defaultButtonProperty().bind(generateButton.disableProperty().not());
setResultConverter(button -> {
if (button == generateButtonType) {
BibDatabaseContext context = new BibDatabaseContext(auxParserResult.getGeneratedBibDatabase());
frame.addTab(context, true);
viewModel.addResultToTabContainer();
}
return null;
});
Expand All @@ -67,36 +62,29 @@ public FromAuxDialog(JabRefFrame frame) {
}

@FXML
private void parseActionPerformed() {
notFoundList.getItems().clear();
statusInfos.setText("");
BibDatabase refBase = libraryTab.getDatabase();
String auxName = auxFileField.getText();
private void initialize() {
viewModel = new FromAuxDialogViewModel(tabContainer, dialogService, preferences, stateManager);

if ((auxName != null) && (refBase != null) && !auxName.isEmpty()) {
AuxParser auxParser = new DefaultAuxParser(refBase);
auxParserResult = auxParser.parse(Path.of(auxName));
notFoundList.getItems().setAll(auxParserResult.getUnresolvedKeys());
statusInfos.setText(new AuxParserResultViewModel(auxParserResult).getInformation(false));
auxFileField.textProperty().bindBidirectional(viewModel.auxFileProperty());
statusInfos.textProperty().bindBidirectional(viewModel.statusTextProperty());
notFoundList.itemsProperty().bind(viewModel.notFoundList());

if (!auxParserResult.getGeneratedBibDatabase().hasEntries()) {
// The generated database contains no entries -> no active generate-button
statusInfos.setText(statusInfos.getText() + "\n" + Localization.lang("empty library"));
generateButton.setDisable(true);
} else {
generateButton.setDisable(false);
}
} else {
generateButton.setDisable(true);
}
libraryListView.setEditable(false);
libraryListView.itemsProperty().bind(viewModel.librariesProperty());
libraryListView.valueProperty().bindBidirectional(viewModel.selectedLibraryProperty());
new ViewModelListCellFactory<BibDatabaseContext>()
.withText(viewModel::getDatabaseName)
.install(libraryListView);
EasyBind.listen(libraryListView.getSelectionModel().selectedItemProperty(), (obs, oldValue, newValue) -> parseActionPerformed());
}

@FXML
private void parseActionPerformed() {
viewModel.parse();
}

@FXML
private void browseButtonClicked() {
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.addExtensionFilter(StandardFileType.AUX)
.withDefaultExtension(StandardFileType.AUX)
.withInitialDirectory(preferences.getFilePreferences().getWorkingDirectory()).build();
dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> auxFileField.setText(file.toAbsolutePath().toString()));
viewModel.browse();
}
}
139 changes: 139 additions & 0 deletions src/main/java/org/jabref/gui/auximport/FromAuxDialogViewModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.jabref.gui.auximport;

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

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyListProperty;
import javafx.beans.property.SimpleBooleanProperty;
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 org.jabref.gui.DialogService;
import org.jabref.gui.LibraryTabContainer;
import org.jabref.gui.StateManager;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.auxparser.AuxParser;
import org.jabref.logic.auxparser.AuxParserResult;
import org.jabref.logic.auxparser.DefaultAuxParser;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.shared.DatabaseLocation;
import org.jabref.logic.util.StandardFileType;
import org.jabref.logic.util.io.FileUtil;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.preferences.PreferencesService;

import com.tobiasdiez.easybind.EasyBind;

public class FromAuxDialogViewModel {

private final BooleanProperty parseFailedProperty = new SimpleBooleanProperty(false);
private final StringProperty auxFileProperty = new SimpleStringProperty();
private final StringProperty statusTextProperty = new SimpleStringProperty();
private final ListProperty<String> notFoundList = new SimpleListProperty<>(FXCollections.observableArrayList());
private final ListProperty<BibDatabaseContext> librariesProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
private final ObjectProperty<BibDatabaseContext> selectedLibraryProperty = new SimpleObjectProperty<>();

private final LibraryTabContainer tabContainer;
private final DialogService dialogService;
private final PreferencesService preferencesService;
private final StateManager stateManager;

private AuxParserResult auxParserResult;

public FromAuxDialogViewModel(LibraryTabContainer tabContainer,
DialogService dialogService,
PreferencesService preferencesService,
StateManager stateManager) {
this.tabContainer = tabContainer;
this.dialogService = dialogService;
this.preferencesService = preferencesService;
this.stateManager = stateManager;

librariesProperty.setAll(stateManager.getOpenDatabases());
selectedLibraryProperty.set(tabContainer.getCurrentLibraryTab().getBibDatabaseContext());
EasyBind.listen(selectedLibraryProperty, (obs, oldValue, newValue) -> {
if (auxParserResult != null) {
parse();
}
});
}

public String getDatabaseName(BibDatabaseContext databaseContext) {
Optional<String> dbOpt = Optional.empty();
if (databaseContext.getDatabasePath().isPresent()) {
dbOpt = FileUtil.getUniquePathFragment(stateManager.collectAllDatabasePaths(), databaseContext.getDatabasePath().get());
}
if (databaseContext.getLocation() == DatabaseLocation.SHARED) {
return databaseContext.getDBMSSynchronizer().getDBName() + " [" + Localization.lang("shared") + "]";
}

return dbOpt.orElse(Localization.lang("untitled"));
}

public void browse() {
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.addExtensionFilter(StandardFileType.AUX)
.withDefaultExtension(StandardFileType.AUX)
.withInitialDirectory(preferencesService.getFilePreferences().getWorkingDirectory()).build();
dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> auxFileProperty.setValue(file.toAbsolutePath().toString()));
}

public void parse() {
parseFailedProperty.set(false);
notFoundList.clear();
statusTextProperty.setValue("");
BibDatabase referenceDatabase = selectedLibraryProperty.get().getDatabase();
String auxName = auxFileProperty.get();

if ((auxName != null) && (referenceDatabase != null) && !auxName.isEmpty()) {
AuxParser auxParser = new DefaultAuxParser(referenceDatabase);
auxParserResult = auxParser.parse(Path.of(auxName));
notFoundList.setAll(auxParserResult.getUnresolvedKeys());
statusTextProperty.set(new AuxParserResultViewModel(auxParserResult).getInformation(false));

if (!auxParserResult.getGeneratedBibDatabase().hasEntries()) {
// The generated database contains no entries -> no active generate-button
statusTextProperty.set(statusTextProperty.get() + "\n" + Localization.lang("empty library"));
parseFailedProperty.set(true);
}
} else {
parseFailedProperty.set(true);
}
}

public void addResultToTabContainer() {
BibDatabaseContext context = new BibDatabaseContext(auxParserResult.getGeneratedBibDatabase());
tabContainer.addTab(context, true);
}

public BooleanProperty parseFailedProperty() {
return parseFailedProperty;
}

public StringProperty auxFileProperty() {
return auxFileProperty;
}

public StringProperty statusTextProperty() {
return statusTextProperty;
}

public ReadOnlyListProperty<String> notFoundList() {
return notFoundList;
}

public ReadOnlyListProperty<BibDatabaseContext> librariesProperty() {
return librariesProperty;
}

public ObjectProperty<BibDatabaseContext> selectedLibraryProperty() {
return selectedLibraryProperty;
}
}
1 change: 1 addition & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ Search\ results\ from\ open\ libraries=Search results from open libraries
Select\ all=Select all
Select\ new\ encoding=Select new encoding

Select\ library=Select library
Select\ entry\ type=Select entry type

Select\ file\ from\ ZIP-archive=Select file from ZIP-archive
Expand Down

0 comments on commit febc379

Please sign in to comment.