diff --git a/src/main/java/org/jabref/gui/Base.css b/src/main/java/org/jabref/gui/Base.css
index 2db5a049c00..0c9565430e4 100644
--- a/src/main/java/org/jabref/gui/Base.css
+++ b/src/main/java/org/jabref/gui/Base.css
@@ -1036,3 +1036,7 @@ We want to have a look that matches our icons in the tool-bar */
.dialog-pane {
-fx-background-color: -fx-control-inner-background;
}
+
+.preference-sidepane {
+ -fx-background-color: -jr-sidepane-background;
+}
diff --git a/src/main/java/org/jabref/gui/preferences/ExternalTab.java b/src/main/java/org/jabref/gui/preferences/ExternalTab.java
index a2bca6c0077..9fa691deb0f 100644
--- a/src/main/java/org/jabref/gui/preferences/ExternalTab.java
+++ b/src/main/java/org/jabref/gui/preferences/ExternalTab.java
@@ -58,7 +58,7 @@ class ExternalTab implements PrefsTab {
private final DialogService dialogService;
private final FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder().build();
- public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) {
+ public ExternalTab(JabRefFrame frame, JabRefPreferences prefs) {
this.prefs = prefs;
this.frame = frame;
dialogService = frame.getDialogService();
diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
new file mode 100644
index 00000000000..3eec679c4f4
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.java b/src/main/java/org/jabref/gui/preferences/FileTab.java
deleted file mode 100644
index 6f005da305a..00000000000
--- a/src/main/java/org/jabref/gui/preferences/FileTab.java
+++ /dev/null
@@ -1,274 +0,0 @@
-package org.jabref.gui.preferences;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import javafx.collections.FXCollections;
-import javafx.geometry.Pos;
-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.control.Separator;
-import javafx.scene.control.TextField;
-import javafx.scene.control.ToggleGroup;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-
-import org.jabref.gui.DialogService;
-import org.jabref.gui.actions.ActionFactory;
-import org.jabref.gui.actions.StandardActions;
-import org.jabref.gui.help.HelpAction;
-import org.jabref.gui.util.DirectoryDialogConfiguration;
-import org.jabref.logic.help.HelpFile;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.logic.util.OS;
-import org.jabref.model.entry.FieldName;
-import org.jabref.model.metadata.FilePreferences;
-import org.jabref.preferences.JabRefPreferences;
-
-/**
- * Preferences tab for file options. These options were moved out from GeneralTab to
- * resolve the space issue.
- */
-class FileTab extends Pane implements PrefsTab {
-
- private final DialogService dialogService;
- private final JabRefPreferences prefs;
-
- private final CheckBox backup;
- private final CheckBox localAutoSave;
- private final CheckBox openLast;
- private final ComboBox newlineSeparator;
- private final CheckBox reformatFileOnSaveAndExport;
- private final RadioButton resolveStringsStandard;
- private final RadioButton resolveStringsAll;
- private final TextField nonWrappableFields;
- private final TextField doNotResolveStringsFor;
- private final GridPane builder = new GridPane();
-
- private final TextField fileDir;
- private final CheckBox bibLocAsPrimaryDir;
- private final CheckBox runAutoFileSearch;
- private final CheckBox allowFileAutoOpenBrowse;
- private final RadioButton useRegExpComboBox;
- private final RadioButton matchExactKeyOnly = new RadioButton(
- Localization.lang("Autolink only files that match the BibTeX key"));
- private final RadioButton matchStartsWithKey = new RadioButton(
- Localization.lang("Autolink files with names starting with the BibTeX key"));
- private final TextField regExpTextField;
-
- public FileTab(DialogService dialogService, JabRefPreferences prefs) {
- this.dialogService = dialogService;
- this.prefs = prefs;
- builder.setVgap(7);
-
- ActionFactory factory = new ActionFactory(prefs.getKeyBindingRepository());
- bibLocAsPrimaryDir = new CheckBox(Localization.lang("Use the BIB file location as primary file directory"));
- bibLocAsPrimaryDir.setAccessibleText(Localization.lang("When downloading files, or moving linked files to the "
- + "file directory, prefer the BIB file location rather than the file directory set above"));
-
- runAutoFileSearch = new CheckBox(Localization.lang("When opening file link, search for matching file if no link is defined"));
- allowFileAutoOpenBrowse = new CheckBox(Localization.lang("Automatically open browse dialog when creating new file link"));
- regExpTextField = new TextField();
- useRegExpComboBox = new RadioButton(Localization.lang("Use regular expression search"));
- useRegExpComboBox.setOnAction(e -> regExpTextField.setEditable(useRegExpComboBox.isSelected()));
-
- openLast = new CheckBox(Localization.lang("Open last edited libraries at startup"));
- backup = new CheckBox(Localization.lang("Backup old file when saving"));
- localAutoSave = new CheckBox(Localization.lang("Autosave local libraries"));
- resolveStringsAll = new RadioButton(Localization.lang("Resolve strings for all fields except") + ":");
- resolveStringsStandard = new RadioButton(Localization.lang("Resolve strings for standard BibTeX fields only"));
-
- // This is sort of a quick hack
- newlineSeparator = new ComboBox<>(FXCollections.observableArrayList("CR", "CR/LF", "LF"));
-
- reformatFileOnSaveAndExport = new CheckBox(Localization.lang("Always reformat BIB file on save and export"));
-
- nonWrappableFields = new TextField();
- doNotResolveStringsFor = new TextField();
- nonWrappableFields.setPrefSize(80, 25);
- doNotResolveStringsFor.setPrefSize(80, 25);
- builder.setPrefSize(800, 600);
-
- Label general = new Label(Localization.lang("General"));
- general.getStyleClass().add("sectionHeader");
- builder.add(general, 1, 1);
- builder.add(openLast, 1, 2);
- builder.add(backup, 1, 3);
-
- HBox notWrapBox = new HBox();
- notWrapBox.setSpacing(15);
- notWrapBox.setAlignment(Pos.CENTER_LEFT);
- Label label = new Label(Localization.lang("Do not wrap the following fields when saving") + ":");
- notWrapBox.getChildren().setAll(label, nonWrappableFields);
- builder.add(notWrapBox, 1, 4);
-
- final ToggleGroup resolveGroup = new ToggleGroup();
- builder.add(resolveStringsStandard, 1, 5);
- builder.add(resolveStringsAll, 1, 6);
- builder.add(doNotResolveStringsFor, 2, 6);
- resolveStringsStandard.setToggleGroup(resolveGroup);
- resolveStringsAll.setToggleGroup(resolveGroup);
- Label newlineSeparatorLabel = new Label(Localization.lang("Newline separator") + ":");
- builder.add(newlineSeparatorLabel, 1, 7);
- builder.add(newlineSeparator, 2, 7);
- builder.add(reformatFileOnSaveAndExport, 1, 8);
-
- builder.add(new Separator(), 1, 13);
- Label externalFileLinks = new Label(Localization.lang("External file links"));
- externalFileLinks.getStyleClass().add("sectionHeader");
- builder.add(externalFileLinks, 1, 14);
-
- // Main File Directory choice
- HBox mainFileDirectoryBox = new HBox();
- mainFileDirectoryBox.setSpacing(10);
- mainFileDirectoryBox.setAlignment(Pos.CENTER_LEFT);
- fileDir = new TextField();
- label = new Label(Localization.lang("Main file directory") + ':');
- Button browse = new Button(Localization.lang("Browse"));
- browse.setPrefSize(80, 20);
- browse.setOnAction(e -> {
- DirectoryDialogConfiguration dirDialogConfiguration =
- new DirectoryDialogConfiguration.Builder().withInitialDirectory(Paths.get(fileDir.getText())).build();
- dialogService.showDirectorySelectionDialog(dirDialogConfiguration)
- .ifPresent(f -> fileDir.setText(f.toString()));
- });
- mainFileDirectoryBox.getChildren().setAll(label, fileDir, browse);
- builder.add(mainFileDirectoryBox, 1, 15);
-
- builder.add(bibLocAsPrimaryDir, 1, 16);
- final ToggleGroup autolinkGroup = new ToggleGroup();
- builder.add(matchStartsWithKey, 1, 17);
- builder.add(matchExactKeyOnly, 1, 18);
- builder.add(useRegExpComboBox, 1, 19);
- builder.add(regExpTextField, 2, 19);
- matchStartsWithKey.setToggleGroup(autolinkGroup);
- matchExactKeyOnly.setToggleGroup(autolinkGroup);
- useRegExpComboBox.setToggleGroup(autolinkGroup);
-
- Button help = factory.createIconButton(StandardActions.HELP_REGEX_SEARCH, new HelpAction(HelpFile.REGEX_SEARCH));
- builder.add(help, 3, 16);
- builder.add(runAutoFileSearch, 1, 21);
- builder.add(allowFileAutoOpenBrowse, 1, 22);
-
- builder.add(new Separator(), 1, 25);
- Label autosave = new Label(Localization.lang("Autosave"));
- autosave.getStyleClass().add("sectionHeader");
- builder.add(autosave, 1, 27);
-
- HBox saveAutosaveBox = new HBox();
- saveAutosaveBox.setSpacing(7);
- saveAutosaveBox.setAlignment(Pos.CENTER_LEFT);
- Button helpAutosave = factory.createIconButton(StandardActions.HELP, new HelpAction(HelpFile.AUTOSAVE));
- saveAutosaveBox.getChildren().setAll(localAutoSave, helpAutosave);
- builder.add(saveAutosaveBox, 1, 28);
- }
-
- @Override
- public void setValues() {
- fileDir.setText(prefs.getAsOptional(FieldName.FILE + FilePreferences.DIR_SUFFIX).orElse(""));
- bibLocAsPrimaryDir.setSelected(prefs.getBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR));
- runAutoFileSearch.setSelected(prefs.getBoolean(JabRefPreferences.RUN_AUTOMATIC_FILE_SEARCH));
- allowFileAutoOpenBrowse.setSelected(prefs.getBoolean(JabRefPreferences.ALLOW_FILE_AUTO_OPEN_BROWSE));
- regExpTextField.setText(prefs.get(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY));
- if (prefs.getBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY)) {
- useRegExpComboBox.setSelected(true);
- } else if (prefs.getBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY)) {
- matchExactKeyOnly.setSelected(true);
- } else {
- matchStartsWithKey.setSelected(true);
- }
-
- openLast.setSelected(prefs.getBoolean(JabRefPreferences.OPEN_LAST_EDITED));
- backup.setSelected(prefs.getBoolean(JabRefPreferences.BACKUP));
-
- String newline = prefs.get(JabRefPreferences.NEWLINE);
- if ("\r".equals(newline)) {
- newlineSeparator.setValue("CR");
- } else if ("\n".equals(newline)) {
- newlineSeparator.setValue("LF");
- } else {
- // fallback: windows standard
- newlineSeparator.setValue("CR/LF");
- }
- reformatFileOnSaveAndExport.setSelected(prefs.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT));
-
- resolveStringsAll.setSelected(prefs.getBoolean(JabRefPreferences.RESOLVE_STRINGS_ALL_FIELDS));
- resolveStringsStandard.setSelected(!resolveStringsAll.isSelected());
- doNotResolveStringsFor.setText(prefs.get(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR));
- nonWrappableFields.setText(prefs.get(JabRefPreferences.NON_WRAPPABLE_FIELDS));
-
- localAutoSave.setSelected(prefs.getBoolean(JabRefPreferences.LOCAL_AUTO_SAVE));
- }
-
- @Override
- public Node getBuilder() {
- return builder;
- }
-
- @Override
- public void storeSettings() {
- prefs.put(FieldName.FILE + FilePreferences.DIR_SUFFIX, fileDir.getText());
- prefs.putBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR, bibLocAsPrimaryDir.isSelected());
- prefs.putBoolean(JabRefPreferences.RUN_AUTOMATIC_FILE_SEARCH, runAutoFileSearch.isSelected());
- prefs.putBoolean(JabRefPreferences.ALLOW_FILE_AUTO_OPEN_BROWSE, allowFileAutoOpenBrowse.isSelected());
- prefs.putBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY, useRegExpComboBox.isSelected());
- prefs.putBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY, matchExactKeyOnly.isSelected());
- if (useRegExpComboBox.isSelected()) {
- prefs.put(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY, regExpTextField.getText());
- }
-
- String newline;
- switch (newlineSeparator.getValue()) {
- case "CR":
- newline = "\r";
- break;
- case "LF":
- newline = "\n";
- break;
- default:
- newline = "\r\n";
- break;
- }
- prefs.put(JabRefPreferences.NEWLINE, newline);
- // we also have to change Globals variable as globals is not a getter, but a constant
- OS.NEWLINE = newline;
-
- prefs.putBoolean(JabRefPreferences.BACKUP, backup.isSelected());
-
- prefs.putBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT, reformatFileOnSaveAndExport.isSelected());
- prefs.putBoolean(JabRefPreferences.OPEN_LAST_EDITED, openLast.isSelected());
- prefs.putBoolean(JabRefPreferences.RESOLVE_STRINGS_ALL_FIELDS, resolveStringsAll.isSelected());
- prefs.put(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR, doNotResolveStringsFor.getText().trim());
- doNotResolveStringsFor.setText(prefs.get(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR));
-
- if (!nonWrappableFields.getText().trim().equals(prefs.get(JabRefPreferences.NON_WRAPPABLE_FIELDS))) {
- prefs.put(JabRefPreferences.NON_WRAPPABLE_FIELDS, nonWrappableFields.getText());
- }
-
- prefs.putBoolean(JabRefPreferences.LOCAL_AUTO_SAVE, localAutoSave.isSelected());
- }
-
- @Override
- public boolean validateSettings() {
- Path path = Paths.get(fileDir.getText());
- boolean valid = Files.exists(path) && Files.isDirectory(path);
- if (!valid) {
- dialogService.showErrorDialogAndWait(
- String.format("%s -> %s %n %n %s: %n %s", Localization.lang("File"),
- Localization.lang("Main file directory"), Localization.lang("Directory not found"), path));
- }
- return valid;
- }
-
- @Override
- public String getTabName() {
- return Localization.lang("File");
- }
-
-}
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
new file mode 100644
index 00000000000..c980e561518
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -0,0 +1,127 @@
+package org.jabref.gui.preferences;
+
+import javax.inject.Inject;
+
+import javafx.application.Platform;
+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.RadioButton;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.VBox;
+
+import org.jabref.Globals;
+import org.jabref.gui.DialogService;
+import org.jabref.gui.actions.ActionFactory;
+import org.jabref.gui.actions.StandardActions;
+import org.jabref.gui.help.HelpAction;
+import org.jabref.gui.util.IconValidationDecorator;
+import org.jabref.logic.help.HelpFile;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.preferences.JabRefPreferences;
+import org.jabref.preferences.NewLineSeparator;
+
+import com.airhacks.afterburner.views.ViewLoader;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
+public class FileTabView extends VBox implements PrefsTab {
+
+ @FXML private CheckBox openLastStartup;
+ @FXML private CheckBox backupOldFile;
+ @FXML private TextField noWrapFiles;
+ @FXML private RadioButton resolveStringsBibTex;
+ @FXML private RadioButton resolveStringsAll;
+ @FXML private TextField resolveStringsExcept;
+ @FXML private ComboBox newLineSeparator;
+ @FXML private CheckBox alwaysReformatBib;
+
+ @FXML private TextField mainFileDir;
+ @FXML private CheckBox useBibLocationAsPrimary;
+ @FXML private Button autolinkRegexHelp;
+ @FXML private RadioButton autolinkFileStartsBibtex;
+ @FXML private RadioButton autolinkFileExactBibtex;
+ @FXML private RadioButton autolinkUseRegex;
+ @FXML private TextField autolinkRegexKey;
+ @FXML private CheckBox searchFilesOnOpen;
+ @FXML private CheckBox openBrowseOnCreate;
+
+ @FXML private CheckBox autosaveLocalLibraries;
+ @FXML private Button autosaveLocalLibrariesHelp;
+
+ @Inject private DialogService dialogService;
+ private final JabRefPreferences preferences;
+
+ private FileTabViewModel viewModel;
+
+ private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+
+ public FileTabView(JabRefPreferences preferences) {
+ this.preferences = preferences;
+ ViewLoader.view(this)
+ .root(this)
+ .load();
+ }
+
+ public void initialize() {
+ viewModel = new FileTabViewModel(dialogService, preferences);
+
+ openLastStartup.selectedProperty().bindBidirectional(viewModel.openLastStartupProperty());
+ backupOldFile.selectedProperty().bindBidirectional(viewModel.backupOldFileProperty());
+ noWrapFiles.textProperty().bindBidirectional(viewModel.noWrapFilesProperty());
+ resolveStringsBibTex.selectedProperty().bindBidirectional(viewModel.resolveStringsBibTexProperty());
+ resolveStringsAll.selectedProperty().bindBidirectional(viewModel.resolveStringsAllProperty());
+ resolveStringsExcept.textProperty().bindBidirectional(viewModel.resolvStringsExceptProperty());
+ newLineSeparator.itemsProperty().bind(viewModel.newLineSeparatorListProperty());
+ newLineSeparator.valueProperty().bindBidirectional(viewModel.selectedNewLineSeparatorProperty());
+ alwaysReformatBib.selectedProperty().bindBidirectional(viewModel.alwaysReformatBibProperty());
+
+ mainFileDir.textProperty().bindBidirectional(viewModel.mainFileDirProperty());
+ useBibLocationAsPrimary.selectedProperty().bindBidirectional(viewModel.useBibLocationAsPrimaryProperty());
+ autolinkFileStartsBibtex.selectedProperty().bindBidirectional(viewModel.autolinkFileStartsBibtexProperty());
+ autolinkFileExactBibtex.selectedProperty().bindBidirectional(viewModel.autolinkFileExactBibtexProperty());
+ autolinkUseRegex.selectedProperty().bindBidirectional(viewModel.autolinkUseRegexProperty());
+ autolinkRegexKey.textProperty().bindBidirectional(viewModel.autolinkRegexKeyProperty());
+ searchFilesOnOpen.selectedProperty().bindBidirectional(viewModel.searchFilesOnOpenProperty());
+ openBrowseOnCreate.selectedProperty().bindBidirectional(viewModel.openBrowseOnCreateProperty());
+
+ autosaveLocalLibraries.selectedProperty().bindBidirectional(viewModel.autosaveLocalLibrariesProperty());
+
+ ActionFactory actionFactory = new ActionFactory(Globals.getKeyPrefs());
+ actionFactory.configureIconButton(StandardActions.HELP_REGEX_SEARCH, new HelpAction(HelpFile.REGEX_SEARCH), autolinkRegexHelp);
+ actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.AUTOSAVE), autosaveLocalLibrariesHelp);
+
+ validationVisualizer.setDecoration(new IconValidationDecorator());
+ Platform.runLater(() -> validationVisualizer.initVisualization(viewModel.mainFileDirValidationStatus(), mainFileDir));
+ }
+
+ @Override
+ public Node getBuilder() {
+ return this;
+ }
+
+ @Override
+ public void setValues() {
+ // Done by bindings
+ }
+
+ @Override
+ public void storeSettings() {
+ viewModel.storeSettings();
+ }
+
+ @Override
+ public boolean validateSettings() {
+ return viewModel.validateSettings();
+ }
+
+ @Override
+ public String getTabName() {
+ return Localization.lang("File");
+ }
+
+ public void mainFileDirBrowse() {
+ viewModel.mainFileDirBrowse();
+ }
+}
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
new file mode 100644
index 00000000000..56266c8fb20
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -0,0 +1,192 @@
+package org.jabref.gui.preferences;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+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.collections.FXCollections;
+
+import org.jabref.gui.DialogService;
+import org.jabref.gui.util.DirectoryDialogConfiguration;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.model.entry.FieldName;
+import org.jabref.model.metadata.FilePreferences;
+import org.jabref.preferences.JabRefPreferences;
+import org.jabref.preferences.NewLineSeparator;
+
+import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator;
+import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
+import de.saxsys.mvvmfx.utils.validation.ValidationStatus;
+
+public class FileTabViewModel implements PreferenceTabViewModel {
+
+ private final BooleanProperty openLastStartupProperty = new SimpleBooleanProperty();
+ private final BooleanProperty backupOldFileProperty = new SimpleBooleanProperty();
+ private final StringProperty noWrapFilesProperty = new SimpleStringProperty("");
+ private final BooleanProperty resolveStringsBibTexProperty = new SimpleBooleanProperty();
+ private final BooleanProperty resolveStringsAllProperty = new SimpleBooleanProperty();
+ private final StringProperty resolveStringsExceptProperty = new SimpleStringProperty("");
+ private final ListProperty newLineSeparatorListProperty = new SimpleListProperty<>();
+ private final ObjectProperty selectedNewLineSeparatorProperty = new SimpleObjectProperty<>();
+ private final BooleanProperty alwaysReformatBibProperty = new SimpleBooleanProperty();
+
+ private final StringProperty mainFileDirProperty = new SimpleStringProperty("");
+ private final BooleanProperty useBibLocationAsPrimaryProperty = new SimpleBooleanProperty();
+ private final BooleanProperty autolinkFileStartsBibtexProperty = new SimpleBooleanProperty();
+ private final BooleanProperty autolinkFileExactBibtexProperty = new SimpleBooleanProperty();
+ private final BooleanProperty autolinkUseRegexProperty = new SimpleBooleanProperty();
+ private final StringProperty autolinkRegexKeyProperty = new SimpleStringProperty("");
+ private final BooleanProperty searchFilesOnOpenProperty = new SimpleBooleanProperty();
+ private final BooleanProperty openBrowseOnCreateProperty = new SimpleBooleanProperty();
+
+ private final BooleanProperty autosaveLocalLibraries = new SimpleBooleanProperty();
+
+ private final FunctionBasedValidator mainFileDirValidator;
+
+ private final DialogService dialogService;
+ private final JabRefPreferences preferences;
+
+ public FileTabViewModel(DialogService dialogService, JabRefPreferences preferences) {
+ this.dialogService = dialogService;
+ this.preferences = preferences;
+ setValues();
+
+ mainFileDirValidator = new FunctionBasedValidator(
+ mainFileDirProperty,
+ input -> {
+ Path path = Paths.get(mainFileDirProperty.getValue());
+ return (Files.exists(path) && Files.isDirectory(path));
+ },
+ ValidationMessage.error(String.format("%s > %s > %s %n %n %s",
+ Localization.lang("File"),
+ Localization.lang("External file links"),
+ Localization.lang("Main file directory"),
+ Localization.lang("Directory not found")
+ )
+ )
+ );
+ }
+
+ public void setValues() {
+ openLastStartupProperty.setValue(preferences.getBoolean(JabRefPreferences.OPEN_LAST_EDITED));
+ backupOldFileProperty.setValue(preferences.getBoolean(JabRefPreferences.BACKUP));
+ noWrapFilesProperty.setValue(preferences.get(JabRefPreferences.NON_WRAPPABLE_FIELDS));
+ resolveStringsAllProperty.setValue(preferences.getBoolean(JabRefPreferences.RESOLVE_STRINGS_ALL_FIELDS)); // Flipped around
+ resolveStringsBibTexProperty.setValue(!resolveStringsAllProperty.getValue());
+ resolveStringsExceptProperty.setValue(preferences.get(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR));
+ newLineSeparatorListProperty.setValue(FXCollections.observableArrayList(NewLineSeparator.values()));
+ selectedNewLineSeparatorProperty.setValue(preferences.getNewLineSeparator());
+ alwaysReformatBibProperty.setValue(preferences.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT));
+
+ mainFileDirProperty.setValue(preferences.getAsOptional(FieldName.FILE + FilePreferences.DIR_SUFFIX).orElse(""));
+ useBibLocationAsPrimaryProperty.setValue(preferences.getBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR));
+ if (preferences.getBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY)) { // Flipped around
+ autolinkUseRegexProperty.setValue(true);
+ } else if (preferences.getBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY)) {
+ autolinkFileExactBibtexProperty.setValue(true);
+ } else {
+ autolinkFileStartsBibtexProperty.setValue(true);
+ }
+ autolinkRegexKeyProperty.setValue(preferences.get(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY));
+ searchFilesOnOpenProperty.setValue(preferences.getBoolean(JabRefPreferences.RUN_AUTOMATIC_FILE_SEARCH));
+ openBrowseOnCreateProperty.setValue(preferences.getBoolean(JabRefPreferences.ALLOW_FILE_AUTO_OPEN_BROWSE));
+
+ autosaveLocalLibraries.setValue(preferences.getBoolean(JabRefPreferences.LOCAL_AUTO_SAVE));
+ }
+
+ public void storeSettings() {
+ preferences.putBoolean(JabRefPreferences.OPEN_LAST_EDITED, openLastStartupProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.BACKUP, backupOldFileProperty.getValue());
+ if (!noWrapFilesProperty.getValue().trim().equals(preferences.get(JabRefPreferences.NON_WRAPPABLE_FIELDS))) {
+ preferences.put(JabRefPreferences.NON_WRAPPABLE_FIELDS, noWrapFilesProperty.getValue());
+ }
+ preferences.putBoolean(JabRefPreferences.RESOLVE_STRINGS_ALL_FIELDS, resolveStringsAllProperty.getValue());
+ preferences.put(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR, resolveStringsExceptProperty.getValue().trim());
+ resolveStringsExceptProperty.setValue(preferences.get(JabRefPreferences.DO_NOT_RESOLVE_STRINGS_FOR));
+ if (autolinkUseRegexProperty.getValue()) {
+ preferences.put(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY, autolinkRegexKeyProperty.getValue());
+ }
+ preferences.setNewLineSeparator(selectedNewLineSeparatorProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT, alwaysReformatBibProperty.getValue());
+
+ preferences.put(FieldName.FILE + FilePreferences.DIR_SUFFIX, mainFileDirProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR, useBibLocationAsPrimaryProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY, autolinkUseRegexProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY, autolinkFileExactBibtexProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.RUN_AUTOMATIC_FILE_SEARCH, searchFilesOnOpenProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.ALLOW_FILE_AUTO_OPEN_BROWSE, openBrowseOnCreateProperty.getValue());
+
+ preferences.putBoolean(JabRefPreferences.LOCAL_AUTO_SAVE, autosaveLocalLibraries.getValue());
+ }
+
+ ValidationStatus mainFileDirValidationStatus() {
+ return mainFileDirValidator.getValidationStatus();
+ }
+
+ public boolean validateSettings() {
+ ValidationStatus status = mainFileDirValidationStatus();
+ if (!status.isValid()) {
+ dialogService.showErrorDialogAndWait(status.getHighestMessage().get().getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ public void mainFileDirBrowse() {
+ DirectoryDialogConfiguration dirDialogConfiguration =
+ new DirectoryDialogConfiguration.Builder().withInitialDirectory(Paths.get(mainFileDirProperty.getValue())).build();
+ dialogService.showDirectorySelectionDialog(dirDialogConfiguration)
+ .ifPresent(f -> mainFileDirProperty.setValue(f.toString()));
+ }
+
+ // General
+
+ public BooleanProperty openLastStartupProperty() { return openLastStartupProperty; }
+
+ public BooleanProperty backupOldFileProperty() { return backupOldFileProperty; }
+
+ public StringProperty noWrapFilesProperty() { return noWrapFilesProperty; }
+
+ public BooleanProperty resolveStringsBibTexProperty() { return resolveStringsBibTexProperty; }
+
+ public BooleanProperty resolveStringsAllProperty() { return resolveStringsAllProperty; }
+
+ public StringProperty resolvStringsExceptProperty() { return resolveStringsExceptProperty; }
+
+ public ListProperty newLineSeparatorListProperty() { return newLineSeparatorListProperty; }
+
+ public ObjectProperty selectedNewLineSeparatorProperty() { return selectedNewLineSeparatorProperty; }
+
+ public BooleanProperty alwaysReformatBibProperty() { return alwaysReformatBibProperty; }
+
+ // External file links
+
+ public StringProperty mainFileDirProperty() { return mainFileDirProperty; }
+
+ public BooleanProperty useBibLocationAsPrimaryProperty() { return useBibLocationAsPrimaryProperty; }
+
+ public BooleanProperty autolinkFileStartsBibtexProperty() { return autolinkFileStartsBibtexProperty; }
+
+ public BooleanProperty autolinkFileExactBibtexProperty() { return autolinkFileExactBibtexProperty; }
+
+ public BooleanProperty autolinkUseRegexProperty() { return autolinkUseRegexProperty; }
+
+ public StringProperty autolinkRegexKeyProperty() { return autolinkRegexKeyProperty; }
+
+ public BooleanProperty searchFilesOnOpenProperty() { return searchFilesOnOpenProperty; }
+
+ public BooleanProperty openBrowseOnCreateProperty() { return openBrowseOnCreateProperty; }
+
+ // Autosave
+
+ public BooleanProperty autosaveLocalLibrariesProperty() { return autosaveLocalLibraries; }
+}
+
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
new file mode 100644
index 00000000000..63eb4929140
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.java b/src/main/java/org/jabref/gui/preferences/GeneralTab.java
deleted file mode 100644
index 4c76449acdb..00000000000
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package org.jabref.gui.preferences;
-
-import java.nio.charset.Charset;
-import java.time.format.DateTimeFormatter;
-
-import javafx.collections.FXCollections;
-import javafx.geometry.Pos;
-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.TextField;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-
-import org.jabref.gui.DialogService;
-import org.jabref.gui.actions.ActionFactory;
-import org.jabref.gui.actions.StandardActions;
-import org.jabref.gui.help.HelpAction;
-import org.jabref.gui.util.DefaultTaskExecutor;
-import org.jabref.gui.util.ViewModelListCellFactory;
-import org.jabref.logic.help.HelpFile;
-import org.jabref.logic.l10n.Encodings;
-import org.jabref.logic.l10n.Language;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.model.database.BibDatabaseMode;
-import org.jabref.model.entry.InternalBibtexFields;
-import org.jabref.preferences.JabRefPreferences;
-
-import static javafx.beans.binding.Bindings.not;
-
-class GeneralTab extends Pane implements PrefsTab {
-
- private final CheckBox useOwner;
- private final CheckBox overwriteOwner;
- private final CheckBox enforceLegalKeys;
- private final CheckBox shouldCollectTelemetry;
- private final CheckBox confirmDelete;
- private final CheckBox memoryStick;
- private final CheckBox inspectionWarnDupli;
- private final CheckBox showAdvancedHints;
- private final CheckBox useTimeStamp;
- private final CheckBox updateTimeStamp;
- private final CheckBox overwriteTimeStamp;
- private final TextField defOwnerField;
- private final GridPane builder = new GridPane();
-
- private final TextField timeStampFormat;
- private final TextField timeStampField;
- private final JabRefPreferences prefs;
-
- private final ComboBox languageSelection = new ComboBox<>();
- private final ComboBox encodings;
- private final ComboBox biblatexMode;
- private final DialogService dialogService;
-
- public GeneralTab(DialogService dialogService, JabRefPreferences prefs) {
- this.prefs = prefs;
- this.dialogService = dialogService;
- builder.setVgap(7);
-
- ActionFactory factory = new ActionFactory(prefs.getKeyBindingRepository());
-
- biblatexMode = new ComboBox<>(FXCollections.observableArrayList(BibDatabaseMode.values()));
- memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)"));
- useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':');
- updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification"));
- useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". "
- + Localization.lang("Date format") + ':');
- updateTimeStamp.disableProperty().bind(not(useTimeStamp.selectedProperty()));
- overwriteOwner = new CheckBox(Localization.lang("Overwrite"));
- overwriteTimeStamp = new CheckBox(Localization.lang("If a pasted or imported entry already has the field set, overwrite."));
- enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys"));
- confirmDelete = new CheckBox(Localization.lang("Show confirmation dialog when deleting entries"));
- defOwnerField = new TextField();
- timeStampFormat = new TextField();
- timeStampField = new TextField();
- inspectionWarnDupli = new CheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window"));
- showAdvancedHints = new CheckBox(Localization.lang("Show advanced hints (i.e. helpful tooltips, suggestions and explanation)"));
- shouldCollectTelemetry = new CheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef."));
- encodings = new ComboBox<>(FXCollections.observableArrayList(Encodings.ENCODINGS));
-
- Label general = new Label(Localization.lang("General"));
- general.getStyleClass().add("sectionHeader");
- builder.add(general, 1, 1);
- builder.add(inspectionWarnDupli, 1, 3);
- builder.add(confirmDelete, 1, 5);
- builder.add(enforceLegalKeys, 1, 7);
- builder.add(memoryStick, 1, 9);
-
- // Owner name
- HBox ownerBox = new HBox();
- ownerBox.setAlignment(Pos.CENTER_LEFT);
- ownerBox.setSpacing(7);
- Button helpOwner = factory.createIconButton(StandardActions.HELP, new HelpAction(HelpFile.OWNER));
- ownerBox.getChildren().addAll(useOwner, defOwnerField, overwriteOwner, helpOwner);
- builder.add(ownerBox, 1, 10);
-
- builder.add(useTimeStamp, 1, 14);
- builder.add(timeStampFormat, 1, 16);
- builder.add(overwriteTimeStamp, 1, 17);
- Label fieldName = new Label(Localization.lang("Field name") + ':');
- builder.add(fieldName, 1, 19);
- builder.add(timeStampField, 1, 21);
-
- Button helpTimestamp = factory.createIconButton(StandardActions.HELP, new HelpAction(HelpFile.TIMESTAMP));
- builder.add(helpTimestamp, 1, 22);
- builder.add(updateTimeStamp, 1, 23);
- builder.add(shouldCollectTelemetry, 1, 25);
-
- // Language configuration
- HBox languageBox = new HBox();
- languageBox.setSpacing(115);
- languageBox.setAlignment(Pos.CENTER_LEFT);
- Label languageLabel = new Label(Localization.lang("Language") + ':');
- languageSelection.setItems(FXCollections.observableArrayList(Language.values()));
- new ViewModelListCellFactory()
- .withText(Language::getDisplayName)
- .install(languageSelection);
- languageBox.getChildren().addAll(languageLabel, languageSelection);
- builder.add(languageBox, 1, 27);
-
- // Encoding configuration
- HBox encodingBox = new HBox();
- encodingBox.setSpacing(68);
- encodingBox.setAlignment(Pos.CENTER_LEFT);
- Label defaultEncoding = new Label(Localization.lang("Default encoding") + ':');
- encodingBox.getChildren().addAll(defaultEncoding, encodings);
- builder.add(encodingBox, 1, 28);
-
- // Bibliography mode configuration
- HBox biblioBox = new HBox();
- biblioBox.setSpacing(10);
- biblioBox.setAlignment(Pos.CENTER_LEFT);
- Label defaultBibliographyMode = new Label(Localization.lang("Default bibliography mode"));
- biblioBox.getChildren().addAll(defaultBibliographyMode, biblatexMode);
- builder.add(biblioBox, 1, 29);
-
- builder.add(showAdvancedHints,1,30);
- }
-
- @Override
- public Node getBuilder() {
- return builder;
- }
-
- @Override
- public void setValues() {
- useOwner.setSelected(prefs.getBoolean(JabRefPreferences.USE_OWNER));
- overwriteOwner.setSelected(prefs.getBoolean(JabRefPreferences.OVERWRITE_OWNER));
- useTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP));
- overwriteTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP));
- updateTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP));
- enforceLegalKeys.setSelected(prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
- shouldCollectTelemetry.setSelected(prefs.shouldCollectTelemetry());
- memoryStick.setSelected(prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE));
- confirmDelete.setSelected(prefs.getBoolean(JabRefPreferences.CONFIRM_DELETE));
- defOwnerField.setText(prefs.get(JabRefPreferences.DEFAULT_OWNER));
- timeStampFormat.setText(prefs.get(JabRefPreferences.TIME_STAMP_FORMAT));
- timeStampField.setText(prefs.get(JabRefPreferences.TIME_STAMP_FIELD));
- inspectionWarnDupli.setSelected(prefs.getBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION));
- if (prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE)) {
- biblatexMode.setValue(BibDatabaseMode.BIBLATEX);
- } else {
- biblatexMode.setValue(BibDatabaseMode.BIBTEX);
- }
- encodings.setValue(prefs.getDefaultEncoding());
- languageSelection.setValue(prefs.getLanguage());
- showAdvancedHints.setSelected(prefs.getBoolean(JabRefPreferences.SHOW_ADVANCED_HINTS));
- }
-
- @Override
- public void storeSettings() {
- prefs.putBoolean(JabRefPreferences.USE_OWNER, useOwner.isSelected());
- prefs.putBoolean(JabRefPreferences.OVERWRITE_OWNER, overwriteOwner.isSelected());
- prefs.putBoolean(JabRefPreferences.USE_TIME_STAMP, useTimeStamp.isSelected());
- prefs.putBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP, overwriteTimeStamp.isSelected());
- prefs.putBoolean(JabRefPreferences.UPDATE_TIMESTAMP, updateTimeStamp.isSelected());
- prefs.putBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY, enforceLegalKeys.isSelected());
- prefs.setShouldCollectTelemetry(shouldCollectTelemetry.isSelected());
- if (prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE) && !memoryStick.isSelected()) {
- dialogService.showInformationDialogAndWait(Localization.lang("Memory stick mode"),
- Localization.lang("To disable the memory stick mode"
- + " rename or remove the jabref.xml file in the same folder as JabRef."));
- }
- prefs.putBoolean(JabRefPreferences.MEMORY_STICK_MODE, memoryStick.isSelected());
- prefs.putBoolean(JabRefPreferences.SHOW_ADVANCED_HINTS, showAdvancedHints.isSelected());
- prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, confirmDelete.isSelected());
- prefs.putBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION, inspectionWarnDupli.isSelected());
- String owner = defOwnerField.getText().trim();
- prefs.put(JabRefPreferences.DEFAULT_OWNER, owner);
- prefs.put(JabRefPreferences.TIME_STAMP_FORMAT, timeStampFormat.getText().trim());
- prefs.put(JabRefPreferences.TIME_STAMP_FIELD, timeStampField.getText().trim());
- // Update name of the time stamp field based on preferences
- InternalBibtexFields.updateTimeStampField(prefs.get(JabRefPreferences.TIME_STAMP_FIELD));
- prefs.setDefaultEncoding(encodings.getValue());
- prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getValue() == BibDatabaseMode.BIBLATEX);
-
- if (languageSelection.getValue() != prefs.getLanguage()) {
- prefs.setLanguage(languageSelection.getValue());
- Localization.setLanguage(languageSelection.getValue());
-
- // Warn about restart needed:
- dialogService.showWarningDialogAndWait(Localization.lang("Changed language settings"),
- Localization.lang("You have changed the language setting.")
- .concat(" ")
- .concat(Localization.lang("You must restart JabRef for this to come into effect.")));
- }
- }
-
- @Override
- public boolean validateSettings() {
- try {
- // Test if date format is legal:
- DateTimeFormatter.ofPattern(timeStampFormat.getText());
-
- } catch (IllegalArgumentException ex2) {
- DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Invalid date format"),
- Localization.lang("The chosen date format for new entries is not valid")));
-
- return false;
- }
- return true;
- }
-
- @Override
- public String getTabName() {
- return Localization.lang("General");
- }
-}
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
new file mode 100644
index 00000000000..3138230d7cd
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -0,0 +1,128 @@
+package org.jabref.gui.preferences;
+
+import java.nio.charset.Charset;
+
+import javax.inject.Inject;
+
+import javafx.application.Platform;
+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.TextField;
+import javafx.scene.layout.VBox;
+
+import org.jabref.Globals;
+import org.jabref.gui.DialogService;
+import org.jabref.gui.actions.ActionFactory;
+import org.jabref.gui.actions.StandardActions;
+import org.jabref.gui.help.HelpAction;
+import org.jabref.gui.util.IconValidationDecorator;
+import org.jabref.logic.help.HelpFile;
+import org.jabref.logic.l10n.Language;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.model.database.BibDatabaseMode;
+import org.jabref.preferences.JabRefPreferences;
+
+import com.airhacks.afterburner.views.ViewLoader;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
+
+public class GeneralTabView extends VBox implements PrefsTab {
+
+ @FXML private ComboBox language;
+ @FXML private ComboBox defaultEncoding;
+ @FXML private ComboBox biblatexMode;
+ @FXML private CheckBox inspectionWarningDuplicate;
+ @FXML private CheckBox confirmDelete;
+ @FXML private CheckBox enforceLegalKeys;
+ @FXML private CheckBox memoryStickMode;
+ @FXML private CheckBox collectTelemetry;
+ @FXML private CheckBox showAdvancedHints;
+ @FXML private CheckBox markOwner;
+ @FXML private TextField markOwnerName;
+ @FXML private CheckBox markOwnerOverwrite;
+ @FXML private Button markOwnerHelp;
+ @FXML private CheckBox markTimestamp;
+ @FXML private TextField markTimeStampFormat;
+ @FXML private CheckBox markTimeStampOverwrite;
+ @FXML private TextField markTimeStampFieldName;
+ @FXML private Button markTimeStampHelp;
+ @FXML private CheckBox updateTimeStamp;
+
+ @Inject private DialogService dialogService;
+ private final JabRefPreferences preferences;
+
+ private GeneralTabViewModel viewModel;
+
+ private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+
+ public GeneralTabView(JabRefPreferences preferences) {
+ this.preferences = preferences;
+ ViewLoader.view(this)
+ .root(this)
+ .load();
+ }
+
+ public void initialize() {
+ viewModel = new GeneralTabViewModel(dialogService, preferences);
+
+ language.itemsProperty().bind(viewModel.languagesListProperty());
+ language.valueProperty().bindBidirectional(viewModel.selectedLanguageProperty());
+
+ defaultEncoding.itemsProperty().bind(viewModel.encodingsListProperty());
+ defaultEncoding.valueProperty().bindBidirectional(viewModel.selectedEncodingProperty());
+
+ biblatexMode.itemsProperty().bind(viewModel.biblatexModeListProperty());
+ biblatexMode.valueProperty().bindBidirectional(viewModel.selectedBiblatexModeProperty());
+
+ inspectionWarningDuplicate.selectedProperty().bindBidirectional(viewModel.inspectionWarningDuplicateProperty());
+ confirmDelete.selectedProperty().bindBidirectional(viewModel.confirmDeleteProperty());
+ enforceLegalKeys.selectedProperty().bindBidirectional(viewModel.enforceLegalKeysProperty());
+ memoryStickMode.selectedProperty().bindBidirectional(viewModel.memoryStickModeProperty());
+ collectTelemetry.selectedProperty().bindBidirectional(viewModel.collectTelemetryProperty());
+ showAdvancedHints.selectedProperty().bindBidirectional(viewModel.showAdvancedHintsProperty());
+
+ markOwner.selectedProperty().bindBidirectional(viewModel.markOwnerProperty());
+ markOwnerName.textProperty().bindBidirectional(viewModel.markOwnerNameProperty());
+ markOwnerOverwrite.selectedProperty().bindBidirectional(viewModel.markOwnerOverwriteProperty());
+
+ markTimestamp.selectedProperty().bindBidirectional(viewModel.markTimestampProperty());
+ markTimeStampFormat.textProperty().bindBidirectional(viewModel.markTimeStampFormatProperty());
+ markTimeStampOverwrite.selectedProperty().bindBidirectional(viewModel.markTimeStampOverwriteProperty());
+ markTimeStampFieldName.textProperty().bindBidirectional(viewModel.markTimeStampFieldNameProperty());
+ updateTimeStamp.selectedProperty().bindBidirectional(viewModel.updateTimeStampProperty());
+
+ ActionFactory actionFactory = new ActionFactory(Globals.getKeyPrefs());
+ actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.OWNER), markOwnerHelp);
+ actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.TIMESTAMP), markTimeStampHelp);
+
+ validationVisualizer.setDecoration(new IconValidationDecorator());
+ Platform.runLater(() -> validationVisualizer.initVisualization(viewModel.markTimeStampFormatValidationStatus(), markTimeStampFormat));
+ }
+
+ @Override
+ public Node getBuilder() {
+ return this;
+ }
+
+ @Override
+ public void setValues() {
+ // ToDo: Remove this after conversion of all tabs
+ }
+
+ @Override
+ public void storeSettings() {
+ viewModel.storeSettings();
+ }
+
+ @Override
+ public boolean validateSettings() {
+ return viewModel.validateSettings();
+ }
+
+ @Override
+ public String getTabName() {
+ return Localization.lang("General");
+ }
+}
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
new file mode 100644
index 00000000000..4b801f54ee3
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -0,0 +1,210 @@
+package org.jabref.gui.preferences;
+
+import java.nio.charset.Charset;
+import java.time.format.DateTimeFormatter;
+
+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.collections.FXCollections;
+
+import org.jabref.gui.DialogService;
+import org.jabref.logic.l10n.Encodings;
+import org.jabref.logic.l10n.Language;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.model.database.BibDatabaseMode;
+import org.jabref.model.entry.InternalBibtexFields;
+import org.jabref.preferences.JabRefPreferences;
+
+import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator;
+import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
+import de.saxsys.mvvmfx.utils.validation.ValidationStatus;
+
+public class GeneralTabViewModel implements PreferenceTabViewModel {
+ private final ListProperty languagesListProperty = new SimpleListProperty<>();
+ private final ObjectProperty selectedLanguageProperty = new SimpleObjectProperty<>();
+ private final ListProperty encodingsListProperty = new SimpleListProperty<>();
+ private final ObjectProperty selectedEncodingProperty = new SimpleObjectProperty<>();
+ private final ListProperty bibliographyModeListProperty = new SimpleListProperty<>();
+ private final ObjectProperty selectedBiblatexModeProperty = new SimpleObjectProperty<>();
+
+ private final BooleanProperty inspectionWarningDuplicateProperty = new SimpleBooleanProperty();
+ private final BooleanProperty confirmDeleteProperty = new SimpleBooleanProperty();
+ private final BooleanProperty memoryStickModeProperty = new SimpleBooleanProperty();
+ private final BooleanProperty collectTelemetryProperty = new SimpleBooleanProperty();
+ private final BooleanProperty enforceLegalKeysProperty = new SimpleBooleanProperty();
+ private final BooleanProperty showAdvancedHintsProperty = new SimpleBooleanProperty();
+ private final BooleanProperty markOwnerProperty = new SimpleBooleanProperty();
+ private final StringProperty markOwnerNameProperty = new SimpleStringProperty("");
+ private final BooleanProperty markOwnerOverwriteProperty = new SimpleBooleanProperty();
+ private final BooleanProperty markTimestampProperty = new SimpleBooleanProperty();
+ private final StringProperty markTimeStampFormatProperty = new SimpleStringProperty("");
+ private final BooleanProperty markTimeStampOverwriteProperty = new SimpleBooleanProperty();
+ private final StringProperty markTimeStampFieldNameProperty = new SimpleStringProperty("");
+ private final BooleanProperty updateTimeStampProperty = new SimpleBooleanProperty();
+
+ private FunctionBasedValidator markTimeStampFormatValidator;
+
+ private final DialogService dialogService;
+ private final JabRefPreferences preferences;
+
+ public GeneralTabViewModel(DialogService dialogService, JabRefPreferences preferences) {
+ this.dialogService = dialogService;
+ this.preferences = preferences;
+ setValues();
+
+ markTimeStampFormatValidator = new FunctionBasedValidator(
+ markTimeStampFormatProperty,
+ input -> {
+ try {
+ DateTimeFormatter.ofPattern(markTimeStampFormatProperty.getValue());
+ } catch (IllegalArgumentException exception) {
+ return false;
+ }
+ return true;
+ },
+ ValidationMessage.error(String.format("%s > %s > %s %n %n %s",
+ Localization.lang("General"),
+ Localization.lang("Time stamp"),
+ Localization.lang("Date format"),
+ Localization.lang("Invalid date format")
+ )
+ )
+ );
+ }
+
+ public void setValues() {
+ languagesListProperty.setValue(FXCollections.observableArrayList(Language.values()));
+ selectedLanguageProperty.setValue(preferences.getLanguage());
+
+ encodingsListProperty.setValue(FXCollections.observableArrayList(Encodings.getCharsets()));
+ selectedEncodingProperty.setValue(preferences.getDefaultEncoding());
+
+ bibliographyModeListProperty.setValue(FXCollections.observableArrayList(BibDatabaseMode.values()));
+ if (preferences.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE)) {
+ selectedBiblatexModeProperty.setValue(BibDatabaseMode.BIBLATEX);
+ } else {
+ selectedBiblatexModeProperty.setValue(BibDatabaseMode.BIBLATEX);
+ }
+
+ inspectionWarningDuplicateProperty.setValue(preferences.getBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION));
+ confirmDeleteProperty.setValue(preferences.getBoolean(JabRefPreferences.CONFIRM_DELETE));
+ enforceLegalKeysProperty.setValue(preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
+ memoryStickModeProperty.setValue(preferences.getBoolean(JabRefPreferences.MEMORY_STICK_MODE));
+ collectTelemetryProperty.setValue(preferences.shouldCollectTelemetry());
+ showAdvancedHintsProperty.setValue(preferences.getBoolean(JabRefPreferences.SHOW_ADVANCED_HINTS));
+
+ markOwnerProperty.setValue(preferences.getBoolean(JabRefPreferences.USE_OWNER));
+ markOwnerNameProperty.setValue(preferences.get(JabRefPreferences.DEFAULT_OWNER));
+ markOwnerOverwriteProperty.setValue(preferences.getBoolean(JabRefPreferences.OVERWRITE_OWNER));
+
+ markTimestampProperty.setValue(preferences.getBoolean(JabRefPreferences.USE_TIME_STAMP));
+ markTimeStampFormatProperty.setValue(preferences.get(JabRefPreferences.TIME_STAMP_FORMAT));
+ markTimeStampOverwriteProperty.setValue(preferences.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP));
+ markTimeStampFieldNameProperty.setValue(preferences.get(JabRefPreferences.TIME_STAMP_FIELD));
+ updateTimeStampProperty.setValue(preferences.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP));
+ }
+
+ public void storeSettings() {
+ if (selectedLanguageProperty.getValue() != preferences.getLanguage()) {
+ preferences.setLanguage(selectedLanguageProperty.getValue());
+ Localization.setLanguage(selectedLanguageProperty.getValue());
+
+ dialogService.showWarningDialogAndWait(Localization.lang("Changed language settings"),
+ Localization.lang("You have changed the language setting.")
+ .concat(" ")
+ .concat(Localization.lang("You must restart JabRef for this to come into effect.")));
+ }
+ preferences.setDefaultEncoding(selectedEncodingProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, selectedBiblatexModeProperty.getValue() == BibDatabaseMode.BIBLATEX);
+
+ preferences.putBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION, inspectionWarningDuplicateProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.CONFIRM_DELETE, confirmDeleteProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY, enforceLegalKeysProperty.getValue());
+ if (preferences.getBoolean(JabRefPreferences.MEMORY_STICK_MODE) && !memoryStickModeProperty.getValue()) {
+ dialogService.showInformationDialogAndWait(Localization.lang("Memory stick mode"),
+ Localization.lang("To disable the memory stick mode"
+ + " rename or remove the jabref.xml file in the same folder as JabRef."));
+ }
+ preferences.putBoolean(JabRefPreferences.MEMORY_STICK_MODE, memoryStickModeProperty.getValue());
+ preferences.setShouldCollectTelemetry(collectTelemetryProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.SHOW_ADVANCED_HINTS, showAdvancedHintsProperty.getValue());
+
+ preferences.putBoolean(JabRefPreferences.USE_OWNER, markOwnerProperty.getValue());
+ preferences.put(JabRefPreferences.DEFAULT_OWNER, markOwnerNameProperty.getValue().trim());
+ preferences.putBoolean(JabRefPreferences.OVERWRITE_OWNER, markOwnerOverwriteProperty.getValue());
+
+ preferences.putBoolean(JabRefPreferences.USE_TIME_STAMP, markTimestampProperty.getValue());
+ preferences.put(JabRefPreferences.TIME_STAMP_FORMAT, markTimeStampFormatProperty.getValue().trim());
+ preferences.put(JabRefPreferences.TIME_STAMP_FIELD, markTimeStampFieldNameProperty.getValue().trim());
+ preferences.putBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP, markTimeStampOverwriteProperty.getValue());
+ preferences.putBoolean(JabRefPreferences.UPDATE_TIMESTAMP, updateTimeStampProperty.getValue());
+
+ // Update name of the time stamp field based on preferences
+ InternalBibtexFields.updateTimeStampField(preferences.get(JabRefPreferences.TIME_STAMP_FIELD));
+ }
+
+ public ValidationStatus markTimeStampFormatValidationStatus() {
+ return markTimeStampFormatValidator.getValidationStatus();
+ }
+
+ public boolean validateSettings() {
+ ValidationStatus status = markTimeStampFormatValidationStatus();
+ if (!status.isValid()) {
+ dialogService.showErrorDialogAndWait(status.getHighestMessage().get().getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ // General
+
+ public ListProperty languagesListProperty() { return this.languagesListProperty; }
+
+ public ObjectProperty selectedLanguageProperty() { return this.selectedLanguageProperty; }
+
+ public ListProperty encodingsListProperty() { return this.encodingsListProperty; }
+
+ public ObjectProperty selectedEncodingProperty() { return this.selectedEncodingProperty; }
+
+ public ListProperty biblatexModeListProperty() { return this.bibliographyModeListProperty; }
+
+ public ObjectProperty selectedBiblatexModeProperty() { return this.selectedBiblatexModeProperty; }
+
+ public BooleanProperty inspectionWarningDuplicateProperty() { return this.inspectionWarningDuplicateProperty; }
+
+ public BooleanProperty confirmDeleteProperty() { return this.confirmDeleteProperty; }
+
+ public BooleanProperty memoryStickModeProperty() { return this.memoryStickModeProperty; }
+
+ public BooleanProperty collectTelemetryProperty() { return this.collectTelemetryProperty; }
+
+ public BooleanProperty enforceLegalKeysProperty() { return this.enforceLegalKeysProperty; }
+
+ public BooleanProperty showAdvancedHintsProperty() { return this.showAdvancedHintsProperty; }
+
+ // Entry owner
+
+ public BooleanProperty markOwnerProperty() { return this.markOwnerProperty; }
+
+ public StringProperty markOwnerNameProperty() { return this.markOwnerNameProperty; }
+
+ public BooleanProperty markOwnerOverwriteProperty() { return this.markOwnerOverwriteProperty; }
+
+ // Time stamp
+
+ public BooleanProperty markTimestampProperty() { return this.markTimestampProperty; }
+
+ public StringProperty markTimeStampFormatProperty() { return this.markTimeStampFormatProperty; }
+
+ public BooleanProperty markTimeStampOverwriteProperty() { return this.markTimeStampOverwriteProperty; }
+
+ public StringProperty markTimeStampFieldNameProperty() { return this.markTimeStampFieldNameProperty; }
+
+ public BooleanProperty updateTimeStampProperty() { return this.updateTimeStampProperty; }
+}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
new file mode 100644
index 00000000000..b3396fe2eec
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
@@ -0,0 +1,10 @@
+package org.jabref.gui.preferences;
+
+public interface PreferenceTabViewModel {
+
+ void setValues();
+
+ void storeSettings();
+
+ boolean validateSettings();
+}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
index 8933d9096a3..f1b7bfdd5e1 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
@@ -1,14 +1,24 @@
-#sideMenu {
- -fx-background-color: -fx-control-inner-background;
+#preferenceTabList {
+ -fx-background-color: transparent;
-fx-border-color: -fx-outer-border;
-fx-border-width: 1;
}
-#sideMenu > .virtual-flow > .clipped-container > .sheet > .list-cell {
+#preferenceTabList > .virtual-flow > .clipped-container > .sheet > .list-cell {
-fx-padding: 8 8 8 8;
+ -fx-background: transparent;
+ -fx-text-fill: -fx-text-base-color;
+}
+
+#preferenceTabList > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected {
-fx-background: -fx-control-inner-background;
}
+.split-pane-divider {
+ -fx-padding: 0 4 0 4;
+ -fx-background-color: transparent;
+}
+
.preferencePaneContainer {
-fx-padding: 1em 1em 1em 3em;
}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
index 367768f7cb9..7a90f13ef60 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
@@ -1,5 +1,60 @@
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.java
deleted file mode 100644
index 4814e1b4165..00000000000
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.java
+++ /dev/null
@@ -1,279 +0,0 @@
-package org.jabref.gui.preferences;
-
-import java.util.List;
-import java.util.Locale;
-import java.util.prefs.BackingStoreException;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
-import javafx.geometry.Pos;
-import javafx.scene.control.Button;
-import javafx.scene.control.ButtonBar.ButtonData;
-import javafx.scene.control.ButtonType;
-import javafx.scene.control.ListView;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.control.TextField;
-import javafx.scene.control.Tooltip;
-import javafx.scene.layout.BorderPane;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-
-import org.jabref.Globals;
-import org.jabref.JabRefException;
-import org.jabref.gui.DialogService;
-import org.jabref.gui.GUIGlobals;
-import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.util.BaseDialog;
-import org.jabref.gui.util.ControlHelper;
-import org.jabref.gui.util.FileDialogConfiguration;
-import org.jabref.gui.util.TaskExecutor;
-import org.jabref.gui.util.ViewModelListCellFactory;
-import org.jabref.logic.exporter.ExporterFactory;
-import org.jabref.logic.exporter.SavePreferences;
-import org.jabref.logic.exporter.TemplateExporter;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.logic.layout.LayoutFormatterPreferences;
-import org.jabref.logic.util.StandardFileType;
-import org.jabref.logic.xmp.XmpPreferences;
-import org.jabref.preferences.JabRefPreferences;
-import org.jabref.preferences.JabRefPreferencesFilter;
-
-import com.airhacks.afterburner.views.ViewLoader;
-import org.fxmisc.easybind.EasyBind;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Preferences dialog. Contains a TabbedPane, and tabs will be defined in separate classes. Tabs MUST implement the
- * PrefsTab interface, since this dialog will call the storeSettings() method of all tabs when the user presses ok.
- *
- * With this design, it should be very easy to add new tabs later.
- */
-public class PreferencesDialog extends BaseDialog {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesDialog.class);
-
- private final BorderPane container;
-
- private final DialogService dialogService;
- private final JabRefFrame frame;
- private final JabRefPreferences prefs;
- private final ObservableList preferenceTabs;
-
- public PreferencesDialog(JabRefFrame parent, TaskExecutor taskExecutor) {
- setTitle(Localization.lang("JabRef preferences"));
- getDialogPane().getScene().getStylesheets().add(this.getClass().getResource("PreferencesDialog.css").toExternalForm());
-
- ViewLoader.view(this)
- .load()
- .setAsDialogPane(this);
-
- ButtonType save = new ButtonType(Localization.lang("Save"), ButtonData.OK_DONE);
- getDialogPane().getButtonTypes().addAll(save, ButtonType.CANCEL);
- ControlHelper.setAction(save, getDialogPane(), event -> {
- storeAllSettings();
- close();
- });
-
- prefs = Globals.prefs;
- frame = parent;
- dialogService = frame.getDialogService();
-
- preferenceTabs = FXCollections.observableArrayList();
- preferenceTabs.add(new GeneralTab(dialogService, prefs));
- preferenceTabs.add(new FileTab(dialogService, prefs));
- preferenceTabs.add(new TablePrefsTab(prefs));
- preferenceTabs.add(new TableColumnsTab(prefs, frame));
- preferenceTabs.add(new PreviewPreferencesTab(dialogService, taskExecutor));
- preferenceTabs.add(new ExternalTab(frame, this, prefs));
- preferenceTabs.add(new GroupsPrefsTab(prefs));
- preferenceTabs.add(new EntryEditorPrefsTab(prefs));
- preferenceTabs.add(new BibtexKeyPatternPrefTab(prefs, frame.getCurrentBasePanel()));
- preferenceTabs.add(new ImportSettingsTab(prefs));
- preferenceTabs.add(new ExportSortingPrefsTab(prefs));
- preferenceTabs.add(new NameFormatterTab(prefs));
- preferenceTabs.add(new XmpPrefsTab(prefs));
- preferenceTabs.add(new NetworkTab(dialogService, prefs));
- preferenceTabs.add(new AdvancedTab(dialogService, prefs));
- preferenceTabs.add(new AppearancePrefsTab(dialogService, prefs));
-
- container = new BorderPane();
- getDialogPane().setContent(container);
-
- construct();
- }
-
- @FXML
- private void initalize() {
- //FIXME: Model whole dialog as fxml
- }
-
- private void construct() {
- VBox vBox = new VBox();
- vBox.setPrefWidth(160);
-
- ListView tabsList = new ListView<>();
- tabsList.setId("sideMenu");
- tabsList.itemsProperty().setValue(preferenceTabs);
- EasyBind.subscribe(tabsList.getSelectionModel().selectedItemProperty(), tab -> {
- if (tab != null) {
- ScrollPane preferencePaneContainer = new ScrollPane(tab.getBuilder());
- preferencePaneContainer.getStyleClass().add("preferencePaneContainer");
- container.setCenter(preferencePaneContainer);
- } else {
- container.setCenter(null);
- }
- });
- tabsList.getSelectionModel().selectFirst();
- new ViewModelListCellFactory()
- .withText(PrefsTab::getTabName)
- .install(tabsList);
-
- TextField searchBox = new TextField();
- searchBox.setPromptText(Localization.lang("Search"));
-
- PreferencesSearchHandler searchHandler = new PreferencesSearchHandler(preferenceTabs);
- tabsList.itemsProperty().bindBidirectional(searchHandler.filteredPreferenceTabsProperty());
- searchBox.textProperty().addListener((observable, previousText, newText) -> {
- searchHandler.filterTabs(newText.toLowerCase(Locale.ROOT));
- tabsList.getSelectionModel().clearSelection();
- tabsList.getSelectionModel().selectFirst();
- });
-
- VBox buttonContainer = new VBox();
- buttonContainer.setAlignment(Pos.BOTTOM_LEFT);
- buttonContainer.setSpacing(3.0);
- Button importPreferences = new Button(Localization.lang("Import preferences"));
- importPreferences.setTooltip(new Tooltip(Localization.lang("Import preferences from file")));
- importPreferences.setOnAction(e -> importPreferences());
- importPreferences.setMaxWidth(Double.MAX_VALUE);
- Button exportPreferences = new Button(Localization.lang("Export preferences"));
- exportPreferences.setTooltip(new Tooltip(Localization.lang("Export preferences to file")));
- exportPreferences.setOnAction(e -> exportPreferences());
- exportPreferences.setMaxWidth(Double.MAX_VALUE);
- Button showPreferences = new Button(Localization.lang("Show preferences"));
- showPreferences.setOnAction(e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).showAndWait());
- showPreferences.setMaxWidth(Double.MAX_VALUE);
- Button resetPreferences = new Button(Localization.lang("Reset preferences"));
- resetPreferences.setOnAction(e -> resetPreferences());
- resetPreferences.setMaxWidth(Double.MAX_VALUE);
- buttonContainer.getChildren().addAll(
- importPreferences,
- exportPreferences,
- showPreferences,
- resetPreferences);
-
- VBox spacer = new VBox();
- spacer.setPrefHeight(10.0);
- VBox.setVgrow(tabsList, Priority.ALWAYS);
- VBox.setVgrow(spacer, Priority.SOMETIMES);
- vBox.getChildren().addAll(
- searchBox,
- tabsList,
- spacer,
- buttonContainer
- );
-
- container.setLeft(vBox);
-
- setValues();
-
- }
-
- private void resetPreferences() {
- boolean resetPreferencesConfirmed = dialogService.showConfirmationDialogAndWait(
- Localization.lang("Reset preferences"),
- Localization.lang("Are you sure you want to reset all settings to default values?"),
- Localization.lang("Reset preferences"),
- Localization.lang("Cancel"));
- if (resetPreferencesConfirmed) {
- try {
- prefs.clear();
-
- dialogService.showWarningDialogAndWait(Localization.lang("Reset preferences"),
- Localization.lang("You must restart JabRef for this to come into effect."));
- } catch (BackingStoreException ex) {
- LOGGER.error("Error while resetting preferences", ex);
- dialogService.showErrorDialogAndWait(Localization.lang("Reset preferences"), ex);
- }
- updateAfterPreferenceChanges();
- }
- }
-
- private void importPreferences() {
- FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
- .addExtensionFilter(StandardFileType.XML)
- .withDefaultExtension(StandardFileType.XML)
- .withInitialDirectory(prefs.setLastPreferencesExportPath()).build();
-
- dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> {
- try {
- prefs.importPreferences(file);
- updateAfterPreferenceChanges();
-
- dialogService.showWarningDialogAndWait(Localization.lang("Import preferences"),
- Localization.lang("You must restart JabRef for this to come into effect."));
- } catch (JabRefException ex) {
- LOGGER.error("Error while importing preferences", ex);
- dialogService.showErrorDialogAndWait(Localization.lang("Import preferences"), ex);
- }
- });
- }
-
- private void updateAfterPreferenceChanges() {
- setValues();
- List customExporters = prefs.getCustomExportFormats(Globals.journalAbbreviationLoader);
- LayoutFormatterPreferences layoutPreferences = prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader);
- SavePreferences savePreferences = prefs.loadForExportFromPreferences();
- XmpPreferences xmpPreferences = prefs.getXMPPreferences();
- Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, xmpPreferences);
- prefs.updateEntryEditorTabList();
- }
-
- private void storeAllSettings() {
- // First check that all tabs are ready to close:
- for (PrefsTab tab : preferenceTabs) {
- if (!tab.validateSettings()) {
- return; // If not, break off.
- }
- }
- // Then store settings and close:
- for (PrefsTab tab : preferenceTabs) {
- tab.storeSettings();
- }
- prefs.flush();
-
- GUIGlobals.updateEntryEditorColors();
- frame.setupAllTables();
- frame.getGlobalSearchBar().updateHintVisibility();
- dialogService.notify(Localization.lang("Preferences recorded."));
- }
-
- public void setValues() {
- // Update all field values in the tabs:
- for (PrefsTab prefsTab : preferenceTabs) {
- prefsTab.setValues();
- }
- }
-
- private void exportPreferences() {
- FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
- .addExtensionFilter(StandardFileType.XML)
- .withDefaultExtension(StandardFileType.XML)
- .withInitialDirectory(prefs.setLastPreferencesExportPath())
- .build();
-
- dialogService.showFileSaveDialog(fileDialogConfiguration)
- .ifPresent(exportFile -> {
- try {
- storeAllSettings();
- prefs.exportPreferences(exportFile);
- prefs.setLastPreferencesExportPath(exportFile);
- } catch (JabRefException ex) {
- LOGGER.warn(ex.getMessage(), ex);
- dialogService.showErrorDialogAndWait(Localization.lang("Export preferences"), ex);
- }
- });
- }
-}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
new file mode 100644
index 00000000000..7fb30a48067
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -0,0 +1,126 @@
+package org.jabref.gui.preferences;
+
+import java.util.Locale;
+
+import javax.inject.Inject;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.ListView;
+import javafx.scene.control.ScrollPane;
+
+import org.jabref.gui.DialogService;
+import org.jabref.gui.JabRefFrame;
+import org.jabref.gui.icon.IconTheme;
+import org.jabref.gui.util.BaseDialog;
+import org.jabref.gui.util.ControlHelper;
+import org.jabref.gui.util.TaskExecutor;
+import org.jabref.gui.util.ViewModelListCellFactory;
+import org.jabref.logic.l10n.Localization;
+
+import com.airhacks.afterburner.views.ViewLoader;
+import org.controlsfx.control.textfield.CustomTextField;
+import org.fxmisc.easybind.EasyBind;
+
+/**
+ * Preferences dialog. Contains a TabbedPane, and tabs will be defined in separate classes. Tabs MUST implement the
+ * PrefsTab interface, since this dialog will call the storeSettings() method of all tabs when the user presses ok.
+ */
+public class PreferencesDialogView extends BaseDialog {
+
+ @FXML private CustomTextField searchBox;
+ @FXML private ListView preferenceTabList;
+ @FXML private ScrollPane preferencePaneContainer;
+ @FXML private ButtonType saveButton;
+
+ @Inject private DialogService dialogService;
+
+ private JabRefFrame frame;
+ private TaskExecutor taskExecutor;
+ private PreferencesDialogViewModel viewModel;
+
+ public PreferencesDialogView(JabRefFrame frame, TaskExecutor taskExecutor) {
+ this.frame = frame;
+ this.taskExecutor = taskExecutor;
+ this.setTitle(Localization.lang("JabRef preferences"));
+
+ ViewLoader.view(this)
+ .load()
+ .setAsDialogPane(this);
+
+ ControlHelper.setAction(saveButton, getDialogPane(), event -> savePreferencesAndCloseDialog());
+
+ // ToDo: After conversion of all tabs to mvvm, rework interface and make validSettings bindable
+ // Button btnSave = (Button) this.getDialogPane().lookupButton(saveButton);
+ // btnSave.disableProperty().bind(viewModel.validSettings().validProperty().not());
+ }
+
+ public PreferencesDialogViewModel getViewModel() {
+ return viewModel;
+ }
+
+ @FXML
+ private void initialize() {
+ viewModel = new PreferencesDialogViewModel(dialogService, taskExecutor, frame);
+
+ preferenceTabList.itemsProperty().setValue(viewModel.getPreferenceTabs());
+
+ PreferencesSearchHandler searchHandler = new PreferencesSearchHandler(viewModel.getPreferenceTabs());
+ preferenceTabList.itemsProperty().bindBidirectional(searchHandler.filteredPreferenceTabsProperty());
+ searchBox.textProperty().addListener((observable, previousText, newText) -> {
+ searchHandler.filterTabs(newText.toLowerCase(Locale.ROOT));
+ preferenceTabList.getSelectionModel().clearSelection();
+ preferenceTabList.getSelectionModel().selectFirst();
+ });
+ searchBox.setPromptText(Localization.lang("Search") + "...");
+ searchBox.setLeft(IconTheme.JabRefIcons.SEARCH.getGraphicNode());
+
+ EasyBind.subscribe(preferenceTabList.getSelectionModel().selectedItemProperty(), tab -> {
+ if (tab != null) {
+ preferencePaneContainer.setContent(tab.getBuilder());
+ } else {
+ preferencePaneContainer.setContent(null);
+ }
+ });
+
+ preferenceTabList.getSelectionModel().selectFirst();
+ new ViewModelListCellFactory()
+ .withText(PrefsTab::getTabName)
+ .install(preferenceTabList);
+
+ viewModel.setValues(); // ToDo: Remove this after conversion of all tabs
+ }
+
+ @FXML
+ private void closeDialog() {
+ close();
+ }
+
+ @FXML
+ private void savePreferencesAndCloseDialog() {
+ if (viewModel.validSettings()) {
+ viewModel.storeAllSettings();
+ closeDialog();
+ }
+ }
+
+ @FXML
+ void exportPreferences() {
+ viewModel.exportPreferences();
+ }
+
+ @FXML
+ void importPreferences() {
+ viewModel.importPreferences();
+ }
+
+ @FXML
+ void showAllPreferences() {
+ viewModel.showPreferences();
+ }
+
+ @FXML
+ void resetPreferences() {
+ viewModel.resetPreferences();
+ }
+}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
new file mode 100644
index 00000000000..2e62aed97be
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -0,0 +1,191 @@
+package org.jabref.gui.preferences;
+
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+
+import javafx.beans.property.ReadOnlyListWrapper;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import org.jabref.Globals;
+import org.jabref.JabRefException;
+import org.jabref.gui.AbstractViewModel;
+import org.jabref.gui.DialogService;
+import org.jabref.gui.GUIGlobals;
+import org.jabref.gui.JabRefFrame;
+import org.jabref.gui.util.FileDialogConfiguration;
+import org.jabref.gui.util.TaskExecutor;
+import org.jabref.logic.exporter.ExporterFactory;
+import org.jabref.logic.exporter.SavePreferences;
+import org.jabref.logic.exporter.TemplateExporter;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.logic.layout.LayoutFormatterPreferences;
+import org.jabref.logic.util.StandardFileType;
+import org.jabref.logic.xmp.XmpPreferences;
+import org.jabref.preferences.JabRefPreferences;
+import org.jabref.preferences.JabRefPreferencesFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PreferencesDialogViewModel extends AbstractViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesDialogViewModel.class);
+
+ private final DialogService dialogService;
+ private final TaskExecutor taskExecutor;
+ private final JabRefPreferences prefs;
+ private final ObservableList preferenceTabs;
+ private final JabRefFrame frame;
+
+ public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor taskExecutor, JabRefFrame frame) {
+ this.dialogService = dialogService;
+ this.taskExecutor = taskExecutor;
+ this.prefs = Globals.prefs;
+ this.frame = frame;
+
+ preferenceTabs = FXCollections.observableArrayList();
+ preferenceTabs.add(new GeneralTabView(prefs));
+ preferenceTabs.add(new FileTabView(prefs));
+ preferenceTabs.add(new TablePrefsTab(prefs));
+ preferenceTabs.add(new TableColumnsTab(prefs, frame));
+ preferenceTabs.add(new PreviewPreferencesTab(dialogService, this.taskExecutor));
+ preferenceTabs.add(new ExternalTab(frame, prefs));
+ preferenceTabs.add(new GroupsPrefsTab(prefs));
+ preferenceTabs.add(new EntryEditorPrefsTab(prefs));
+ preferenceTabs.add(new BibtexKeyPatternPrefTab(prefs, frame.getCurrentBasePanel()));
+ preferenceTabs.add(new ImportSettingsTab(prefs));
+ preferenceTabs.add(new ExportSortingPrefsTab(prefs));
+ preferenceTabs.add(new NameFormatterTab(prefs));
+ preferenceTabs.add(new XmpPrefsTab(prefs));
+ preferenceTabs.add(new NetworkTab(dialogService, prefs));
+ preferenceTabs.add(new AdvancedTab(dialogService, prefs));
+ preferenceTabs.add(new AppearancePrefsTab(dialogService, prefs));
+ }
+
+ public ObservableList getPreferenceTabs() {
+ return new ReadOnlyListWrapper<>(preferenceTabs);
+ }
+
+ public void importPreferences() {
+ FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
+ .addExtensionFilter(StandardFileType.XML)
+ .withDefaultExtension(StandardFileType.XML)
+ .withInitialDirectory(prefs.setLastPreferencesExportPath()).build();
+
+ dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> {
+ try {
+ prefs.importPreferences(file);
+ updateAfterPreferenceChanges();
+
+ dialogService.showWarningDialogAndWait(Localization.lang("Import preferences"),
+ Localization.lang("You must restart JabRef for this to come into effect."));
+ } catch (JabRefException ex) {
+ LOGGER.error("Error while importing preferences", ex);
+ dialogService.showErrorDialogAndWait(Localization.lang("Import preferences"), ex);
+ }
+ });
+ }
+
+ public void exportPreferences() {
+ FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
+ .addExtensionFilter(StandardFileType.XML)
+ .withDefaultExtension(StandardFileType.XML)
+ .withInitialDirectory(prefs.setLastPreferencesExportPath())
+ .build();
+
+ dialogService.showFileSaveDialog(fileDialogConfiguration)
+ .ifPresent(exportFile -> {
+ try {
+ storeAllSettings();
+ prefs.exportPreferences(exportFile);
+ prefs.setLastPreferencesExportPath(exportFile);
+ } catch (JabRefException ex) {
+ LOGGER.warn(ex.getMessage(), ex);
+ dialogService.showErrorDialogAndWait(Localization.lang("Export preferences"), ex);
+ }
+ });
+ }
+
+ public void showPreferences() {
+ new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).showAndWait();
+ }
+
+ public void resetPreferences() {
+ boolean resetPreferencesConfirmed = dialogService.showConfirmationDialogAndWait(
+ Localization.lang("Reset preferences"),
+ Localization.lang("Are you sure you want to reset all settings to default values?"),
+ Localization.lang("Reset preferences"),
+ Localization.lang("Cancel"));
+ if (resetPreferencesConfirmed) {
+ try {
+ prefs.clear();
+
+ dialogService.showWarningDialogAndWait(Localization.lang("Reset preferences"),
+ Localization.lang("You must restart JabRef for this to come into effect."));
+ } catch (BackingStoreException ex) {
+ LOGGER.error("Error while resetting preferences", ex);
+ dialogService.showErrorDialogAndWait(Localization.lang("Reset preferences"), ex);
+ }
+
+ updateAfterPreferenceChanges();
+ }
+ }
+
+ /**
+ * Reloads the JabRefPreferences into the UI
+ */
+ private void updateAfterPreferenceChanges() {
+ setValues();
+
+ List customExporters = prefs.getCustomExportFormats(Globals.journalAbbreviationLoader);
+ LayoutFormatterPreferences layoutPreferences = prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader);
+ SavePreferences savePreferences = prefs.loadForExportFromPreferences();
+ XmpPreferences xmpPreferences = prefs.getXMPPreferences();
+ Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, xmpPreferences);
+ prefs.updateEntryEditorTabList();
+ }
+
+ /**
+ * Checks if all tabs are valid
+ * ToDo: After conversion of all tabs use mvvmfx-validator
+ * ToDo: should be observable for binding of OK-button in View
+ */
+
+ public boolean validSettings() {
+ for (PrefsTab tab : preferenceTabs) {
+ if (!tab.validateSettings()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void storeAllSettings() {
+ // Run validation checks
+ if (!validSettings()) {
+ return;
+ }
+
+ // Store settings
+ for (PrefsTab tab : preferenceTabs) {
+ tab.storeSettings(); // ToDo: After conversion of all tabs: prefsTab.getViewModel().storeSettings();
+ }
+ prefs.flush();
+
+ GUIGlobals.updateEntryEditorColors();
+ frame.setupAllTables();
+ frame.getGlobalSearchBar().updateHintVisibility();
+ dialogService.notify(Localization.lang("Preferences recorded."));
+ }
+
+ /**
+ * Inserts the JabRefPreferences-values into the the Properties of the ViewModel
+ * ToDo: Reword after conversion of all tabs: resetValues()
+ */
+ public void setValues() {
+ for (PrefsTab prefsTab : preferenceTabs) {
+ prefsTab.setValues(); // ToDo: After conversion of all tabs: prefsTab.getViewModel().setValues();
+ }
+ }
+}
diff --git a/src/main/java/org/jabref/gui/preferences/PrefsTab.java b/src/main/java/org/jabref/gui/preferences/PrefsTab.java
index 47bf3fd77cf..d5e794754ea 100644
--- a/src/main/java/org/jabref/gui/preferences/PrefsTab.java
+++ b/src/main/java/org/jabref/gui/preferences/PrefsTab.java
@@ -19,14 +19,14 @@ interface PrefsTab {
* is ILLEGAL to set values only at construction time, because the dialog
* will be reused and updated.
*/
- void setValues();
+ void setValues(); // ToDo: Remove this after conversion of all tabs, done in ViewModel
/**
* This method is called when the user presses OK in the
* Preferences dialog. Implementing classes must make sure all
* settings presented get stored in JabRefPreferences.
*/
- void storeSettings();
+ void storeSettings(); // ToDo: After conversion of all tabs: viewModel.storeSettings()
/**
* This method is called before the {@link #storeSettings()} method,
@@ -35,7 +35,7 @@ interface PrefsTab {
* If the tab is *not* ready, it should display a message to the user
* informing about the illegal setting.
*/
- boolean validateSettings();
+ boolean validateSettings(); // ToDo: After conversion of all tabs: viewModel.validateSettings()
/**
* Should return the localized identifier to use for the tab.
diff --git a/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java b/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java
index b47321f0095..684e830d445 100644
--- a/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java
+++ b/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java
@@ -16,7 +16,6 @@ public ShowPreferencesAction(JabRefFrame jabRefFrame, TaskExecutor taskExecutor)
@Override
public void execute() {
- PreferencesDialog preferencesDialog = new PreferencesDialog(jabRefFrame, taskExecutor);
- preferencesDialog.showAndWait();
+ new PreferencesDialogView(jabRefFrame, taskExecutor).show();
}
}
diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java
index 253b64cb8e4..e002caa979b 100644
--- a/src/main/java/org/jabref/preferences/JabRefPreferences.java
+++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java
@@ -2118,4 +2118,16 @@ public void setActivePushToApplication(PushToApplication application, PushToAppl
manager.updateApplicationAction();
}
}
+
+ public NewLineSeparator getNewLineSeparator() {
+ return NewLineSeparator.parse(get(JabRefPreferences.NEWLINE));
+ }
+
+ public void setNewLineSeparator(NewLineSeparator newLineSeparator) {
+ String escapeChars = newLineSeparator.getEscapeChars();
+ put(JabRefPreferences.NEWLINE, escapeChars);
+
+ // we also have to change Globals variable as globals is not a getter, but a constant
+ OS.NEWLINE = escapeChars;
+ }
}
diff --git a/src/main/java/org/jabref/preferences/NewLineSeparator.java b/src/main/java/org/jabref/preferences/NewLineSeparator.java
new file mode 100644
index 00000000000..975bdcd88fc
--- /dev/null
+++ b/src/main/java/org/jabref/preferences/NewLineSeparator.java
@@ -0,0 +1,52 @@
+package org.jabref.preferences;
+
+public enum NewLineSeparator {
+ CR,
+ LF,
+ CRLF;
+
+ /**
+ * An enum which contains the possible NewLineSeperators
+ * Possible are CR ("\n"), LF ("\r") and the windows standard CR/LF.
+ */
+
+ public String toString() {
+ switch (this) {
+ case CR:
+ return "CR (\"\\r\")";
+ case LF:
+ return "LF (\"\\n\")";
+ default:
+ return "CR/LF (\"\\r\\n\")";
+ }
+ }
+
+ /**
+ * @return the name of the current mode as String
+ */
+ public String getEscapeChars() {
+ switch (this) {
+ case CR:
+ return "\r";
+ case LF:
+ return "\n";
+ default:
+ return "\r\n";
+ }
+ }
+
+ /**
+ * Returns the {@link NewLineSeparator} that equals the given string.
+ **/
+ public static NewLineSeparator parse(String data) {
+ switch (data) {
+ case "\r":
+ return CR;
+ case "\n":
+ return LF;
+ default:
+ return CRLF;
+ }
+ }
+}
+
diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties
index eb1ffbb0894..8243244f3f1 100644
--- a/src/main/resources/l10n/JabRef_en.properties
+++ b/src/main/resources/l10n/JabRef_en.properties
@@ -313,6 +313,8 @@ entry=entry
Entry\ editor=Entry editor
+Entry\ owner=Entry owner
+
Entry\ preview=Entry preview
Entry\ table=Entry table
@@ -892,7 +894,6 @@ Tabname=Tabname
Tertiary\ sort\ criterion=Tertiary sort criterion
Test=Test
-The\ chosen\ date\ format\ for\ new\ entries\ is\ not\ valid=The chosen date format for new entries is not valid
The\ chosen\ encoding\ '%0'\ could\ not\ encode\ the\ following\ characters\:=The chosen encoding '%0' could not encode the following characters:
@@ -931,7 +932,7 @@ This\ operation\ requires\ one\ or\ more\ entries\ to\ be\ selected.=This operat
This\ setting\ may\ be\ changed\ in\ preferences\ at\ any\ time.=This setting may be changed in preferences at any time.
Timezone\ (Provides\ for\ better\ recommendations\ by\ indicating\ the\ time\ of\ day\ the\ request\ is\ being\ made.)=Timezone (Provides for better recommendations by indicating the time of day the request is being made.)
-
+Time\ stamp=Time stamp
Toggle\ entry\ preview=Toggle entry preview
Toggle\ groups\ interface=Toggle groups interface