package org.jabref.gui.keyboard; import java.util.Optional; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import org.jabref.gui.IconTheme; import com.google.common.base.CaseFormat; /** * This class represents a view model for objects of the KeyBinding * class. It has two properties representing the localized name of an * action and its key bind. It can also represent a key binding category * instead of a key bind itself. * */ public class KeyBindingViewModel { private KeyBinding keyBinding = null; private String realBinding = ""; private ObservableList<KeyBindingViewModel> children = FXCollections.observableArrayList(); private KeyBindingRepository keyBindingRepository; private final SimpleStringProperty displayName = new SimpleStringProperty(); private final SimpleStringProperty shownBinding = new SimpleStringProperty(); private final KeyBindingCategory category; public KeyBindingViewModel(KeyBindingRepository keyBindingRepository, KeyBinding keyBinding, String binding) { this(keyBindingRepository, keyBinding.getCategory()); this.keyBinding = keyBinding; setDisplayName(); setBinding(binding); } public KeyBindingViewModel(KeyBindingRepository keyBindingRepository, KeyBindingCategory category) { this.keyBindingRepository = keyBindingRepository; this.category = category; setDisplayName(); } public ObservableList<KeyBindingViewModel> getChildren() { return children; } public KeyBinding getKeyBinding() { return keyBinding; } public StringProperty shownBindingProperty() { return this.shownBinding; } public String getBinding() { return realBinding; } private void setBinding(String bind) { this.realBinding = bind; String[] parts = bind.split(" "); String displayBind = ""; for (String part : parts) { displayBind += CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, part) + " "; } this.shownBinding.set(displayBind.trim().replace(" ", " + ")); } private void setDisplayName() { this.displayName.set((keyBinding == null) ? this.category.getName() : keyBinding.getLocalization()); } public StringProperty nameProperty() { return this.displayName; } public boolean isCategory() { return (keyBinding == null) ? true : false; } /** * Sets a a new key bind to this objects key binding object if * the given key event is a valid combination of keys. * * @param evt as KeyEvent * @return true if the KeyEvent is a valid binding, false else */ public boolean setNewBinding(KeyEvent evt) { // validate the shortcut is no modifier key KeyCode code = evt.getCode(); if (code.isModifierKey() || (code == KeyCode.BACK_SPACE) || (code == KeyCode.SPACE) || (code == KeyCode.TAB) || (code == KeyCode.ENTER) || (code == KeyCode.UNDEFINED)) { return false; } // gather the pressed modifier keys String modifiers = ""; if (evt.isControlDown()) { modifiers = "ctrl "; } if (evt.isShiftDown()) { modifiers += "shift "; } if (evt.isAltDown()) { modifiers += "alt "; } // if no modifier keys are pressed, only special keys can be shortcuts if (modifiers.isEmpty()) { if (!(code.isFunctionKey() || (code == KeyCode.ESCAPE) || (code == KeyCode.DELETE))) { return false; } } String newShortcut = modifiers + code; setBinding(newShortcut); return true; } /** * This method will reset the key bind of this models KeyBinding object to it's default bind */ public void resetToDefault() { if (!isCategory()) { String key = getKeyBinding().getKey(); keyBindingRepository.resetToDefault(key); setBinding(keyBindingRepository.get(key)); } } public Optional<IconTheme.JabRefIcon> getIcon() { return isCategory() ? Optional.empty() : Optional.of(IconTheme.JabRefIcon.CLEANUP_ENTRIES); } }