diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml index 728897bd5db..b5139c6ebb6 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml @@ -7,31 +7,54 @@ - - - - - - - - - - - - - - - - + + + + + + + diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogView.java b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogView.java index 58dc75d6e23..dafc2035b80 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogView.java +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogView.java @@ -2,20 +2,23 @@ import javax.inject.Inject; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn.CellEditEvent; import javafx.scene.control.TableView; +import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.util.converter.DefaultStringConverter; import org.jabref.gui.DialogService; -import org.jabref.gui.icon.IconTheme.JabRefIcons; +import org.jabref.gui.icon.IconTheme; import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.IconValidationDecorator; +import org.jabref.gui.util.ValueTableCellFactory; import org.jabref.gui.util.ViewModelTextFieldTableCellVisualizationFactory; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabase; @@ -25,26 +28,26 @@ public class BibtexStringEditorDialogView extends BaseDialog { - @FXML private Button btnNewString; - @FXML private Button btnRemove; - @FXML private Button btnHelp; + @FXML private TableView stringsList; + @FXML private TableColumn labelColumn; + @FXML private TableColumn contentColumn; + @FXML private TableColumn actionsColumn; + @FXML private TextField addStringLabel; + @FXML private TextField addStringContent; + @FXML private Button addStringButton; @FXML private ButtonType saveButton; - @FXML private TableView tblStrings; - @FXML private TableColumn colLabel; - @FXML private TableColumn colContent; - private final ControlsFxVisualizer visualizer = new ControlsFxVisualizer(); private final BibtexStringEditorDialogViewModel viewModel; @Inject private DialogService dialogService; public BibtexStringEditorDialogView(BibDatabase database) { - viewModel = new BibtexStringEditorDialogViewModel(database); + this.viewModel = new BibtexStringEditorDialogViewModel(database); ViewLoader.view(this) - .load() - .setAsDialogPane(this); + .load() + .setAsDialogPane(this); Button btnSave = (Button) this.getDialogPane().lookupButton(saveButton); @@ -64,51 +67,72 @@ public BibtexStringEditorDialogView(BibDatabase database) { private void initialize() { visualizer.setDecoration(new IconValidationDecorator()); - btnHelp.setGraphic(JabRefIcons.HELP.getGraphicNode()); - btnHelp.setTooltip(new Tooltip(Localization.lang("Open Help page"))); - - btnNewString.setTooltip(new Tooltip(Localization.lang("New string"))); - btnRemove.setTooltip(new Tooltip(Localization.lang("Remove selected strings"))); - - colLabel.setCellValueFactory(cellData -> cellData.getValue().labelProperty()); - new ViewModelTextFieldTableCellVisualizationFactory().withValidation(BibtexStringViewModel::labelValidation, visualizer).install(colLabel, new DefaultStringConverter()); - - colContent.setCellValueFactory(cellData -> cellData.getValue().contentProperty()); - new ViewModelTextFieldTableCellVisualizationFactory().withValidation(BibtexStringViewModel::contentValidation, visualizer).install(colContent, new DefaultStringConverter()); - - colLabel.setOnEditCommit((CellEditEvent cell) -> { + addStringButton.setTooltip(new Tooltip(Localization.lang("New string"))); + labelColumn.setSortable(true); + labelColumn.setReorderable(false); + labelColumn.setCellValueFactory(cellData -> cellData.getValue().labelProperty()); + new ViewModelTextFieldTableCellVisualizationFactory() + .withValidation(BibtexStringEditorItemModel::labelValidation, visualizer) + .install(labelColumn, new DefaultStringConverter()); + labelColumn.setOnEditCommit((CellEditEvent cell) -> { String newLabelValue = cell.getNewValue(); - if (cell.getTableView().getItems().stream().anyMatch(strs -> strs.labelProperty().get().equals(newLabelValue))) { - + if (viewModel.labelAlreadyExists(newLabelValue)) { dialogService.showErrorDialogAndWait(Localization.lang("A string with the label '%0' already exists.", newLabelValue)); - cell.getRowValue().setLabel(""); + cell.getRowValue().setLabel(cell.getOldValue()); } else { - cell.getRowValue().setLabel(cell.getNewValue()); + cell.getRowValue().setLabel(newLabelValue); } }); - colContent.setOnEditCommit((CellEditEvent cell) -> { - cell.getRowValue().setContent(cell.getNewValue()); + + contentColumn.setSortable(true); + contentColumn.setReorderable(false); + contentColumn.setCellValueFactory(cellData -> cellData.getValue().contentProperty()); + new ViewModelTextFieldTableCellVisualizationFactory() + .withValidation(BibtexStringEditorItemModel::contentValidation, visualizer) + .install(contentColumn, new DefaultStringConverter()); + contentColumn.setOnEditCommit((CellEditEvent cell) -> + cell.getRowValue().setContent(cell.getNewValue())); + + actionsColumn.setSortable(false); + actionsColumn.setReorderable(false); + actionsColumn.setCellValueFactory(cellData -> cellData.getValue().labelProperty()); + new ValueTableCellFactory() + .withGraphic(label -> IconTheme.JabRefIcons.DELETE_ENTRY.getGraphicNode()) + .withTooltip(label -> Localization.lang("Remove string %0", label)) + .withOnMouseClickedEvent(item -> evt -> + viewModel.removeString(stringsList.getFocusModel().getFocusedItem())) + .install(actionsColumn); + + addStringLabel.textProperty().bindBidirectional(viewModel.addLabelProperty()); + addStringLabel.addEventFilter(KeyEvent.KEY_PRESSED, event -> { + if (event.getCode() == KeyCode.ENTER) { + addStringContent.requestFocus(); + addStringContent.selectAll(); + event.consume(); + } }); - tblStrings.itemsProperty().bindBidirectional(viewModel.allStringsProperty()); - tblStrings.setEditable(true); + addStringContent.textProperty().bindBidirectional(viewModel.addContentProperty()); + addStringContent.addEventFilter(KeyEvent.KEY_PRESSED, event -> { + if (event.getCode() == KeyCode.ENTER) { + viewModel.addNewString(); + addStringLabel.requestFocus(); + event.consume(); + } + }); - viewModel.seletedItemProperty().bind(tblStrings.getSelectionModel().selectedItemProperty()); + stringsList.itemsProperty().bindBidirectional(viewModel.stringsListProperty()); + stringsList.setEditable(true); } @FXML - private void addString(ActionEvent event) { + private void addString() { viewModel.addNewString(); } @FXML - private void openHelp(ActionEvent event) { + private void openHelp() { viewModel.openHelpPage(); } - - @FXML - private void removeString(ActionEvent event) { - viewModel.removeString(); - } } diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogViewModel.java b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogViewModel.java index 12f8508e195..8ec6c755e25 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogViewModel.java +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialogViewModel.java @@ -6,10 +6,10 @@ 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.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -20,13 +20,16 @@ import org.jabref.logic.help.HelpFile; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibtexString; +import org.jabref.model.strings.StringUtil; import org.fxmisc.easybind.EasyBind; public class BibtexStringEditorDialogViewModel extends AbstractViewModel { - private final ListProperty allStrings = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final ObjectProperty selectedItemProperty = new SimpleObjectProperty<>(); + private final ListProperty stringsListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final StringProperty addLabelProperty = new SimpleStringProperty(); + private final StringProperty addContentProperty = new SimpleStringProperty(); + private final BibDatabase bibDatabase; private final BooleanProperty validProperty = new SimpleBooleanProperty(); @@ -34,57 +37,70 @@ public BibtexStringEditorDialogViewModel(BibDatabase bibDatabase) { this.bibDatabase = bibDatabase; addAllStringsFromDB(); - ObservableList> allValidProperty = EasyBind.map(allStringsProperty(), BibtexStringViewModel::combinedValidationValidProperty); + ObservableList> allValidProperty = EasyBind.map(stringsListProperty(), BibtexStringEditorItemModel::combinedValidationValidProperty); validProperty.bind(EasyBind.combine(allValidProperty, stream -> stream.allMatch(valid -> valid))); } private void addAllStringsFromDB() { - - Set strings = bibDatabase.getStringValues() - .stream() - .sorted(new BibtexStringComparator(false)) - .map(this::convertFromBibTexString) - .collect(Collectors.toSet()); - allStrings.addAll(strings); + Set strings = bibDatabase.getStringValues().stream() + .sorted(new BibtexStringComparator(false)) + .map(this::convertFromBibTexString) + .collect(Collectors.toSet()); + stringsListProperty.addAll(strings); } - public ListProperty allStringsProperty() { - return this.allStrings; + public boolean addNewString() { + if (!StringUtil.isNullOrEmpty(addLabelProperty.getValue()) + && !labelAlreadyExists(addLabelProperty.getValue())) { + stringsListProperty.add(new BibtexStringEditorItemModel(addLabelProperty.getValue(), addContentProperty.getValue())); + addLabelProperty.setValue(""); + addContentProperty.setValue(""); + return true; + } else { + return false; + } } - public void addNewString() { - allStrings.add(new BibtexStringViewModel("", "")); + public void removeString(BibtexStringEditorItemModel item) { + stringsListProperty.remove(item); } - public void removeString() { - BibtexStringViewModel toBeRemoved = selectedItemProperty.getValue(); - allStrings.remove(toBeRemoved); - } - - private BibtexStringViewModel convertFromBibTexString(BibtexString bibtexString) { - return new BibtexStringViewModel(bibtexString.getName(), bibtexString.getContent()); - } - - public ObjectProperty seletedItemProperty() { - return this.selectedItemProperty; + private BibtexStringEditorItemModel convertFromBibTexString(BibtexString bibtexString) { + return new BibtexStringEditorItemModel(bibtexString.getName(), bibtexString.getContent()); } public void save() { - List stringsToAdd = allStrings.stream().map(this::fromBibtexStringViewModel).collect(Collectors.toList()); + List stringsToAdd = stringsListProperty.stream().map(this::fromBibtexStringViewModel).collect(Collectors.toList()); bibDatabase.setStrings(stringsToAdd); } - private BibtexString fromBibtexStringViewModel(BibtexStringViewModel viewModel) { + private BibtexString fromBibtexStringViewModel(BibtexStringEditorItemModel viewModel) { String label = viewModel.labelProperty().getValue(); String content = viewModel.contentProperty().getValue(); return new BibtexString(label, content); } - public BooleanProperty validProperty() { - return validProperty; + public boolean labelAlreadyExists(String label) { + return stringsListProperty.stream().anyMatch(item -> item.labelProperty().getValue().equals(label)); } public void openHelpPage() { HelpAction.openHelpPage(HelpFile.STRING_EDITOR); } + + public ListProperty stringsListProperty() { + return stringsListProperty; + } + + public BooleanProperty validProperty() { + return validProperty; + } + + public StringProperty addLabelProperty() { + return addLabelProperty; + } + + public StringProperty addContentProperty() { + return addContentProperty; + } } diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringViewModel.java b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorItemModel.java similarity index 93% rename from src/main/java/org/jabref/gui/metadata/BibtexStringViewModel.java rename to src/main/java/org/jabref/gui/metadata/BibtexStringEditorItemModel.java index c8dd02e52a6..00ba787ce42 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringViewModel.java +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorItemModel.java @@ -14,7 +14,7 @@ import de.saxsys.mvvmfx.utils.validation.ValidationStatus; import de.saxsys.mvvmfx.utils.validation.Validator; -public class BibtexStringViewModel { +public class BibtexStringEditorItemModel { private final static Pattern IS_NUMBER = Pattern.compile("-?\\d+(\\.\\d+)?"); @@ -25,12 +25,12 @@ public class BibtexStringViewModel { private final Validator contentValidator; private final CompositeValidator combinedValidator; - public BibtexStringViewModel(String label, String content) { + public BibtexStringEditorItemModel(String label, String content) { this.labelProperty.setValue(label); this.contentProperty.setValue(content); - labelValidator = new FunctionBasedValidator<>(this.labelProperty, BibtexStringViewModel::validateLabel); - contentValidator = new FunctionBasedValidator<>(this.contentProperty, BibtexStringViewModel::validateContent); + labelValidator = new FunctionBasedValidator<>(this.labelProperty, BibtexStringEditorItemModel::validateLabel); + contentValidator = new FunctionBasedValidator<>(this.contentProperty, BibtexStringEditorItemModel::validateContent); combinedValidator = new CompositeValidator(labelValidator, contentValidator); } diff --git a/src/main/java/org/jabref/gui/preferences/NameFormatterTab.fxml b/src/main/java/org/jabref/gui/preferences/NameFormatterTab.fxml index c6c4d1f9c67..1053c1347f8 100644 --- a/src/main/java/org/jabref/gui/preferences/NameFormatterTab.fxml +++ b/src/main/java/org/jabref/gui/preferences/NameFormatterTab.fxml @@ -23,7 +23,7 @@ + editable="false" resizable="false" reorderable="false"/> @@ -36,7 +36,7 @@