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

single line text fields #4138

Merged
merged 9 commits into from
Jul 22, 2018
5 changes: 2 additions & 3 deletions src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ private Region setupPanel(BibEntry entry, boolean compressed, SuggestionProvider
boolean isFirstField = true;
for (String fieldName : fields) {
FieldEditorFX fieldEditor = FieldEditors.getForField(fieldName, Globals.TASK_EXECUTOR, dialogService,
Globals.journalAbbreviationLoader, Globals.prefs.getJournalAbbreviationPreferences(), Globals.prefs,
databaseContext, entry.getType(),
suggestionProviders, undoManager);
Globals.journalAbbreviationLoader.getRepository(Globals.prefs.getJournalAbbreviationPreferences()),
Globals.prefs, databaseContext, entry.getType(), suggestionProviders, undoManager);
fieldEditor.bindToEntry(entry);

editors.put(fieldName, fieldEditor);
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.jabref.gui.fieldeditors;

import java.util.List;
import java.util.function.Supplier;

import javafx.scene.control.MenuItem;

public interface ContextMenuAddable {
/**
* Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need
* to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary
* allocations when the main table is just scrolled with the entry editor open.
*/
void addToContextMenu(final Supplier<List<MenuItem>> items);
}
12 changes: 4 additions & 8 deletions src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@

import com.sun.javafx.scene.control.skin.TextAreaSkin;

public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable {
public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable, ContextMenuAddable {

public EditorTextArea() {
this("");
}

public EditorTextArea(String text) {
public EditorTextArea(final String text) {
super(text);

setMinHeight(1);
Expand Down Expand Up @@ -49,12 +49,8 @@ public EditorTextArea(String text) {
});
}

/**
* Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need
* to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary
* allocations when the main table is just scrolled with the entry editor open.
*/
public void addToContextMenu(Supplier<List<MenuItem>> items) {
@Override
public void addToContextMenu(final Supplier<List<MenuItem>> items) {
TextAreaSkin customContextSkin = new TextAreaSkin(this) {
@Override
public void populateContextMenu(ContextMenu contextMenu) {
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.jabref.gui.fieldeditors;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.function.Supplier;

import javafx.fxml.Initializable;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import com.sun.javafx.scene.control.skin.TextFieldSkin;

public class EditorTextField extends javafx.scene.control.TextField implements Initializable, ContextMenuAddable {

public EditorTextField() {
this("");
}

public EditorTextField(final String text) {
super(text);

setMinHeight(1);
setMinWidth(200);

// Should behave as a normal text field with respect to TAB behaviour
addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.TAB) {
TextFieldSkin skin = (TextFieldSkin) getSkin();
if (event.isShiftDown()) {
// Shift + Tab > previous text area
skin.getBehavior().traversePrevious();
} else {
if (event.isControlDown()) {
// Ctrl + Tab > insert tab
skin.getBehavior().callAction("InsertTab");
} else {
// Tab > next text area
skin.getBehavior().traverseNext();
}
}
event.consume();
}
});
}

@Override
public void addToContextMenu(final Supplier<List<MenuItem>> items) {
TextFieldSkin customContextSkin = new TextFieldSkin(this) {
@Override
public void populateContextMenu(ContextMenu contextMenu) {
super.populateContextMenu(contextMenu);
contextMenu.getItems().addAll(0, items.get());
}
};
setSkin(customContextSkin);
}

@Override
public void initialize(URL location, ResourceBundle resources) {
// not needed
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.fieldeditors;

import javafx.scene.control.TextInputControl;

import org.jabref.gui.util.IconValidationDecorator;
import org.jabref.preferences.JabRefPreferences;

Expand All @@ -14,11 +16,11 @@ public EditorValidator(JabRefPreferences preferences) {
this.preferences = preferences;
}

public void configureValidation(ValidationStatus status, EditorTextArea area) {
public void configureValidation(final ValidationStatus status, final TextInputControl textInput) {
if (preferences.getBoolean(JabRefPreferences.VALIDATE_IN_ENTRY_EDITOR)) {
ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
validationVisualizer.setDecoration(new IconValidationDecorator());
validationVisualizer.initVisualization(status, area);
validationVisualizer.initVisualization(status, textInput);
}
}
}
29 changes: 21 additions & 8 deletions src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
import org.jabref.gui.autocompleter.SuggestionProviders;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.FieldName;
import org.jabref.model.entry.FieldProperty;
Expand All @@ -29,12 +28,26 @@ public class FieldEditors {

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

public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecutor, DialogService dialogService, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, JabRefPreferences preferences, BibDatabaseContext databaseContext, String entryType, SuggestionProviders suggestionProviders, UndoManager undoManager) {
public static FieldEditorFX getForField(final String fieldName,
final TaskExecutor taskExecutor,
final DialogService dialogService,
final JournalAbbreviationRepository journalAbbreviationRepository,
final JabRefPreferences preferences,
final BibDatabaseContext databaseContext,
final String entryType,
final SuggestionProviders suggestionProviders,
final UndoManager undoManager) {
final Set<FieldProperty> fieldExtras = InternalBibtexFields.getFieldProperties(fieldName);

AutoCompleteSuggestionProvider<?> suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData());
final AutoCompleteSuggestionProvider<?> suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData());

FieldCheckers fieldCheckers = new FieldCheckers(databaseContext, preferences.getFileDirectoryPreferences(), journalAbbreviationLoader.getRepository(journalAbbreviationPreferences), preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
final FieldCheckers fieldCheckers = new FieldCheckers(
databaseContext,
preferences.getFileDirectoryPreferences(),
journalAbbreviationRepository,
preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));

final boolean isSingleLine = InternalBibtexFields.isSingleLineField(fieldName);

if (preferences.getTimestampPreferences().getTimestampField().equals(fieldName) || fieldExtras.contains(FieldProperty.DATE)) {
if (fieldExtras.contains(FieldProperty.ISO_DATE)) {
Expand All @@ -45,7 +58,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu
} else if (fieldExtras.contains(FieldProperty.EXTERNAL)) {
return new UrlEditor(fieldName, dialogService, suggestionProvider, fieldCheckers, preferences);
} else if (fieldExtras.contains(FieldProperty.JOURNAL_NAME)) {
return new JournalEditor(fieldName, journalAbbreviationLoader, preferences, suggestionProvider, fieldCheckers);
return new JournalEditor(fieldName, journalAbbreviationRepository, preferences, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.DOI) || fieldExtras.contains(FieldProperty.EPRINT) || fieldExtras.contains(FieldProperty.ISBN)) {
return new IdentifierEditor(fieldName, taskExecutor, dialogService, suggestionProvider, fieldCheckers, preferences);
} else if (fieldExtras.contains(FieldProperty.OWNER)) {
Expand All @@ -71,7 +84,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu
} else if (fieldExtras.contains(FieldProperty.SINGLE_ENTRY_LINK) || fieldExtras.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) {
return new LinkedEntriesEditor(fieldName, databaseContext, suggestionProvider, fieldCheckers);
} else if (fieldExtras.contains(FieldProperty.PERSON_NAMES)) {
return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers);
return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers, isSingleLine);
} else if (FieldName.KEYWORDS.equals(fieldName)) {
return new KeywordsEditor(fieldName, suggestionProvider, fieldCheckers, preferences);
} else if (fieldExtras.contains(FieldProperty.MULTILINE_TEXT)) {
Expand All @@ -81,7 +94,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu
}

// default
return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences);
return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences, isSingleLine);
}

@SuppressWarnings("unchecked")
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding;
import org.jabref.gui.fieldeditors.contextmenu.EditorMenus;
import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;

Expand All @@ -19,8 +19,8 @@ public class JournalEditor extends HBox implements FieldEditorFX {
@FXML private JournalEditorViewModel viewModel;
@FXML private EditorTextArea textArea;

public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JabRefPreferences preferences, AutoCompleteSuggestionProvider<?> suggestionProvider, FieldCheckers fieldCheckers) {
this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, preferences.getJournalAbbreviationPreferences(), fieldCheckers);
public JournalEditor(String fieldName, JournalAbbreviationRepository journalAbbreviationRepository, JabRefPreferences preferences, AutoCompleteSuggestionProvider<?> suggestionProvider, FieldCheckers fieldCheckers) {
this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationRepository, fieldCheckers);

ViewLoader.view(this)
.root(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,25 @@

import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider;
import org.jabref.logic.integrity.FieldCheckers;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.model.strings.StringUtil;

public class JournalEditorViewModel extends AbstractEditorViewModel {
private final JournalAbbreviationLoader journalAbbreviationLoader;
private final JournalAbbreviationPreferences journalAbbreviationPreferences;
private final JournalAbbreviationRepository journalAbbreviationRepository;

public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider<?> suggestionProvider, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, FieldCheckers fieldCheckers) {
public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider<?> suggestionProvider, JournalAbbreviationRepository journalAbbreviationRepository, FieldCheckers fieldCheckers) {
super(fieldName, suggestionProvider, fieldCheckers);

this.journalAbbreviationLoader = journalAbbreviationLoader;
this.journalAbbreviationPreferences = journalAbbreviationPreferences;
this.journalAbbreviationRepository = journalAbbreviationRepository;
}

public void toggleAbbreviation() {
if (StringUtil.isBlank(text.get())) {
return;
}

JournalAbbreviationRepository abbreviationRepository = journalAbbreviationLoader.getRepository(journalAbbreviationPreferences);
if (abbreviationRepository.isKnownName(text.get())) {
Optional<String> nextAbbreviation = abbreviationRepository.getNextAbbreviation(text.get());
if (journalAbbreviationRepository.isKnownName(text.get())) {
Optional<String> nextAbbreviation = journalAbbreviationRepository.getNextAbbreviation(text.get());

if (nextAbbreviation.isPresent()) {
text.set(nextAbbreviation.get());
Expand Down
27 changes: 17 additions & 10 deletions src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.TextInputControl;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;

Expand All @@ -16,20 +17,26 @@ public class PersonsEditor extends HBox implements FieldEditorFX {

@FXML private final PersonsEditorViewModel viewModel;

private EditorTextArea textArea;
private TextInputControl textInput;

public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider<?> suggestionProvider, JabRefPreferences preferences, FieldCheckers fieldCheckers) {
public PersonsEditor(final String fieldName,
final AutoCompleteSuggestionProvider<?> suggestionProvider,
final JabRefPreferences preferences,
final FieldCheckers fieldCheckers,
final boolean isSingleLine) {
this.viewModel = new PersonsEditorViewModel(fieldName, suggestionProvider, preferences.getAutoCompletePreferences(), fieldCheckers);

textArea = new EditorTextArea();
HBox.setHgrow(textArea, Priority.ALWAYS);
textArea.textProperty().bindBidirectional(viewModel.textProperty());
textArea.addToContextMenu(EditorMenus.getNameMenu(textArea));
this.getChildren().add(textArea);
textInput = isSingleLine
? new EditorTextField()
: new EditorTextArea();
HBox.setHgrow(textInput, Priority.ALWAYS);
textInput.textProperty().bindBidirectional(viewModel.textProperty());
((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getNameMenu(textInput));
this.getChildren().add(textInput);

AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy());
AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy());

new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea);
new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput);
}

@Override
Expand All @@ -44,7 +51,7 @@ public Parent getNode() {

@Override
public void requestFocus() {
textArea.requestFocus();
textInput.requestFocus();
}

}
31 changes: 23 additions & 8 deletions src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.TextInputControl;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;

Expand All @@ -17,22 +18,36 @@ public class SimpleEditor extends HBox implements FieldEditorFX {

@FXML private final SimpleEditorViewModel viewModel;

public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider<?> suggestionProvider, FieldCheckers fieldCheckers, JabRefPreferences preferences) {
public SimpleEditor(final String fieldName,
final AutoCompleteSuggestionProvider<?> suggestionProvider,
final FieldCheckers fieldCheckers,
final JabRefPreferences preferences,
final boolean isSingleLine) {
this.viewModel = new SimpleEditorViewModel(fieldName, suggestionProvider, fieldCheckers);

EditorTextArea textArea = new EditorTextArea();
HBox.setHgrow(textArea, Priority.ALWAYS);
textArea.textProperty().bindBidirectional(viewModel.textProperty());
textArea.addToContextMenu(EditorMenus.getDefaultMenu(textArea));
this.getChildren().add(textArea);
TextInputControl textInput = isSingleLine
? new EditorTextField()
: new EditorTextArea();
HBox.setHgrow(textInput, Priority.ALWAYS);
textInput.textProperty().bindBidirectional(viewModel.textProperty());
((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getDefaultMenu(textInput));
this.getChildren().add(textInput);

AutoCompletionTextInputBinding<?> autoCompleter = AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionStrategy());
AutoCompletionTextInputBinding<?> autoCompleter = AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionStrategy());
if (suggestionProvider instanceof ContentSelectorSuggestionProvider) {
// If content selector values are present, then we want to show the auto complete suggestions immediately on focus
autoCompleter.setShowOnFocus(true);
}

new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea);
new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput);
}


public SimpleEditor(final String fieldName,
final AutoCompleteSuggestionProvider<?> suggestionProvider,
final FieldCheckers fieldCheckers,
final JabRefPreferences preferences) {
this(fieldName, suggestionProvider, fieldCheckers, preferences, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.jabref.gui.fieldeditors.contextmenu;

import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextInputControl;

import org.jabref.logic.l10n.Localization;

class ClearField extends MenuItem {

public ClearField(TextArea opener) {
public ClearField(TextInputControl opener) {
super(Localization.lang("Clear"));
setOnAction(event -> opener.setText(""));
}
Expand Down
Loading