diff --git a/CHANGELOG.md b/CHANGELOG.md index cd32fdd16bb..29aabcaeaf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We slightly changed the layout of the Journal tab in the preferences for ui consistency. [#7937](https://github.com/JabRef/jabref/pull/7937) - The JabRefHost on Windows now writes a temporary file and calls `-importToOpen` instead of passing the bibtex via `-importBibtex`. [#7374](https://github.com/JabRef/jabref/issues/7374), [JabRef Browser Ext #274](https://github.com/JabRef/JabRef-Browser-Extension/issues/274) - We merged the barely used ImportSettingsTab and the CustomizationTab in the preferences into one single tab and moved the option to allow Integers in Edition Fields in Bibtex-Mode to the EntryEditor tab. [#7849](https://github.com/JabRef/jabref/pull/7849) +- We moved the export order in the preferences from `File` to `Import and Export`. [#7935](https://github.com/JabRef/jabref/pull/7935) +- We reworked the export order in the preferences and the save order in the library preferences. You can now set more than three sort criteria in your library preferences. [#7935](https://github.com/JabRef/jabref/pull/7935) ### Fixed diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.fxml b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.fxml index a5992d1457e..1e2b9f84822 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.fxml +++ b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.fxml @@ -1,14 +1,14 @@ - - - + + + - + @@ -23,38 +23,25 @@ - + - - + + - - - - - - - + diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.java b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.java index 55bb2b66941..77feb6b38c4 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanel.java @@ -1,16 +1,28 @@ package org.jabref.gui.commonfxcontrols; +import java.util.List; +import java.util.stream.Collectors; + +import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ListProperty; -import javafx.beans.property.ObjectProperty; +import javafx.collections.ListChangeListener; import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.control.RadioButton; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.icon.JabRefIconView; import org.jabref.gui.util.FieldsUtil; import org.jabref.gui.util.ViewModelListCellFactory; +import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.field.Field; import com.airhacks.afterburner.views.ViewLoader; @@ -20,12 +32,8 @@ public class SaveOrderConfigPanel extends VBox { @FXML private RadioButton exportInSpecifiedOrder; @FXML private RadioButton exportInTableOrder; @FXML private RadioButton exportInOriginalOrder; - @FXML private ComboBox savePriSort; - @FXML private ComboBox saveSecSort; - @FXML private ComboBox saveTerSort; - @FXML private CheckBox savePriDesc; - @FXML private CheckBox saveSecDesc; - @FXML private CheckBox saveTerDesc; + @FXML private GridPane sortCriterionList; + @FXML private Button addButton; private SaveOrderConfigPanelViewModel viewModel; @@ -43,77 +51,142 @@ private void initialize() { exportInTableOrder.selectedProperty().bindBidirectional(viewModel.saveInTableOrderProperty()); exportInSpecifiedOrder.selectedProperty().bindBidirectional(viewModel.saveInSpecifiedOrderProperty()); - new ViewModelListCellFactory() - .withText(FieldsUtil::getNameWithType) - .install(savePriSort); - savePriSort.itemsProperty().bindBidirectional(viewModel.primarySortFieldsProperty()); - savePriSort.valueProperty().bindBidirectional(viewModel.savePrimarySortSelectedValueProperty()); - savePriSort.setConverter(FieldsUtil.fieldStringConverter); - - new ViewModelListCellFactory() - .withText(FieldsUtil::getNameWithType) - .install(saveSecSort); - saveSecSort.itemsProperty().bindBidirectional(viewModel.secondarySortFieldsProperty()); - saveSecSort.valueProperty().bindBidirectional(viewModel.saveSecondarySortSelectedValueProperty()); - saveSecSort.setConverter(FieldsUtil.fieldStringConverter); + viewModel.sortCriteriaProperty().addListener((ListChangeListener) change -> { + while (change.next()) { + if (change.wasReplaced()) { + clearCriterionRow(change.getFrom()); + createCriterionRow(change.getAddedSubList().get(0), change.getFrom()); + } else if (change.wasAdded()) { + for (SortCriterionViewModel criterionViewModel : change.getAddedSubList()) { + int row = change.getFrom() + change.getAddedSubList().indexOf(criterionViewModel); + createCriterionRow(criterionViewModel, row); + } + } else if (change.wasRemoved()) { + for (SortCriterionViewModel criterionViewModel : change.getRemoved()) { + clearCriterionRow(change.getFrom()); + } + } + } + }); + } + private void createCriterionRow(SortCriterionViewModel criterionViewModel, int row) { + sortCriterionList.getChildren().stream() + .filter(item -> GridPane.getRowIndex(item) >= row) + .forEach(item -> { + GridPane.setRowIndex(item, GridPane.getRowIndex(item) + 1); + if (item instanceof Label label) { + label.setText(String.valueOf(GridPane.getRowIndex(item) + 1)); + } + }); + + Label label = new Label(String.valueOf(row + 1)); + sortCriterionList.add(label, 0, row); + + ComboBox field = new ComboBox<>(viewModel.sortableFieldsProperty()); + field.setMaxWidth(Double.MAX_VALUE); new ViewModelListCellFactory() .withText(FieldsUtil::getNameWithType) - .install(saveTerSort); - saveTerSort.itemsProperty().bindBidirectional(viewModel.tertiarySortFieldsProperty()); - saveTerSort.valueProperty().bindBidirectional(viewModel.saveTertiarySortSelectedValueProperty()); - saveTerSort.setConverter(FieldsUtil.fieldStringConverter); - - savePriDesc.selectedProperty().bindBidirectional(viewModel.savePrimaryDescPropertySelected()); - saveSecDesc.selectedProperty().bindBidirectional(viewModel.saveSecondaryDescPropertySelected()); - saveTerDesc.selectedProperty().bindBidirectional(viewModel.saveTertiaryDescPropertySelected()); + .install(field); + field.setConverter(FieldsUtil.fieldStringConverter); + field.itemsProperty().bindBidirectional(viewModel.sortableFieldsProperty()); + field.valueProperty().bindBidirectional(criterionViewModel.fieldProperty()); + sortCriterionList.add(field, 1, row); + GridPane.getHgrow(field); + + CheckBox descending = new CheckBox(Localization.lang("Descending")); + descending.selectedProperty().bindBidirectional(criterionViewModel.descendingProperty()); + sortCriterionList.add(descending, 2, row); + + HBox hBox = new HBox(); + hBox.getChildren().addAll(createRowButtons(criterionViewModel)); + sortCriterionList.add(hBox, 3, row); } - public BooleanProperty saveInOriginalProperty() { - return viewModel.saveInOriginalProperty(); + private List createRowButtons(SortCriterionViewModel criterionViewModel) { + Button remove = new Button("", new JabRefIconView(IconTheme.JabRefIcons.REMOVE_NOBOX)); + remove.getStyleClass().addAll("icon-button", "narrow"); + remove.setPrefHeight(20.0); + remove.setPrefWidth(20.0); + remove.setOnAction(event -> removeCriterion(criterionViewModel)); + + Button moveUp = new Button("", new JabRefIconView(IconTheme.JabRefIcons.LIST_MOVE_UP)); + moveUp.getStyleClass().addAll("icon-button", "narrow"); + moveUp.setPrefHeight(20.0); + moveUp.setPrefWidth(20.0); + moveUp.setOnAction(event -> moveCriterionUp(criterionViewModel)); + + Button moveDown = new Button("", new JabRefIconView(IconTheme.JabRefIcons.LIST_MOVE_DOWN)); + moveDown.getStyleClass().addAll("icon-button", "narrow"); + moveDown.setPrefHeight(20.0); + moveDown.setPrefWidth(20.0); + moveDown.setOnAction(event -> moveCriterionDown(criterionViewModel)); + + return List.of(moveUp, moveDown, remove); } - public BooleanProperty saveInTableOrderProperty() { - return viewModel.saveInTableOrderProperty(); + private void clearCriterionRow(int row) { + List criterionRow = sortCriterionList.getChildren().stream() + .filter(item -> GridPane.getRowIndex(item) == row) + .collect(Collectors.toList()); + sortCriterionList.getChildren().removeAll(criterionRow); + + sortCriterionList.getChildren().stream() + .filter(item -> GridPane.getRowIndex(item) > row) + .forEach(item -> { + GridPane.setRowIndex(item, GridPane.getRowIndex(item) - 1); + if (item instanceof Label label) { + label.setText(String.valueOf(GridPane.getRowIndex(item) + 1)); + } + }); } - public BooleanProperty saveInSpecifiedOrderProperty() { - return viewModel.saveInSpecifiedOrderProperty(); + public void setCriteriaLimit(int limit) { + addButton.disableProperty().unbind(); + addButton.disableProperty().bind( + Bindings.createBooleanBinding( + () -> viewModel.sortCriteriaProperty().size() >= limit || !exportInSpecifiedOrder.selectedProperty().get(), + viewModel.sortCriteriaProperty().sizeProperty(), + exportInSpecifiedOrder.selectedProperty())); } - public ListProperty primarySortFieldsProperty() { - return viewModel.primarySortFieldsProperty(); + @FXML + public void addCriterion() { + viewModel.addCriterion(); } - public ListProperty secondarySortFieldsProperty() { - return viewModel.secondarySortFieldsProperty(); + @FXML + public void moveCriterionUp(SortCriterionViewModel criterionViewModel) { + viewModel.moveCriterionUp(criterionViewModel); } - public ListProperty tertiarySortFieldsProperty() { - return viewModel.tertiarySortFieldsProperty(); + @FXML + public void moveCriterionDown(SortCriterionViewModel criterionViewModel) { + viewModel.moveCriterionDown(criterionViewModel); } - public ObjectProperty savePrimarySortSelectedValueProperty() { - return viewModel.savePrimarySortSelectedValueProperty(); + @FXML + public void removeCriterion(SortCriterionViewModel criterionViewModel) { + viewModel.removeCriterion(criterionViewModel); } - public ObjectProperty saveSecondarySortSelectedValueProperty() { - return viewModel.saveSecondarySortSelectedValueProperty(); + public BooleanProperty saveInOriginalProperty() { + return viewModel.saveInOriginalProperty(); } - public ObjectProperty saveTertiarySortSelectedValueProperty() { - return viewModel.saveTertiarySortSelectedValueProperty(); + public BooleanProperty saveInTableOrderProperty() { + return viewModel.saveInTableOrderProperty(); } - public BooleanProperty savePrimaryDescPropertySelected() { - return viewModel.savePrimaryDescPropertySelected(); + public BooleanProperty saveInSpecifiedOrderProperty() { + return viewModel.saveInSpecifiedOrderProperty(); } - public BooleanProperty saveSecondaryDescPropertySelected() { - return viewModel.saveSecondaryDescPropertySelected(); + public ListProperty sortableFieldsProperty() { + return viewModel.sortableFieldsProperty(); } - public BooleanProperty saveTertiaryDescPropertySelected() { - return viewModel.saveTertiaryDescPropertySelected(); + public ListProperty sortCriteriaProperty() { + return viewModel.sortCriteriaProperty(); } } diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModel.java b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModel.java index 0fb898392b1..efba3ab390d 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModel.java @@ -1,81 +1,71 @@ package org.jabref.gui.commonfxcontrols; +import java.util.Collections; + import javafx.beans.property.BooleanProperty; import javafx.beans.property.ListProperty; -import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleListProperty; -import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import org.jabref.model.entry.field.Field; +import org.jabref.model.metadata.SaveOrderConfig; public class SaveOrderConfigPanelViewModel { - private final ListProperty primarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final ListProperty secondarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final ListProperty tertiarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - - private final BooleanProperty savePrimaryDescPropertySelected = new SimpleBooleanProperty(); - private final BooleanProperty saveSecondaryDescPropertySelected = new SimpleBooleanProperty(); - private final BooleanProperty saveTertiaryDescPropertySelected = new SimpleBooleanProperty(); - - private final ObjectProperty savePrimarySortSelectedValueProperty = new SimpleObjectProperty<>(null); - private final ObjectProperty saveSecondarySortSelectedValueProperty = new SimpleObjectProperty<>(null); - private final ObjectProperty saveTertiarySortSelectedValueProperty = new SimpleObjectProperty<>(null); - private final BooleanProperty saveInOriginalProperty = new SimpleBooleanProperty(); private final BooleanProperty saveInTableOrderProperty = new SimpleBooleanProperty(); private final BooleanProperty saveInSpecifiedOrderProperty = new SimpleBooleanProperty(); - public SaveOrderConfigPanelViewModel() { - } - - public BooleanProperty saveInOriginalProperty() { - return saveInOriginalProperty; - } + private final ListProperty sortableFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty selectedSortCriteriaProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - public BooleanProperty saveInTableOrderProperty() { - return saveInTableOrderProperty; - } - - public BooleanProperty saveInSpecifiedOrderProperty() { - return saveInSpecifiedOrderProperty; + public SaveOrderConfigPanelViewModel() { } - public ListProperty primarySortFieldsProperty() { - return primarySortFieldsProperty; + public void addCriterion() { + selectedSortCriteriaProperty.add(new SortCriterionViewModel(new SaveOrderConfig.SortCriterion())); } - public ListProperty secondarySortFieldsProperty() { - return secondarySortFieldsProperty; + public void removeCriterion(SortCriterionViewModel sortCriterionViewModel) { + selectedSortCriteriaProperty.remove(sortCriterionViewModel); } - public ListProperty tertiarySortFieldsProperty() { - return tertiarySortFieldsProperty; + public void moveCriterionUp(SortCriterionViewModel sortCriterionViewModel) { + if (selectedSortCriteriaProperty.contains(sortCriterionViewModel)) { + int index = selectedSortCriteriaProperty.indexOf(sortCriterionViewModel); + if (index > 0) { + Collections.swap(selectedSortCriteriaProperty, index - 1, index); + } + } } - public ObjectProperty savePrimarySortSelectedValueProperty() { - return savePrimarySortSelectedValueProperty; + public void moveCriterionDown(SortCriterionViewModel sortCriterionViewModel) { + if (selectedSortCriteriaProperty.contains(sortCriterionViewModel)) { + int index = selectedSortCriteriaProperty.indexOf(sortCriterionViewModel); + if (index >= 0 && index < selectedSortCriteriaProperty.size() - 1) { + Collections.swap(selectedSortCriteriaProperty, index + 1, index); + } + } } - public ObjectProperty saveSecondarySortSelectedValueProperty() { - return saveSecondarySortSelectedValueProperty; + public BooleanProperty saveInOriginalProperty() { + return saveInOriginalProperty; } - public ObjectProperty saveTertiarySortSelectedValueProperty() { - return saveTertiarySortSelectedValueProperty; + public BooleanProperty saveInTableOrderProperty() { + return saveInTableOrderProperty; } - public BooleanProperty savePrimaryDescPropertySelected() { - return savePrimaryDescPropertySelected; + public BooleanProperty saveInSpecifiedOrderProperty() { + return saveInSpecifiedOrderProperty; } - public BooleanProperty saveSecondaryDescPropertySelected() { - return saveSecondaryDescPropertySelected; + public ListProperty sortableFieldsProperty() { + return sortableFieldsProperty; } - public BooleanProperty saveTertiaryDescPropertySelected() { - return saveTertiaryDescPropertySelected; + public ListProperty sortCriteriaProperty() { + return selectedSortCriteriaProperty; } } diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/SortCriterionViewModel.java b/src/main/java/org/jabref/gui/commonfxcontrols/SortCriterionViewModel.java new file mode 100644 index 00000000000..485fa2368d2 --- /dev/null +++ b/src/main/java/org/jabref/gui/commonfxcontrols/SortCriterionViewModel.java @@ -0,0 +1,32 @@ +package org.jabref.gui.commonfxcontrols; + +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; + +import org.jabref.model.entry.field.Field; +import org.jabref.model.metadata.SaveOrderConfig; + +public class SortCriterionViewModel { + + private final ObjectProperty fieldProperty = new SimpleObjectProperty<>(); + private final BooleanProperty descendingProperty = new SimpleBooleanProperty(); + + public SortCriterionViewModel(SaveOrderConfig.SortCriterion criterion) { + this.fieldProperty.setValue(criterion.field); + this.descendingProperty.setValue(criterion.descending); + } + + public ObjectProperty fieldProperty() { + return fieldProperty; + } + + public BooleanProperty descendingProperty() { + return descendingProperty; + } + + public SaveOrderConfig.SortCriterion getCriterion() { + return new SaveOrderConfig.SortCriterion(fieldProperty.getValue(), descendingProperty.getValue()); + } +} diff --git a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java index ae5027555d6..b77fa8a7b82 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java @@ -4,7 +4,6 @@ import javax.inject.Inject; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.ButtonType; import javafx.scene.control.CheckBox; @@ -82,32 +81,25 @@ private void initialize() { saveOrderConfigPanel.saveInOriginalProperty().bindBidirectional(viewModel.saveInOriginalProperty()); saveOrderConfigPanel.saveInTableOrderProperty().bindBidirectional(viewModel.saveInTableOrderProperty()); saveOrderConfigPanel.saveInSpecifiedOrderProperty().bindBidirectional(viewModel.saveInSpecifiedOrderProperty()); - saveOrderConfigPanel.primarySortFieldsProperty().bind(viewModel.primarySortFieldsProperty()); - saveOrderConfigPanel.secondarySortFieldsProperty().bind(viewModel.secondarySortFieldsProperty()); - saveOrderConfigPanel.tertiarySortFieldsProperty().bind(viewModel.tertiarySortFieldsProperty()); - saveOrderConfigPanel.savePrimaryDescPropertySelected().bindBidirectional(viewModel.savePrimaryDescPropertySelected()); - saveOrderConfigPanel.saveSecondaryDescPropertySelected().bindBidirectional(viewModel.saveSecondaryDescPropertySelected()); - saveOrderConfigPanel.saveTertiaryDescPropertySelected().bindBidirectional(viewModel.saveTertiaryDescPropertySelected()); - saveOrderConfigPanel.savePrimarySortSelectedValueProperty().bindBidirectional(viewModel.savePrimarySortSelectedValueProperty()); - saveOrderConfigPanel.saveSecondarySortSelectedValueProperty().bindBidirectional(viewModel.saveSecondarySortSelectedValueProperty()); - saveOrderConfigPanel.saveTertiarySortSelectedValueProperty().bindBidirectional(viewModel.saveTertiarySortSelectedValueProperty()); + saveOrderConfigPanel.sortableFieldsProperty().bind(viewModel.sortableFieldsProperty()); + saveOrderConfigPanel.sortCriteriaProperty().bindBidirectional(viewModel.sortCriteriaProperty()); fieldFormatterCleanupsPanel.cleanupsDisableProperty().bindBidirectional(viewModel.cleanupsDisableProperty()); fieldFormatterCleanupsPanel.cleanupsProperty().bindBidirectional(viewModel.cleanupsProperty()); } @FXML - public void browseGeneralFileDirectory(ActionEvent event) { + public void browseGeneralFileDirectory() { viewModel.browseGeneralDir(); } @FXML - public void browseUserSpecificFileDirectory(ActionEvent event) { + public void browseUserSpecificFileDirectory() { viewModel.browseUserDir(); } @FXML - void browseLatexFileDirectory(ActionEvent event) { + void browseLatexFileDirectory() { viewModel.browseLatexDir(); } } diff --git a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java index b70e582d80c..1d6538413ea 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java @@ -6,6 +6,7 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ListProperty; @@ -18,6 +19,7 @@ import javafx.collections.FXCollections; import org.jabref.gui.DialogService; +import org.jabref.gui.commonfxcontrols.SortCriterionViewModel; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.logic.cleanup.Cleanups; import org.jabref.logic.cleanup.FieldFormatterCleanup; @@ -50,16 +52,8 @@ public class LibraryPropertiesDialogViewModel { private final BooleanProperty saveInOriginalProperty = new SimpleBooleanProperty(); private final BooleanProperty saveInTableOrderProperty = new SimpleBooleanProperty(); private final BooleanProperty saveInSpecifiedOrderProperty = new SimpleBooleanProperty(); - // ToDo: The single criterions should really be a map or a list. - private final ListProperty primarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final ListProperty secondarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final ListProperty tertiarySortFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final BooleanProperty savePrimaryDescPropertySelected = new SimpleBooleanProperty(); - private final BooleanProperty saveSecondaryDescPropertySelected = new SimpleBooleanProperty(); - private final BooleanProperty saveTertiaryDescPropertySelected = new SimpleBooleanProperty(); - private final ObjectProperty savePrimarySortSelectedValueProperty = new SimpleObjectProperty<>(null); - private final ObjectProperty saveSecondarySortSelectedValueProperty = new SimpleObjectProperty<>(null); - private final ObjectProperty saveTertiarySortSelectedValueProperty = new SimpleObjectProperty<>(null); + private final ListProperty sortableFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty sortCriteriaProperty = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>())); // FieldFormatterCleanupsPanel private final BooleanProperty cleanupsDisableProperty = new SimpleBooleanProperty(); @@ -78,7 +72,7 @@ public LibraryPropertiesDialogViewModel(BibDatabaseContext databaseContext, Dial this.dialogService = dialogService; this.preferences = preferences; this.initialMetaData = databaseContext.getMetaData(); - this.initialSaveOrderConfig = initialMetaData.getSaveOrderConfig().orElseGet(preferences::loadExportSaveOrder); + this.initialSaveOrderConfig = initialMetaData.getSaveOrderConfig().orElseGet(preferences::getExportSaveOrder); this.directoryDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(preferences.getWorkingDir()).build(); @@ -100,29 +94,19 @@ void setValues() { // SaveOrderConfigPanel - if (initialSaveOrderConfig.saveInOriginalOrder()) { - saveInOriginalProperty.setValue(true); - } else if (initialSaveOrderConfig.saveInSpecifiedOrder()) { - saveInSpecifiedOrderProperty.setValue(true); - } else { - saveInTableOrderProperty.setValue(true); + switch (initialSaveOrderConfig.getOrderType()) { + case SPECIFIED -> saveInSpecifiedOrderProperty.setValue(true); + case ORIGINAL -> saveInOriginalProperty.setValue(true); + case TABLE -> saveInTableOrderProperty.setValue(true); } List fieldNames = new ArrayList<>(FieldFactory.getCommonFields()); - // allow entrytype field as sort criterion - fieldNames.add(InternalField.TYPE_HEADER); + fieldNames.add(InternalField.TYPE_HEADER); // allow entrytype field as sort criterion fieldNames.sort(Comparator.comparing(Field::getDisplayName)); - primarySortFieldsProperty.addAll(fieldNames); - secondarySortFieldsProperty.addAll(fieldNames); - tertiarySortFieldsProperty.addAll(fieldNames); - - savePrimarySortSelectedValueProperty.setValue(initialSaveOrderConfig.getSortCriteria().get(0).field); - saveSecondarySortSelectedValueProperty.setValue(initialSaveOrderConfig.getSortCriteria().get(1).field); - saveTertiarySortSelectedValueProperty.setValue(initialSaveOrderConfig.getSortCriteria().get(2).field); - - savePrimaryDescPropertySelected.setValue(initialSaveOrderConfig.getSortCriteria().get(0).descending); - saveSecondaryDescPropertySelected.setValue(initialSaveOrderConfig.getSortCriteria().get(1).descending); - saveTertiaryDescPropertySelected.setValue(initialSaveOrderConfig.getSortCriteria().get(2).descending); + sortableFieldsProperty.addAll(fieldNames); + sortCriteriaProperty.addAll(initialSaveOrderConfig.getSortCriteria().stream() + .map(SortCriterionViewModel::new) + .collect(Collectors.toList())); // FieldFormatterCleanupsPanel @@ -184,17 +168,8 @@ void storeSettings() { } SaveOrderConfig newSaveOrderConfig = new SaveOrderConfig( - saveInOriginalProperty.getValue(), - saveInSpecifiedOrderProperty.getValue(), - new SaveOrderConfig.SortCriterion( - savePrimarySortSelectedValueProperty.get(), - savePrimaryDescPropertySelected.getValue()), - new SaveOrderConfig.SortCriterion( - saveSecondarySortSelectedValueProperty.get(), - saveSecondaryDescPropertySelected.getValue()), - new SaveOrderConfig.SortCriterion( - saveTertiarySortSelectedValueProperty.get(), - saveTertiaryDescPropertySelected.getValue())); + SaveOrderConfig.OrderType.fromBooleans(saveInSpecifiedOrderProperty.getValue(), saveInOriginalProperty.getValue()), + sortCriteriaProperty.stream().map(SortCriterionViewModel::getCriterion).toList()); if (!newSaveOrderConfig.equals(initialSaveOrderConfig)) { if (newSaveOrderConfig.equals(SaveOrderConfig.getDefaultSaveOrder())) { @@ -281,40 +256,12 @@ public BooleanProperty saveInSpecifiedOrderProperty() { return saveInSpecifiedOrderProperty; } - public ListProperty primarySortFieldsProperty() { - return primarySortFieldsProperty; - } - - public ListProperty secondarySortFieldsProperty() { - return secondarySortFieldsProperty; - } - - public ListProperty tertiarySortFieldsProperty() { - return tertiarySortFieldsProperty; - } - - public ObjectProperty savePrimarySortSelectedValueProperty() { - return savePrimarySortSelectedValueProperty; - } - - public ObjectProperty saveSecondarySortSelectedValueProperty() { - return saveSecondarySortSelectedValueProperty; - } - - public ObjectProperty saveTertiarySortSelectedValueProperty() { - return saveTertiarySortSelectedValueProperty; - } - - public BooleanProperty savePrimaryDescPropertySelected() { - return savePrimaryDescPropertySelected; - } - - public BooleanProperty saveSecondaryDescPropertySelected() { - return saveSecondaryDescPropertySelected; + public ListProperty sortableFieldsProperty() { + return sortableFieldsProperty; } - public BooleanProperty saveTertiaryDescPropertySelected() { - return saveTertiaryDescPropertySelected; + public ListProperty sortCriteriaProperty() { + return sortCriteriaProperty; } // FieldFormatterCleanupsPanel diff --git a/src/main/java/org/jabref/gui/preferences/file/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/file/FileTab.fxml index 6d548856b98..742560fb2d3 100644 --- a/src/main/java/org/jabref/gui/preferences/file/FileTab.fxml +++ b/src/main/java/org/jabref/gui/preferences/file/FileTab.fxml @@ -10,7 +10,7 @@ - + @@ -37,9 +37,6 @@ - diff --git a/src/main/java/org/jabref/gui/preferences/importexport/ImportExportTab.java b/src/main/java/org/jabref/gui/preferences/importexport/ImportExportTab.java index 7b538180fc7..742d3f7cd41 100644 --- a/src/main/java/org/jabref/gui/preferences/importexport/ImportExportTab.java +++ b/src/main/java/org/jabref/gui/preferences/importexport/ImportExportTab.java @@ -4,6 +4,7 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.TextField; +import org.jabref.gui.commonfxcontrols.SaveOrderConfigPanel; import org.jabref.gui.preferences.AbstractPreferenceTabView; import org.jabref.gui.preferences.PreferencesTab; import org.jabref.logic.l10n.Localization; @@ -16,6 +17,8 @@ public class ImportExportTab extends AbstractPreferenceTabView sortableFieldsProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty sortCriteriaProperty = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>())); + private final PreferencesService preferencesService; private final DOIPreferences initialDOIPreferences; private final ImportSettingsPreferences initialImportSettingsPreferences; + private final SaveOrderConfig initialExportOrder; public ImportExportTabViewModel(PreferencesService preferencesService) { this.preferencesService = preferencesService; this.initialImportSettingsPreferences = preferencesService.getImportSettingsPreferences(); this.initialDOIPreferences = preferencesService.getDOIPreferences(); + this.initialExportOrder = preferencesService.getExportSaveOrder(); } @Override @@ -33,6 +53,20 @@ public void setValues() { generateKeyOnImportProperty.setValue(initialImportSettingsPreferences.generateNewKeyOnImport()); useCustomDOIProperty.setValue(initialDOIPreferences.isUseCustom()); useCustomDOINameProperty.setValue(initialDOIPreferences.getDefaultBaseURI()); + + switch (initialExportOrder.getOrderType()) { + case SPECIFIED -> exportInSpecifiedOrderProperty.setValue(true); + case ORIGINAL -> exportInOriginalProperty.setValue(true); + case TABLE -> exportInTableOrderProperty.setValue(true); + } + + List fieldNames = new ArrayList<>(FieldFactory.getCommonFields()); + fieldNames.sort(Comparator.comparing(Field::getDisplayName)); + + sortableFieldsProperty.addAll(fieldNames); + sortCriteriaProperty.addAll(initialExportOrder.getSortCriteria().stream() + .map(SortCriterionViewModel::new) + .collect(Collectors.toList())); } @Override @@ -43,6 +77,12 @@ public void storeSettings() { preferencesService.storeDOIPreferences(new DOIPreferences( useCustomDOIProperty.getValue(), useCustomDOINameProperty.getValue().trim())); + + SaveOrderConfig newSaveOrderConfig = new SaveOrderConfig( + SaveOrderConfig.OrderType.fromBooleans(exportInSpecifiedOrderProperty.getValue(), exportInTableOrderProperty.getValue()), + sortCriteriaProperty.stream().map(SortCriterionViewModel::getCriterion).toList()); + preferencesService.storeExportSaveOrder(newSaveOrderConfig); + } public BooleanProperty generateKeyOnImportProperty() { @@ -56,4 +96,26 @@ public BooleanProperty useCustomDOIProperty() { public StringProperty useCustomDOINameProperty() { return this.useCustomDOINameProperty; } + + // SaveOrderConfigPanel + + public BooleanProperty saveInOriginalProperty() { + return exportInOriginalProperty; + } + + public BooleanProperty saveInTableOrderProperty() { + return exportInTableOrderProperty; + } + + public BooleanProperty saveInSpecifiedOrderProperty() { + return exportInSpecifiedOrderProperty; + } + + public ListProperty sortableFieldsProperty() { + return sortableFieldsProperty; + } + + public ListProperty sortCriteriaProperty() { + return sortCriteriaProperty; + } } diff --git a/src/main/java/org/jabref/model/metadata/SaveOrderConfig.java b/src/main/java/org/jabref/model/metadata/SaveOrderConfig.java index a444e12a5c0..26720236083 100644 --- a/src/main/java/org/jabref/model/metadata/SaveOrderConfig.java +++ b/src/main/java/org/jabref/model/metadata/SaveOrderConfig.java @@ -1,13 +1,15 @@ package org.jabref.model.metadata; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.Objects; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.FieldFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Stores the save order config from MetaData *

@@ -15,22 +17,46 @@ */ public class SaveOrderConfig { - private static final String ORIGINAL = "original"; - private static final String SPECIFIED = "specified"; - private final LinkedList sortCriteria = new LinkedList<>(); - private boolean saveInOriginalOrder; - private boolean saveInSpecifiedOrder; + public enum OrderType { + SPECIFIED("specified"), + ORIGINAL("original"), + TABLE("table"); + + private final String name; + + OrderType(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public static SaveOrderConfig.OrderType fromBooleans(boolean saveInSpecifiedOrder, boolean saveInTableOrder) { + SaveOrderConfig.OrderType orderType = SaveOrderConfig.OrderType.ORIGINAL; + if (saveInSpecifiedOrder) { + orderType = SaveOrderConfig.OrderType.SPECIFIED; + } else if (saveInTableOrder) { + orderType = SaveOrderConfig.OrderType.TABLE; + } + + return orderType; + } + } + + private static final Logger LOGGER = LoggerFactory.getLogger(SaveOrderConfig.class); + + private final List sortCriteria = new ArrayList<>(); + private OrderType orderType; public SaveOrderConfig() { - setSaveInOriginalOrder(); + this.orderType = OrderType.ORIGINAL; } - public SaveOrderConfig(boolean saveInOriginalOrder, boolean saveInSpecifiedOrder, SortCriterion first, SortCriterion second, SortCriterion third) { - this.saveInOriginalOrder = saveInOriginalOrder; - this.saveInSpecifiedOrder = saveInSpecifiedOrder; - sortCriteria.add(first); - sortCriteria.add(second); - sortCriteria.add(third); + public SaveOrderConfig(OrderType orderType, List sortCriteria) { + this.orderType = orderType; + this.sortCriteria.addAll(sortCriteria); } private SaveOrderConfig(List data) { @@ -40,15 +66,21 @@ private SaveOrderConfig(List data) { throw new IllegalArgumentException(); } - String choice = data.get(0); - if (ORIGINAL.equals(choice)) { - setSaveInOriginalOrder(); - } else { - setSaveInSpecifiedOrder(); + try { + this.orderType = OrderType.valueOf(data.get(0)); + } catch (IllegalArgumentException ex) { + if (data.size() > 1 && data.size() % 2 == 1) { + LOGGER.warn("Could not parse sort order: {} - trying to parse the sort criteria", data.get(0)); + this.orderType = OrderType.SPECIFIED; + } else { + LOGGER.warn("Could not parse sort order: {}", data.get(0)); + this.orderType = OrderType.ORIGINAL; + return; + } } for (int index = 1; index < data.size(); index = index + 2) { - sortCriteria.addLast(new SortCriterion(FieldFactory.parseField(data.get(index)), data.get(index + 1))); + sortCriteria.add(new SortCriterion(FieldFactory.parseField(data.get(index)), data.get(index + 1))); } } @@ -58,19 +90,15 @@ public static SaveOrderConfig parse(List orderedData) { public static SaveOrderConfig getDefaultSaveOrder() { SaveOrderConfig standard = new SaveOrderConfig(); - standard.setSaveInOriginalOrder(); + standard.orderType = OrderType.ORIGINAL; return standard; } - public boolean saveInOriginalOrder() { - return saveInOriginalOrder; + public OrderType getOrderType() { + return orderType; } - public boolean saveInSpecifiedOrder() { - return saveInSpecifiedOrder; - } - - public LinkedList getSortCriteria() { + public List getSortCriteria() { return sortCriteria; } @@ -79,46 +107,34 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (o instanceof SaveOrderConfig) { - SaveOrderConfig that = (SaveOrderConfig) o; + if (o instanceof SaveOrderConfig that) { return Objects.equals(sortCriteria, that.sortCriteria) && - Objects.equals(saveInOriginalOrder, that.saveInOriginalOrder) && - Objects.equals(saveInSpecifiedOrder, that.saveInSpecifiedOrder); + Objects.equals(orderType, that.orderType); } return false; } @Override public int hashCode() { - return Objects.hash(saveInOriginalOrder, saveInSpecifiedOrder, sortCriteria); + return Objects.hash(orderType, sortCriteria); } @Override public String toString() { - return "SaveOrderConfig{" + "saveInOriginalOrder=" + saveInOriginalOrder - + "saveInSpecifiedOrder =" + saveInSpecifiedOrder - + ", sortCriteria=" + sortCriteria + + return "SaveOrderConfig{" + "orderType=" + orderType.toString() + + ", sortCriteria=" + sortCriteria + '}'; } - public void setSaveInOriginalOrder() { - this.saveInOriginalOrder = true; - } - - public void setSaveInSpecifiedOrder() { - this.saveInOriginalOrder = false; - this.saveInSpecifiedOrder = true; - } - /** * Outputs the current configuration to be consumed later by the constructor */ public List getAsStringList() { List res = new ArrayList<>(7); - if (saveInOriginalOrder) { - res.add(ORIGINAL); + if (orderType == OrderType.ORIGINAL) { + res.add(OrderType.ORIGINAL.toString()); } else { - res.add(SPECIFIED); + res.add(OrderType.SPECIFIED.toString()); } for (SortCriterion sortCriterion : sortCriteria) { diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 1b3dd68b980..d6cb06ae8e7 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -1141,43 +1141,6 @@ public void setCleanupPreset(CleanupPreset cleanupPreset) { putStringList(CLEANUP_FORMATTERS, cleanupPreset.getFormatterCleanups().getAsStringList(OS.NEWLINE)); } - @Override - public void storeExportSaveOrder(SaveOrderConfig config) { - putBoolean(EXPORT_PRIMARY_SORT_DESCENDING, config.getSortCriteria().get(0).descending); - putBoolean(EXPORT_SECONDARY_SORT_DESCENDING, config.getSortCriteria().get(1).descending); - putBoolean(EXPORT_TERTIARY_SORT_DESCENDING, config.getSortCriteria().get(2).descending); - putBoolean(EXPORT_IN_ORIGINAL_ORDER, config.saveInOriginalOrder()); - putBoolean(EXPORT_IN_SPECIFIED_ORDER, config.saveInSpecifiedOrder()); - - put(EXPORT_PRIMARY_SORT_FIELD, config.getSortCriteria().get(0).field.getName()); - put(EXPORT_SECONDARY_SORT_FIELD, config.getSortCriteria().get(1).field.getName()); - put(EXPORT_TERTIARY_SORT_FIELD, config.getSortCriteria().get(2).field.getName()); - } - - private SaveOrderConfig loadTableSaveOrder() { - SaveOrderConfig config = new SaveOrderConfig(); - - updateMainTableColumns(); - List sortOrder = createMainTableColumnSortOrder(); - - for (var column : sortOrder) { - boolean descending = (column.getSortType() == SortType.DESCENDING); - config.getSortCriteria().add(new SaveOrderConfig.SortCriterion( - FieldFactory.parseField(column.getQualifier()), - descending)); - } - - return config; - } - - @Override - public SaveOrderConfig loadExportSaveOrder() { - return new SaveOrderConfig(getBoolean(EXPORT_IN_ORIGINAL_ORDER), getBoolean(EXPORT_IN_SPECIFIED_ORDER), - new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_PRIMARY_SORT_FIELD)), getBoolean(EXPORT_PRIMARY_SORT_DESCENDING)), - new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_SECONDARY_SORT_FIELD)), getBoolean(EXPORT_SECONDARY_SORT_DESCENDING)), - new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_TERTIARY_SORT_FIELD)), getBoolean(EXPORT_TERTIARY_SORT_DESCENDING))); - } - public String getOrCreateUserId() { Optional userId = getAsOptional(USER_ID); if (userId.isPresent()) { @@ -2050,13 +2013,56 @@ public ImportFormatPreferences getImportFormatPreferences() { getSpecialFieldsPreferences().isKeywordSyncEnabled()); } + @Override + public SaveOrderConfig getExportSaveOrder() { + List sortCriteria = List.of( + new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_PRIMARY_SORT_FIELD)), getBoolean(EXPORT_PRIMARY_SORT_DESCENDING)), + new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_SECONDARY_SORT_FIELD)), getBoolean(EXPORT_SECONDARY_SORT_DESCENDING)), + new SaveOrderConfig.SortCriterion(FieldFactory.parseField(get(EXPORT_TERTIARY_SORT_FIELD)), getBoolean(EXPORT_TERTIARY_SORT_DESCENDING)) + ); + + return new SaveOrderConfig( + SaveOrderConfig.OrderType.fromBooleans(getBoolean(EXPORT_IN_SPECIFIED_ORDER), getBoolean(EXPORT_IN_ORIGINAL_ORDER)), + sortCriteria + ); + } + + @Override + public void storeExportSaveOrder(SaveOrderConfig config) { + putBoolean(EXPORT_IN_ORIGINAL_ORDER, config.getOrderType() == SaveOrderConfig.OrderType.ORIGINAL); + putBoolean(EXPORT_IN_SPECIFIED_ORDER, config.getOrderType() == SaveOrderConfig.OrderType.SPECIFIED); + + put(EXPORT_PRIMARY_SORT_FIELD, config.getSortCriteria().get(0).field.getName()); + put(EXPORT_SECONDARY_SORT_FIELD, config.getSortCriteria().get(1).field.getName()); + put(EXPORT_TERTIARY_SORT_FIELD, config.getSortCriteria().get(2).field.getName()); + putBoolean(EXPORT_PRIMARY_SORT_DESCENDING, config.getSortCriteria().get(0).descending); + putBoolean(EXPORT_SECONDARY_SORT_DESCENDING, config.getSortCriteria().get(1).descending); + putBoolean(EXPORT_TERTIARY_SORT_DESCENDING, config.getSortCriteria().get(2).descending); + } + + private SaveOrderConfig loadTableSaveOrder() { + SaveOrderConfig config = new SaveOrderConfig(); + + updateMainTableColumns(); + List sortOrder = createMainTableColumnSortOrder(); + + for (var column : sortOrder) { + boolean descending = (column.getSortType() == SortType.DESCENDING); + config.getSortCriteria().add(new SaveOrderConfig.SortCriterion( + FieldFactory.parseField(column.getQualifier()), + descending)); + } + + return config; + } + @Override public SavePreferences getSavePreferencesForExport() { Boolean saveInOriginalOrder = this.getBoolean(EXPORT_IN_ORIGINAL_ORDER); SaveOrderConfig saveOrder = null; if (!saveInOriginalOrder) { if (this.getBoolean(EXPORT_IN_SPECIFIED_ORDER)) { - saveOrder = this.loadExportSaveOrder(); + saveOrder = this.getExportSaveOrder(); } else { saveOrder = this.loadTableSaveOrder(); } diff --git a/src/main/java/org/jabref/preferences/PreferencesService.java b/src/main/java/org/jabref/preferences/PreferencesService.java index 70fa7bcfd07..bcbf0ab39c0 100644 --- a/src/main/java/org/jabref/preferences/PreferencesService.java +++ b/src/main/java/org/jabref/preferences/PreferencesService.java @@ -102,7 +102,7 @@ public interface PreferencesService { String getUser(); - SaveOrderConfig loadExportSaveOrder(); + SaveOrderConfig getExportSaveOrder(); void storeExportSaveOrder(SaveOrderConfig config); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 2eb613f94de..7b60659b08c 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -638,7 +638,6 @@ Selected=Selected Selected\ Layouts\ can\ not\ be\ empty=Selected Layouts can not be empty Reset\ default\ preview\ style=Reset default preview style Previous\ entry=Previous entry -Primary\ sort\ criterion=Primary sort criterion Problem\ with\ parsing\ entry=Problem with parsing entry Processing\ %0=Processing %0 Pull\ changes\ from\ shared\ database=Pull changes from shared database @@ -754,8 +753,6 @@ Searching\ for\ duplicates...=Searching for duplicates... Searching\ for\ files=Searching for files -Secondary\ sort\ criterion=Secondary sort criterion - Select\ all=Select all Select\ new\ encoding=Select new encoding @@ -816,8 +813,6 @@ Sublibrary\ from\ AUX\ to\ BibTeX=Sublibrary from AUX to BibTeX Switches\ between\ full\ and\ abbreviated\ journal\ name\ if\ the\ journal\ name\ is\ known.=Switches between full and abbreviated journal name if the journal name is known. -Tertiary\ sort\ criterion=Tertiary sort criterion - The\ chosen\ encoding\ '%0'\ could\ not\ encode\ the\ following\ characters\:=The chosen encoding '%0' could not encode the following characters: diff --git a/src/test/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModelTest.java b/src/test/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModelTest.java new file mode 100644 index 00000000000..da85a54cef9 --- /dev/null +++ b/src/test/java/org/jabref/gui/commonfxcontrols/SaveOrderConfigPanelViewModelTest.java @@ -0,0 +1,67 @@ +package org.jabref.gui.commonfxcontrols; + +import java.util.List; + +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.metadata.SaveOrderConfig; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SaveOrderConfigPanelViewModelTest { + + SortCriterionViewModel sortCriterionKey = new SortCriterionViewModel(new SaveOrderConfig.SortCriterion(StandardField.KEY, false)); + SortCriterionViewModel sortCriterionAuthor = new SortCriterionViewModel(new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false)); + SortCriterionViewModel sortCriterionTitle = new SortCriterionViewModel(new SaveOrderConfig.SortCriterion(StandardField.TITLE, true)); + + SaveOrderConfigPanelViewModel viewModel; + + @BeforeEach + void setUp() { + viewModel = new SaveOrderConfigPanelViewModel(); + viewModel.sortCriteriaProperty().addAll(List.of(sortCriterionKey, sortCriterionAuthor, sortCriterionTitle)); + } + + @Test + void addCriterion() { + viewModel.addCriterion(); + assertEquals(4, viewModel.sortCriteriaProperty().size()); + } + + @Test + void removeCriterion() { + SortCriterionViewModel unknownCriterion = new SortCriterionViewModel(new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false)); + viewModel.removeCriterion(unknownCriterion); + assertEquals(3, viewModel.sortCriteriaProperty().size()); + + viewModel.removeCriterion(sortCriterionAuthor); + assertEquals(2, viewModel.sortCriteriaProperty().size()); + assertEquals(List.of(sortCriterionKey, sortCriterionTitle), viewModel.sortCriteriaProperty()); + } + + @Test + void moveCriterionUp() { + viewModel.moveCriterionUp(sortCriterionTitle); + assertEquals(List.of(sortCriterionKey, sortCriterionTitle, sortCriterionAuthor), viewModel.sortCriteriaProperty()); + + viewModel.moveCriterionUp(sortCriterionTitle); + assertEquals(List.of(sortCriterionTitle, sortCriterionKey, sortCriterionAuthor), viewModel.sortCriteriaProperty()); + + viewModel.moveCriterionUp(sortCriterionTitle); + assertEquals(List.of(sortCriterionTitle, sortCriterionKey, sortCriterionAuthor), viewModel.sortCriteriaProperty()); + } + + @Test + void moveCriterionDown() { + viewModel.moveCriterionDown(sortCriterionKey); + assertEquals(List.of(sortCriterionAuthor, sortCriterionKey, sortCriterionTitle), viewModel.sortCriteriaProperty()); + + viewModel.moveCriterionDown(sortCriterionKey); + assertEquals(List.of(sortCriterionAuthor, sortCriterionTitle, sortCriterionKey), viewModel.sortCriteriaProperty()); + + viewModel.moveCriterionDown(sortCriterionKey); + assertEquals(List.of(sortCriterionAuthor, sortCriterionTitle, sortCriterionKey), viewModel.sortCriteriaProperty()); + } +} diff --git a/src/test/java/org/jabref/logic/exporter/BibtexDatabaseWriterTest.java b/src/test/java/org/jabref/logic/exporter/BibtexDatabaseWriterTest.java index 0854bb57467..87c241fa30b 100644 --- a/src/test/java/org/jabref/logic/exporter/BibtexDatabaseWriterTest.java +++ b/src/test/java/org/jabref/logic/exporter/BibtexDatabaseWriterTest.java @@ -10,6 +10,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.List; import org.jabref.logic.citationkeypattern.AbstractCitationKeyPattern; import org.jabref.logic.citationkeypattern.DatabaseCitationKeyPattern; @@ -496,9 +497,10 @@ void writeSaveActions() throws Exception { @Test void writeSaveOrderConfig() throws Exception { - SaveOrderConfig saveOrderConfig = new SaveOrderConfig(false, true, new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), - new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), - new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false)); + SaveOrderConfig saveOrderConfig = new SaveOrderConfig(SaveOrderConfig.OrderType.SPECIFIED, + List.of(new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), + new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), + new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false))); metaData.setSaveOrderConfig(saveOrderConfig); databaseWriter.savePartOfDatabase(bibtexContext, Collections.emptyList()); @@ -557,10 +559,10 @@ void writeFileDirectories() throws Exception { @Test void writeEntriesSorted() throws Exception { - SaveOrderConfig saveOrderConfig = new SaveOrderConfig(false, true, - new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), - new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), - new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false)); + SaveOrderConfig saveOrderConfig = new SaveOrderConfig(SaveOrderConfig.OrderType.SPECIFIED, + List.of(new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), + new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), + new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false))); metaData.setSaveOrderConfig(saveOrderConfig); BibEntry firstEntry = new BibEntry(); diff --git a/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java b/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java index 2879938f5ba..e0958825e03 100644 --- a/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java +++ b/src/test/java/org/jabref/logic/importer/fileformat/BibtexParserTest.java @@ -1339,8 +1339,10 @@ void integrationTestSaveOrderConfig() throws IOException { Optional saveOrderConfig = result.getMetaData().getSaveOrderConfig(); - assertEquals(new SaveOrderConfig(false, true, new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), - new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false)), + assertEquals(new SaveOrderConfig(SaveOrderConfig.OrderType.SPECIFIED, List.of( + new SaveOrderConfig.SortCriterion(StandardField.AUTHOR, false), + new SaveOrderConfig.SortCriterion(StandardField.YEAR, true), + new SaveOrderConfig.SortCriterion(StandardField.ABSTRACT, false))), saveOrderConfig.get()); }