From 427f74ae240effa610ea6569a63be6dad734f46d Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Wed, 5 Jun 2019 22:15:27 +0200
Subject: [PATCH 01/22] Refactor PreferenceDialog to MVVM with a split-pane

---
 .../jabref/gui/preferences/ExternalTab.java   |   2 +-
 .../gui/preferences/PreferencesDialog.css     |   4 +-
 .../gui/preferences/PreferencesDialog.fxml    |  51 +++-
 .../gui/preferences/PreferencesDialog.java    | 279 ------------------
 .../preferences/PreferencesDialogView.java    | 132 +++++++++
 .../PreferencesDialogViewModel.java           | 168 +++++++++++
 .../preferences/ShowPreferencesAction.java    |   3 +-
 7 files changed, 353 insertions(+), 286 deletions(-)
 delete mode 100644 src/main/java/org/jabref/gui/preferences/PreferencesDialog.java
 create mode 100644 src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
 create mode 100644 src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java

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/PreferencesDialog.css b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
index 8933d9096a3..b6b9da0f317 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
@@ -1,10 +1,10 @@
-#sideMenu {
+#preferenceTabList {
     -fx-background-color: -fx-control-inner-background;
     -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: -fx-control-inner-background;
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
index 367768f7cb9..139fd9adc20 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
@@ -1,5 +1,52 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonType?>
 <?import javafx.scene.control.DialogPane?>
-<DialogPane prefHeight="700.0" prefWidth="1100.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.PreferencesDialog" />
+<?import javafx.scene.control.ListView?>
+<?import javafx.scene.control.ScrollPane?>
+<?import javafx.scene.control.SplitPane?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.control.Tooltip?>
+<?import javafx.scene.layout.VBox?>
+
+<DialogPane prefHeight="700.0" prefWidth="1100.0" minHeight="400" minWidth="600" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.PreferencesDialogView">
+    <content>
+        <SplitPane dividerPositions="0.3">
+            <items>
+                <VBox prefWidth="160.0" styleClass="split-pane">
+                    <children>
+                        <TextField fx:id="searchBox" promptText="%Search" VBox.vgrow="NEVER">
+                            <VBox.margin>
+                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
+                            </VBox.margin>
+                        </TextField>
+                        <ListView fx:id="preferenceTabList" VBox.vgrow="ALWAYS" />
+                        <VBox prefHeight="10.0" VBox.vgrow="SOMETIMES" />
+                        <VBox alignment="BOTTOM_LEFT" spacing="3.0">
+                            <children>
+                                <Button maxWidth="Infinity" onAction="#importPreferences" text="%Import preferences">
+                                    <tooltip><Tooltip text="%Import preferences from file" /></tooltip>
+                                </Button>
+                                <Button maxWidth="Infinity" onAction="#exportPreferences" text="%Export preferences">
+                                    <tooltip><Tooltip text="%Export preferences to file" /></tooltip>
+                                </Button>
+                                <Button maxWidth="Infinity" onAction="#showAllPreferences" text="%Show preferences" />
+                                <Button maxWidth="Infinity" onAction="#resetPreferences" text="%Reset preferences" />
+                            </children>
+                            <padding>
+                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
+                            </padding>
+                        </VBox>
+                    </children>
+                </VBox>
+                <ScrollPane fx:id="preferencePaneContainer" />
+            </items>
+        </SplitPane>
+    </content>
+    <buttonTypes>
+        <ButtonType fx:id="saveButton" text="%Save" buttonData="OK_DONE" />
+        <ButtonType fx:constant="CANCEL" />
+    </buttonTypes>
+</DialogPane>
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<Void> {
-
-    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<PrefsTab> 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<PrefsTab> 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<PrefsTab>()
-                                                .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<TemplateExporter> 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..1c2f6c6da41
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -0,0 +1,132 @@
+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 javafx.scene.control.TextField;
+
+import org.jabref.gui.DialogService;
+import org.jabref.gui.JabRefFrame;
+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 org.jabref.preferences.PreferencesService;
+
+import com.airhacks.afterburner.views.ViewLoader;
+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<PreferencesDialogViewModel> {
+
+    @FXML private TextField searchBox;
+    @FXML private ListView<PrefsTab> preferenceTabList;
+    @FXML private ScrollPane preferencePaneContainer;
+    @FXML private ButtonType saveButton;
+
+    @Inject private DialogService dialogService;
+    @Inject private PreferencesService preferences;
+
+    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());
+    }
+
+    public PreferencesDialogViewModel getViewModel() { return viewModel; }
+
+    @FXML
+    private void initialize () {
+        viewModel = new PreferencesDialogViewModel(dialogService, taskExecutor, frame, this);
+        getDialogPane().getScene().getStylesheets().add(this.getClass().getResource("PreferencesDialog.css").toExternalForm());
+        preferencePaneContainer.getStyleClass().add("preferencePaneContainer");
+
+        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();
+        });
+
+        EasyBind.subscribe(preferenceTabList.getSelectionModel().selectedItemProperty(), tab -> {
+            if (tab != null) {
+                preferencePaneContainer.setContent(tab.getBuilder());
+            } else {
+                preferencePaneContainer.setContent(null);
+            }
+        });
+
+        preferenceTabList.getSelectionModel().selectFirst();
+        new ViewModelListCellFactory<PrefsTab>()
+                .withText(PrefsTab::getTabName)
+                .install(preferenceTabList);
+
+        setValues();
+    }
+
+    @FXML
+    private void closeDialog() { close(); }
+
+    @FXML
+    private void savePreferencesAndCloseDialog() {
+        viewModel.storeAllSettings();
+        closeDialog();
+    }
+
+    @FXML
+    void exportPreferences() {
+        viewModel.exportPreferences();
+    }
+
+    @FXML
+    void importPreferences() {
+        viewModel.importPreferences();
+    }
+
+    @FXML
+    void showAllPreferences() {
+        viewModel.showPreferences();
+    }
+
+    @FXML
+    void resetPreferences() {
+        viewModel.resetPreferences();
+    }
+
+    /**
+     * Sets the values in each preference tab according to Globals.prefs.
+     * Currently the PreferenceDialogViewModel uses this method, which,
+     * I believe, is not allowed in the MVVM-model. Fixing this would
+     * probably require refactoring the JabRefPreferences to use
+     * Properties probably (?), which would go way beyond this PR.
+     * So this is just deprecated and awaits refactoring.
+     */
+    @Deprecated
+    public void setValues() {
+        for (PrefsTab prefsTab : viewModel.getPreferenceTabs()) {
+            prefsTab.setValues();
+        }
+    }
+}
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..9642f155ad5
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -0,0 +1,168 @@
+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.importer.ImportCustomizationDialogViewModel;
+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(ImportCustomizationDialogViewModel.class);
+
+    private final DialogService dialogService;
+    private final TaskExecutor taskExecutor;
+    private final JabRefPreferences prefs;
+    private final ObservableList<PrefsTab> preferenceTabs;
+    private final PreferencesDialogView view;
+    private final JabRefFrame frame;
+
+    public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor taskExecutor, JabRefFrame frame, PreferencesDialogView view) {
+        this.dialogService = dialogService;
+        this.taskExecutor = taskExecutor;
+        this.prefs = Globals.prefs;
+        this.frame = frame;
+        this.view = view;
+
+        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, 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<PrefsTab> 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();
+        }
+    }
+
+    private void updateAfterPreferenceChanges() {
+
+        view.setValues();
+
+        List<TemplateExporter> 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();
+    }
+
+    public 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."));
+    }
+}
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();
     }
 }

From 8462cc797d29cf953d5f1b4a8d6d7b3716fe1726 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Wed, 5 Jun 2019 22:55:15 +0200
Subject: [PATCH 02/22] Fixed wrong logging class

---
 .../org/jabref/gui/preferences/PreferencesDialogViewModel.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index 9642f155ad5..bc62461053e 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -31,7 +31,7 @@
 
 public class PreferencesDialogViewModel extends AbstractViewModel {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ImportCustomizationDialogViewModel.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesDialogViewModel.class);
 
     private final DialogService dialogService;
     private final TaskExecutor taskExecutor;

From 106aea44f137d9c1bfa008de9071f071fa4268d3 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Wed, 5 Jun 2019 22:59:17 +0200
Subject: [PATCH 03/22] Fixed unused import

---
 .../org/jabref/gui/preferences/PreferencesDialogViewModel.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index bc62461053e..af4e3845c56 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -13,7 +13,6 @@
 import org.jabref.gui.DialogService;
 import org.jabref.gui.GUIGlobals;
 import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.importer.ImportCustomizationDialogViewModel;
 import org.jabref.gui.util.FileDialogConfiguration;
 import org.jabref.gui.util.TaskExecutor;
 import org.jabref.logic.exporter.ExporterFactory;

From dbfb3d67b6a467cfc7d3039c9145f51ac3cd8803 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Thu, 6 Jun 2019 17:37:35 +0200
Subject: [PATCH 04/22] Added visual improvements

---
 src/main/java/org/jabref/gui/Base.css               |  4 ++++
 .../jabref/gui/preferences/PreferencesDialog.css    | 12 +++++++++++-
 .../jabref/gui/preferences/PreferencesDialog.fxml   | 13 +++++++------
 .../gui/preferences/PreferencesDialogView.java      |  7 +++++--
 4 files changed, 27 insertions(+), 9 deletions(-)

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/PreferencesDialog.css b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.css
index b6b9da0f317..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 @@
 #preferenceTabList {
-    -fx-background-color: -fx-control-inner-background;
+    -fx-background-color: transparent;
     -fx-border-color: -fx-outer-border;
     -fx-border-width: 1;
 }
 
 #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 139fd9adc20..48bf2979668 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
@@ -7,21 +7,22 @@
 <?import javafx.scene.control.ListView?>
 <?import javafx.scene.control.ScrollPane?>
 <?import javafx.scene.control.SplitPane?>
-<?import javafx.scene.control.TextField?>
 <?import javafx.scene.control.Tooltip?>
 <?import javafx.scene.layout.VBox?>
 
+<?import org.controlsfx.control.textfield.CustomTextField?>
+
 <DialogPane prefHeight="700.0" prefWidth="1100.0" minHeight="400" minWidth="600" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.PreferencesDialogView">
     <content>
-        <SplitPane dividerPositions="0.3">
+        <SplitPane dividerPositions="0.2">
             <items>
-                <VBox prefWidth="160.0" styleClass="split-pane">
+                <VBox prefWidth="160.0" styleClass="preference-sidepane">
                     <children>
-                        <TextField fx:id="searchBox" promptText="%Search" VBox.vgrow="NEVER">
+                        <CustomTextField fx:id="searchBox" promptText="%Search" VBox.vgrow="NEVER">
                             <VBox.margin>
                                 <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
                             </VBox.margin>
-                        </TextField>
+                        </CustomTextField>
                         <ListView fx:id="preferenceTabList" VBox.vgrow="ALWAYS" />
                         <VBox prefHeight="10.0" VBox.vgrow="SOMETIMES" />
                         <VBox alignment="BOTTOM_LEFT" spacing="3.0">
@@ -41,7 +42,7 @@
                         </VBox>
                     </children>
                 </VBox>
-                <ScrollPane fx:id="preferencePaneContainer" />
+                <ScrollPane fx:id="preferencePaneContainer" maxHeight="Infinity" maxWidth="Infinity" />
             </items>
         </SplitPane>
     </content>
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
index 1c2f6c6da41..6da1cc06d96 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -8,10 +8,10 @@
 import javafx.scene.control.ButtonType;
 import javafx.scene.control.ListView;
 import javafx.scene.control.ScrollPane;
-import javafx.scene.control.TextField;
 
 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;
@@ -20,6 +20,7 @@
 import org.jabref.preferences.PreferencesService;
 
 import com.airhacks.afterburner.views.ViewLoader;
+import org.controlsfx.control.textfield.CustomTextField;
 import org.fxmisc.easybind.EasyBind;
 
 /**
@@ -28,7 +29,7 @@
  */
 public class PreferencesDialogView extends BaseDialog<PreferencesDialogViewModel> {
 
-    @FXML private TextField searchBox;
+    @FXML private CustomTextField searchBox;
     @FXML private ListView<PrefsTab> preferenceTabList;
     @FXML private ScrollPane preferencePaneContainer;
     @FXML private ButtonType saveButton;
@@ -69,6 +70,8 @@ private void initialize () {
             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) {

From e8ce43a4e3e58754dfa53e16e0ff6aaf3e4c94f2 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Thu, 6 Jun 2019 17:44:37 +0200
Subject: [PATCH 05/22] Convertet GeneralTab to MVVM

---
 .../jabref/gui/preferences/GeneralTab.fxml    |  82 ++++++++
 .../gui/preferences/GeneralTabView.java       | 121 ++++++++++++
 .../gui/preferences/GeneralTabViewModel.java  | 186 ++++++++++++++++++
 .../PreferencesDialogViewModel.java           |   2 +-
 src/main/resources/l10n/JabRef_en.properties  |   4 +-
 5 files changed, 393 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
 create mode 100644 src/main/java/org/jabref/gui/preferences/GeneralTabView.java
 create mode 100644 src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java

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..3fdc6464a1b
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?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.ColumnConstraints?>
+<?import javafx.scene.layout.GridPane?>
+<?import javafx.scene.layout.RowConstraints?>
+
+<fx:root xmlns:fx="http://javafx.com/fxml/1"
+         type="GridPane"
+         xmlns="http://javafx.com/javafx/8.0.212"
+         fx:controller="org.jabref.gui.preferences.GeneralTabView">
+
+    <columnConstraints>
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="230.0" />
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="200.0" />
+        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0" />
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints valignment="CENTER" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+    </rowConstraints>
+    <children>
+        <Label styleClass="sectionHeader" text="%General" />
+        <Label text="\%Language:" GridPane.rowIndex="1" />
+        <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="1" />
+        <Label text="\%Default encoding:" GridPane.rowIndex="2" />
+        <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="2" />
+        <Label text="\%Default bibliography mode:" GridPane.rowIndex="3" />
+        <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="3" />
+        <CheckBox fx:id="inspectionWarningDuplicate" text="\%Warn about unresolved duplicates when closing inspection window" GridPane.columnSpan="3" GridPane.rowIndex="4" />
+        <CheckBox fx:id="confirmDelete" text="\%Show confirmation dialog when deleting entries" GridPane.columnSpan="3" GridPane.rowIndex="5" />
+        <CheckBox fx:id="enforceLegalKeys" text="\%Enforce legal characters in BibTex keys" GridPane.columnSpan="3" GridPane.rowIndex="6" />
+        <CheckBox fx:id="memoryStickMode" text="\%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" GridPane.columnSpan="3" GridPane.rowIndex="7" />
+        <CheckBox fx:id="collectTelemetry" text="\%Collect and share telemetry data to help improve JabRef." GridPane.columnSpan="3" GridPane.rowIndex="8" />
+        <CheckBox fx:id="showAdvancedHints" text="\%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" GridPane.columnSpan="3" GridPane.rowIndex="9" />
+
+        <Label styleClass="sectionHeader" text="%Entry owner" GridPane.rowIndex="10" />
+        <CheckBox fx:id="markOwner" text="\%Mark new entries with owner name:" GridPane.rowIndex="11" />
+        <TextField fx:id="markOwnerName" GridPane.columnIndex="1" GridPane.rowIndex="11" />
+        <CheckBox fx:id="markOwnerOverwrite" text="\%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="11">
+            <GridPane.margin>
+                <Insets left="5.0" />
+            </GridPane.margin>
+        </CheckBox>
+        <Button fx:id="markOwnerHelp" GridPane.columnIndex="3" GridPane.rowIndex="11" />
+
+        <Label styleClass="sectionHeader" text="%Time stamp" GridPane.rowIndex="12" />
+        <CheckBox fx:id="markTimestamp" text="\%Mark new entries with addition date" GridPane.columnSpan="3" GridPane.rowIndex="13" />
+        <Label text="\%Date format:" GridPane.halignment="RIGHT" GridPane.rowIndex="14" />
+        <TextField fx:id="markTimeStampFormat" GridPane.columnIndex="1" GridPane.rowIndex="14" />
+        <CheckBox fx:id="markTimeStampOverwrite" text="\%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="14">
+            <GridPane.margin>
+                <Insets left="5.0" />
+            </GridPane.margin>
+        </CheckBox>
+        <Label text="\%Field name:" GridPane.halignment="RIGHT" GridPane.rowIndex="15" />
+        <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="1" GridPane.rowIndex="15" />
+        <Button fx:id="markTimeStampHelp" GridPane.columnIndex="3" GridPane.rowIndex="15" />
+        <CheckBox fx:id="updateTimeStamp" text="\%Update timestamp on modification" GridPane.rowIndex="16" />
+    </children>
+</fx:root>
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..40ccb7695cc
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -0,0 +1,121 @@
+package org.jabref.gui.preferences;
+
+import java.nio.charset.Charset;
+
+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.GridPane;
+
+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.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;
+
+public class GeneralTabView extends GridPane implements PrefsTab {
+
+    @FXML private ComboBox<Language> language;
+    @FXML private ComboBox<Charset> defaultEncoding;
+    @FXML private ComboBox<BibDatabaseMode> 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;
+
+    private final DialogService dialogService;
+    private final JabRefPreferences preferences;
+
+    private GeneralTabViewModel viewModel;
+
+    public GeneralTabView (DialogService dialogService, JabRefPreferences preferences) {
+        this.dialogService = dialogService;
+        this.preferences = preferences;
+        ViewLoader.view(this)
+                  .root(this)
+                  .load();
+// ???       Globals.getThemeLoader().installCss(this.getScene(), Globals.prefs);
+    }
+
+    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);
+    }
+
+    @Override
+    public Node getBuilder() {
+        return this;
+    }
+
+    @Override
+    public void setValues() {
+        // Done by bindings
+    }
+
+    @Override
+    public void storeSettings() {
+        viewModel.storeSettings();
+    }
+
+    @Deprecated
+    @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..76fff2c1cf1
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -0,0 +1,186 @@
+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.AbstractViewModel;
+import org.jabref.gui.DialogService;
+import org.jabref.gui.util.DefaultTaskExecutor;
+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;
+
+public class GeneralTabViewModel extends AbstractViewModel {
+    private final ListProperty<Language> languagesListProperty = new SimpleListProperty<>();
+    private final ObjectProperty<Language> selectedLanguageProperty = new SimpleObjectProperty<>();
+    private final ListProperty<Charset> encodingsListProperty = new SimpleListProperty<>();
+    private final ObjectProperty<Charset> selectedEncodingProperty = new SimpleObjectProperty<>();
+    private final ListProperty<BibDatabaseMode> bibliographyModeListProperty = new SimpleListProperty<>();
+    private final ObjectProperty<BibDatabaseMode> 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 final DialogService dialogService;
+    private final JabRefPreferences preferences;
+
+    public GeneralTabViewModel (DialogService dialogService, JabRefPreferences preferences) {
+        this.dialogService = dialogService;
+        this.preferences = preferences;
+        setValues();
+    }
+
+    private 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, markOwnerOverwriteProperty.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 boolean validateSettings() {
+        try {
+            // Test if date format is legal:
+            DateTimeFormatter.ofPattern(markTimeStampFormatProperty.getValue());
+        } catch (IllegalArgumentException exception) {
+            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;
+    }
+
+    // General
+
+    public ListProperty<Language> languagesListProperty() { return this.languagesListProperty; }
+
+    public ObjectProperty<Language> selectedLanguageProperty() { return this.selectedLanguageProperty; }
+
+    public ListProperty<Charset> encodingsListProperty() { return this.encodingsListProperty; }
+
+    public ObjectProperty<Charset> selectedEncodingProperty() { return this.selectedEncodingProperty; }
+
+    public ListProperty<BibDatabaseMode> biblatexModeListProperty() { return this.bibliographyModeListProperty; }
+
+    public ObjectProperty<BibDatabaseMode> 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/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index af4e3845c56..bc7667787da 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -47,7 +47,7 @@ public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor task
         this.view = view;
 
         preferenceTabs = FXCollections.observableArrayList();
-        preferenceTabs.add(new GeneralTab(dialogService, prefs));
+        preferenceTabs.add(new GeneralTabView(dialogService, prefs));
         preferenceTabs.add(new FileTab(dialogService, prefs));
         preferenceTabs.add(new TablePrefsTab(prefs));
         preferenceTabs.add(new TableColumnsTab(prefs, frame));
diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties
index 28e5ce1f177..c3c8ed1fc31 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
@@ -931,7 +933,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
 

From 4e64bde1a4741478b9f2d23712c98904744ecedc Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Thu, 6 Jun 2019 18:09:07 +0200
Subject: [PATCH 06/22] Removed old GeneralTab

---
 .../jabref/gui/preferences/GeneralTab.java    | 232 ------------------
 1 file changed, 232 deletions(-)
 delete mode 100644 src/main/java/org/jabref/gui/preferences/GeneralTab.java

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<Language> languageSelection = new ComboBox<>();
-    private final ComboBox<Charset> encodings;
-    private final ComboBox<BibDatabaseMode> 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<Language>()
-                .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");
-    }
-}

From 0aad34f19ce70a434fdb7a56b6754e8988487433 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Thu, 6 Jun 2019 18:39:42 +0200
Subject: [PATCH 07/22] Removed old GeneralTab

---
 .../jabref/gui/preferences/GeneralTab.fxml    | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
index 3fdc6464a1b..3bf02ce7c4c 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -42,23 +42,23 @@
     </rowConstraints>
     <children>
         <Label styleClass="sectionHeader" text="%General" />
-        <Label text="\%Language:" GridPane.rowIndex="1" />
+        <Label text="%Language" GridPane.rowIndex="1" />
         <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="1" />
-        <Label text="\%Default encoding:" GridPane.rowIndex="2" />
+        <Label text="%Default encoding" GridPane.rowIndex="2" />
         <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="2" />
-        <Label text="\%Default bibliography mode:" GridPane.rowIndex="3" />
+        <Label text="%Default bibliography mode" GridPane.rowIndex="3" />
         <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="3" />
-        <CheckBox fx:id="inspectionWarningDuplicate" text="\%Warn about unresolved duplicates when closing inspection window" GridPane.columnSpan="3" GridPane.rowIndex="4" />
-        <CheckBox fx:id="confirmDelete" text="\%Show confirmation dialog when deleting entries" GridPane.columnSpan="3" GridPane.rowIndex="5" />
-        <CheckBox fx:id="enforceLegalKeys" text="\%Enforce legal characters in BibTex keys" GridPane.columnSpan="3" GridPane.rowIndex="6" />
-        <CheckBox fx:id="memoryStickMode" text="\%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" GridPane.columnSpan="3" GridPane.rowIndex="7" />
-        <CheckBox fx:id="collectTelemetry" text="\%Collect and share telemetry data to help improve JabRef." GridPane.columnSpan="3" GridPane.rowIndex="8" />
-        <CheckBox fx:id="showAdvancedHints" text="\%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" GridPane.columnSpan="3" GridPane.rowIndex="9" />
+        <CheckBox fx:id="inspectionWarningDuplicate" text="%Warn about unresolved duplicates when closing inspection window" GridPane.columnSpan="3" GridPane.rowIndex="4" />
+        <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries" GridPane.columnSpan="3" GridPane.rowIndex="5" />
+        <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys" GridPane.columnSpan="3" GridPane.rowIndex="6" />
+        <CheckBox fx:id="memoryStickMode" text="%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" GridPane.columnSpan="3" GridPane.rowIndex="7" />
+        <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef." GridPane.columnSpan="3" GridPane.rowIndex="8" />
+        <CheckBox fx:id="showAdvancedHints" text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" GridPane.columnSpan="3" GridPane.rowIndex="9" />
 
         <Label styleClass="sectionHeader" text="%Entry owner" GridPane.rowIndex="10" />
-        <CheckBox fx:id="markOwner" text="\%Mark new entries with owner name:" GridPane.rowIndex="11" />
+        <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" GridPane.rowIndex="11" />
         <TextField fx:id="markOwnerName" GridPane.columnIndex="1" GridPane.rowIndex="11" />
-        <CheckBox fx:id="markOwnerOverwrite" text="\%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="11">
+        <CheckBox fx:id="markOwnerOverwrite" text="%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="11">
             <GridPane.margin>
                 <Insets left="5.0" />
             </GridPane.margin>
@@ -66,17 +66,17 @@
         <Button fx:id="markOwnerHelp" GridPane.columnIndex="3" GridPane.rowIndex="11" />
 
         <Label styleClass="sectionHeader" text="%Time stamp" GridPane.rowIndex="12" />
-        <CheckBox fx:id="markTimestamp" text="\%Mark new entries with addition date" GridPane.columnSpan="3" GridPane.rowIndex="13" />
-        <Label text="\%Date format:" GridPane.halignment="RIGHT" GridPane.rowIndex="14" />
+        <CheckBox fx:id="markTimestamp" text="%Mark new entries with addition date" GridPane.columnSpan="3" GridPane.rowIndex="13" />
+        <Label text="%Date format" GridPane.rowIndex="14" />
         <TextField fx:id="markTimeStampFormat" GridPane.columnIndex="1" GridPane.rowIndex="14" />
-        <CheckBox fx:id="markTimeStampOverwrite" text="\%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="14">
+        <CheckBox fx:id="markTimeStampOverwrite" text="%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="14">
             <GridPane.margin>
                 <Insets left="5.0" />
             </GridPane.margin>
         </CheckBox>
-        <Label text="\%Field name:" GridPane.halignment="RIGHT" GridPane.rowIndex="15" />
+        <Label text="%Field name" GridPane.rowIndex="15" />
         <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="1" GridPane.rowIndex="15" />
         <Button fx:id="markTimeStampHelp" GridPane.columnIndex="3" GridPane.rowIndex="15" />
-        <CheckBox fx:id="updateTimeStamp" text="\%Update timestamp on modification" GridPane.rowIndex="16" />
+        <CheckBox fx:id="updateTimeStamp" text="%Update timestamp on modification" GridPane.rowIndex="16" />
     </children>
 </fx:root>

From e51571ec00fc05fa3dc85a2e0378cef84baa7648 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Thu, 6 Jun 2019 18:53:20 +0200
Subject: [PATCH 08/22] Added tooltip, fixed travis

---
 src/main/java/org/jabref/gui/preferences/GeneralTab.fxml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
index 3bf02ce7c4c..24e431240bd 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -10,6 +10,7 @@
 <?import javafx.scene.layout.GridPane?>
 <?import javafx.scene.layout.RowConstraints?>
 
+<?import javafx.scene.control.Tooltip?>
 <fx:root xmlns:fx="http://javafx.com/fxml/1"
          type="GridPane"
          xmlns="http://javafx.com/javafx/8.0.212"
@@ -62,6 +63,7 @@
             <GridPane.margin>
                 <Insets left="5.0" />
             </GridPane.margin>
+            <tooltip><Tooltip text="%If a pasted or imported entry already has the field set, overwrite." /></tooltip>
         </CheckBox>
         <Button fx:id="markOwnerHelp" GridPane.columnIndex="3" GridPane.rowIndex="11" />
 
@@ -73,6 +75,7 @@
             <GridPane.margin>
                 <Insets left="5.0" />
             </GridPane.margin>
+            <tooltip><Tooltip text="%If a pasted or imported entry already has the field set, overwrite." /></tooltip>
         </CheckBox>
         <Label text="%Field name" GridPane.rowIndex="15" />
         <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="1" GridPane.rowIndex="15" />

From 86de348d6dbfa47fa9830477ccad9102c260fcb1 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Fri, 7 Jun 2019 14:54:00 +0200
Subject: [PATCH 09/22] Added initial FileTab-MVVM

---
 .../org/jabref/gui/preferences/FileTab.fxml   | 93 +++++++++++++++++++
 .../jabref/gui/preferences/FileTabView.java   | 57 ++++++++++++
 .../gui/preferences/FileTabViewModel.java     | 29 ++++++
 .../jabref/gui/preferences/GeneralTab.fxml    |  8 +-
 .../preferences/PreferenceTabViewModel.java   | 11 +++
 .../PreferencesDialogViewModel.java           |  2 +-
 6 files changed, 195 insertions(+), 5 deletions(-)
 create mode 100644 src/main/java/org/jabref/gui/preferences/FileTab.fxml
 create mode 100644 src/main/java/org/jabref/gui/preferences/FileTabView.java
 create mode 100644 src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
 create mode 100644 src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java

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..64bd73289a7
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?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.TextField?>
+<?import javafx.scene.control.ToggleGroup?>
+<?import javafx.scene.layout.ColumnConstraints?>
+<?import javafx.scene.layout.GridPane?>
+<?import javafx.scene.layout.RowConstraints?>
+
+<fx:root type="GridPane" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1"
+         fx:controller="org.jabref.gui.preferences.FileTabView">
+
+    <columnConstraints>
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="250.0"/>
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="250.0"/>
+        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="80.0"/>
+        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints valignment="CENTER" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+    </rowConstraints>
+    <children>
+        <Label styleClass="sectionHeader" text="%General"/>
+        <CheckBox text="%Open last edited libraries at startup" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
+        <CheckBox text="%Backup old file when saving" GridPane.columnSpan="3" GridPane.rowIndex="2"/>
+        <Label text="%Do not wrap the following fields when saving" GridPane.rowIndex="3"/>
+        <TextField GridPane.columnIndex="1" GridPane.rowIndex="3"/>
+        <RadioButton text="%Resolve strings for standard BibTeX fields only" GridPane.rowIndex="4">
+            <toggleGroup>
+                <ToggleGroup fx:id="stringsResolveToggleGroup"/>
+            </toggleGroup>
+        </RadioButton>
+        <RadioButton text="%Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup"
+                     GridPane.rowIndex="5"/>
+        <TextField GridPane.columnIndex="1" GridPane.rowIndex="5"/>
+        <Label text="%Newline separator" GridPane.rowIndex="6"/>
+        <ComboBox prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="6"/>
+        <CheckBox text="%Always reformat BIB file on save and export" GridPane.columnSpan="3" GridPane.rowIndex="7"/>
+
+        <Label styleClass="sectionHeader" text="%External file links" GridPane.rowIndex="8"/>
+        <Label text="%Main file directory" GridPane.rowIndex="9"/>
+        <TextField GridPane.columnIndex="1" GridPane.rowIndex="9"/>
+        <Button maxWidth="1.7976931348623157E308" text="%Browse" GridPane.columnIndex="2" GridPane.hgrow="SOMETIMES"
+                GridPane.rowIndex="9">
+            <GridPane.margin>
+                <Insets left="5.0" right="5.0"/>
+            </GridPane.margin>
+        </Button>
+        <CheckBox text="%Use the BIB file location as primary file directory" GridPane.columnSpan="3"
+                  GridPane.rowIndex="10"/>
+        <Button GridPane.columnIndex="3" GridPane.rowIndex="10"/>
+        <RadioButton text="%Autolink files with names starting with the BibTeX key" GridPane.columnSpan="2147483647"
+                     GridPane.rowIndex="11">
+            <toggleGroup>
+                <ToggleGroup fx:id="autolinkToggleGroup"/>
+            </toggleGroup>
+        </RadioButton>
+        <RadioButton text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup"
+                     GridPane.columnSpan="2147483647" GridPane.rowIndex="12"/>
+        <RadioButton text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" GridPane.rowIndex="13"/>
+        <TextField GridPane.columnIndex="1" GridPane.rowIndex="13"/>
+        <CheckBox text="%When opening file link, search for matching file if no link is defined" GridPane.columnSpan="3"
+                  GridPane.rowIndex="14"/>
+        <CheckBox text="%Automatically open browse dialog when creating new file link" GridPane.columnSpan="3"
+                  GridPane.rowIndex="15"/>
+        <Label styleClass="sectionHeader" text="%Autosave" GridPane.rowIndex="17"/>
+        <CheckBox text="%Autosave local libraries" GridPane.rowIndex="18"/>
+        <Button GridPane.columnIndex="3" GridPane.rowIndex="18"/>
+    </children>
+</fx:root>
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..dbe00e693ad
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -0,0 +1,57 @@
+package org.jabref.gui.preferences;
+
+import javafx.scene.Node;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.VBox;
+
+import org.jabref.gui.DialogService;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.preferences.JabRefPreferences;
+
+import com.airhacks.afterburner.views.ViewLoader;
+
+public class FileTabView extends VBox implements PrefsTab {
+
+    private final DialogService dialogService;
+    private final JabRefPreferences preferences;
+
+    private FileTabViewModel viewModel;
+
+    public FileTabView (DialogService dialogService, JabRefPreferences preferences) {
+        this.dialogService = dialogService;
+        this.preferences = preferences;
+        ViewLoader.view(this)
+                  .root(this)
+                  .load();
+    }
+
+    public void initialize() {
+        viewModel = new FileTabViewModel(dialogService, preferences);
+    }
+
+    @Override
+    public Node getBuilder() {
+        return this;
+    }
+
+    @Override
+    public void setValues() {
+        // Done by bindings
+    }
+
+    @Override
+    public void storeSettings() {
+        viewModel.storeSettings();
+    }
+
+    @Deprecated
+    @Override
+    public boolean validateSettings() {
+        return viewModel.validateSettings();
+    }
+
+    @Override
+    public String getTabName() {
+        return Localization.lang("File");
+    }
+}
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..107e1affce9
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -0,0 +1,29 @@
+package org.jabref.gui.preferences;
+
+import org.jabref.gui.DialogService;
+import org.jabref.preferences.JabRefPreferences;
+
+public class FileTabViewModel implements PreferenceTabViewModel {
+
+    private final DialogService dialogService;
+    private final JabRefPreferences preferences;
+
+    public FileTabViewModel(DialogService dialogService, JabRefPreferences preferences) {
+        this.dialogService = dialogService;
+        this.preferences = preferences;
+        setValues();
+    }
+
+    public void setValues() {
+
+    }
+
+    public void storeSettings() {
+
+    }
+
+    public boolean validateSettings() {
+         return true;
+    }
+}
+
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
index 24e431240bd..8d1aadf4605 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -17,10 +17,10 @@
          fx:controller="org.jabref.gui.preferences.GeneralTabView">
 
     <columnConstraints>
-        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="230.0" />
-        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="200.0" />
-        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
-        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0" />
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="250.0"/>
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="250.0"/>
+        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="80.0"/>
+        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0"/>
     </columnConstraints>
     <rowConstraints>
         <RowConstraints valignment="CENTER" vgrow="SOMETIMES" />
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..0a3507ad676
--- /dev/null
+++ b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
@@ -0,0 +1,11 @@
+package org.jabref.gui.preferences;
+
+public interface PreferenceTabViewModel {
+
+    void setValues();
+
+    void storeSettings();
+
+    boolean validateSettings();
+
+}
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index bc7667787da..bf8ebcfc1e6 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -48,7 +48,7 @@ public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor task
 
         preferenceTabs = FXCollections.observableArrayList();
         preferenceTabs.add(new GeneralTabView(dialogService, prefs));
-        preferenceTabs.add(new FileTab(dialogService, prefs));
+        preferenceTabs.add(new FileTabView(dialogService, prefs));
         preferenceTabs.add(new TablePrefsTab(prefs));
         preferenceTabs.add(new TableColumnsTab(prefs, frame));
         preferenceTabs.add(new PreviewPreferencesTab(dialogService, taskExecutor));

From 7f0c7a6e588ff04a4fd78c2b751c150f6524f323 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Fri, 7 Jun 2019 23:49:29 +0200
Subject: [PATCH 10/22] Minor corrections

---
 .../org/jabref/gui/preferences/FileTab.fxml   | 159 +++++++++---------
 .../gui/preferences/GeneralTabView.java       |   1 -
 2 files changed, 82 insertions(+), 78 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
index 64bd73289a7..79774162d15 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -8,86 +8,91 @@
 <?import javafx.scene.control.RadioButton?>
 <?import javafx.scene.control.TextField?>
 <?import javafx.scene.control.ToggleGroup?>
-<?import javafx.scene.layout.ColumnConstraints?>
-<?import javafx.scene.layout.GridPane?>
-<?import javafx.scene.layout.RowConstraints?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
 
-<fx:root type="GridPane" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1"
-         fx:controller="org.jabref.gui.preferences.FileTabView">
 
-    <columnConstraints>
-        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="250.0"/>
-        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="250.0"/>
-        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="80.0"/>
-        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0"/>
-    </columnConstraints>
-    <rowConstraints>
-        <RowConstraints valignment="CENTER" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
-    </rowConstraints>
-    <children>
-        <Label styleClass="sectionHeader" text="%General"/>
-        <CheckBox text="%Open last edited libraries at startup" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
-        <CheckBox text="%Backup old file when saving" GridPane.columnSpan="3" GridPane.rowIndex="2"/>
-        <Label text="%Do not wrap the following fields when saving" GridPane.rowIndex="3"/>
-        <TextField GridPane.columnIndex="1" GridPane.rowIndex="3"/>
-        <RadioButton text="%Resolve strings for standard BibTeX fields only" GridPane.rowIndex="4">
-            <toggleGroup>
-                <ToggleGroup fx:id="stringsResolveToggleGroup"/>
-            </toggleGroup>
+<fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
+   <children>
+        <Label styleClass="sectionHeader" text="%General" />
+        <CheckBox text="%Open last edited libraries at startup" />
+        <CheckBox text="%Backup old file when saving" />
+      <HBox spacing="8.0">
+         <children>
+              <Label text="%Do not wrap the following fields when saving" />
+            <TextField HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+        <RadioButton text="%Resolve strings for standard BibTeX fields only">
+         <toggleGroup>
+                <ToggleGroup fx:id="stringsResolveToggleGroup" />
+         </toggleGroup>
         </RadioButton>
-        <RadioButton text="%Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup"
-                     GridPane.rowIndex="5"/>
-        <TextField GridPane.columnIndex="1" GridPane.rowIndex="5"/>
-        <Label text="%Newline separator" GridPane.rowIndex="6"/>
-        <ComboBox prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="6"/>
-        <CheckBox text="%Always reformat BIB file on save and export" GridPane.columnSpan="3" GridPane.rowIndex="7"/>
+        <RadioButton alignment="TOP_LEFT" maxWidth="1.7976931348623157E308" toggleGroup="$stringsResolveToggleGroup">
+         <graphic>
+            <HBox>
+               <children>
+                  <VBox maxWidth="1.7976931348623157E308" prefHeight="43.0" prefWidth="1581.0" spacing="10.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label text="\\%Resolve strings for all fields exception">
+                           <opaqueInsets>
+                              <Insets />
+                           </opaqueInsets>
+                        </Label>
+                          <TextField />
+                     </children>
+                  </VBox>
+               </children>
+               <opaqueInsets>
+                  <Insets left="4.0" />
+               </opaqueInsets>
+            </HBox>
+         </graphic>
+      </RadioButton>
+      <HBox alignment="CENTER_LEFT" spacing="10.0">
+         <children>
+              <Label alignment="TOP_LEFT" text="%Newline separator" />
+              <ComboBox prefWidth="200.0" />
+         </children>
+      </HBox>
+        <CheckBox text="%Always reformat BIB file on save and export" />
 
-        <Label styleClass="sectionHeader" text="%External file links" GridPane.rowIndex="8"/>
-        <Label text="%Main file directory" GridPane.rowIndex="9"/>
-        <TextField GridPane.columnIndex="1" GridPane.rowIndex="9"/>
-        <Button maxWidth="1.7976931348623157E308" text="%Browse" GridPane.columnIndex="2" GridPane.hgrow="SOMETIMES"
-                GridPane.rowIndex="9">
-            <GridPane.margin>
-                <Insets left="5.0" right="5.0"/>
-            </GridPane.margin>
-        </Button>
-        <CheckBox text="%Use the BIB file location as primary file directory" GridPane.columnSpan="3"
-                  GridPane.rowIndex="10"/>
-        <Button GridPane.columnIndex="3" GridPane.rowIndex="10"/>
-        <RadioButton text="%Autolink files with names starting with the BibTeX key" GridPane.columnSpan="2147483647"
-                     GridPane.rowIndex="11">
-            <toggleGroup>
-                <ToggleGroup fx:id="autolinkToggleGroup"/>
-            </toggleGroup>
+              <Label styleClass="sectionHeader" text="%External file links" />
+      <HBox alignment="CENTER_LEFT" spacing="10.0">
+         <children>
+              <Label text="%Main file directory" />
+              <TextField HBox.hgrow="ALWAYS" />
+              <Button maxWidth="1.7976931348623157E308" text="%Browse" />
+         </children>
+      </HBox>
+      <HBox alignment="CENTER_LEFT">
+         <children>
+              <CheckBox text="%Use the BIB file location as primary file directory" />
+            <HBox HBox.hgrow="ALWAYS" />
+              <Button />
+         </children>
+      </HBox>
+        <RadioButton text="%Autolink files with names starting with the BibTeX key">
+         <toggleGroup>
+                <ToggleGroup fx:id="autolinkToggleGroup" />
+         </toggleGroup>
         </RadioButton>
-        <RadioButton text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup"
-                     GridPane.columnSpan="2147483647" GridPane.rowIndex="12"/>
-        <RadioButton text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" GridPane.rowIndex="13"/>
-        <TextField GridPane.columnIndex="1" GridPane.rowIndex="13"/>
-        <CheckBox text="%When opening file link, search for matching file if no link is defined" GridPane.columnSpan="3"
-                  GridPane.rowIndex="14"/>
-        <CheckBox text="%Automatically open browse dialog when creating new file link" GridPane.columnSpan="3"
-                  GridPane.rowIndex="15"/>
-        <Label styleClass="sectionHeader" text="%Autosave" GridPane.rowIndex="17"/>
-        <CheckBox text="%Autosave local libraries" GridPane.rowIndex="18"/>
-        <Button GridPane.columnIndex="3" GridPane.rowIndex="18"/>
-    </children>
+        <RadioButton text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup" />
+      <HBox alignment="CENTER_LEFT" spacing="10.0">
+         <children>
+              <RadioButton text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" />
+              <TextField HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
+        <CheckBox text="%When opening file link, search for matching file if no link is defined" />
+        <CheckBox text="%Automatically open browse dialog when creating new file link" />
+        <Label styleClass="sectionHeader" text="%Autosave" />
+      <HBox>
+         <children>
+              <CheckBox text="%Autosave local libraries" />
+            <HBox HBox.hgrow="ALWAYS" />
+              <Button />
+         </children>
+      </HBox>
+   </children>
 </fx:root>
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
index 40ccb7695cc..aaf6560545a 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -56,7 +56,6 @@ public GeneralTabView (DialogService dialogService, JabRefPreferences preference
         ViewLoader.view(this)
                   .root(this)
                   .load();
-// ???       Globals.getThemeLoader().installCss(this.getScene(), Globals.prefs);
     }
 
     public void initialize() {

From 968f028bb07f9c4a130864f14f61ce1a58ebdd1f Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sat, 8 Jun 2019 02:48:12 +0200
Subject: [PATCH 11/22] Added FileTab, Reworked with VBox, comments and minor
 changes

---
 .../org/jabref/gui/preferences/FileTab.fxml   |  70 +++-----
 .../jabref/gui/preferences/FileTabView.java   |  42 ++++-
 .../gui/preferences/FileTabViewModel.java     |   5 +
 .../jabref/gui/preferences/GeneralTab.fxml    | 163 ++++++++++--------
 .../gui/preferences/GeneralTabView.java       |   6 +-
 .../preferences/PreferenceTabViewModel.java   |   3 +-
 .../gui/preferences/PreferencesDialog.fxml    |   2 +-
 .../preferences/PreferencesDialogView.java    |  21 +--
 .../PreferencesDialogViewModel.java           |  12 +-
 .../org/jabref/gui/preferences/PrefsTab.java  |   6 +-
 .../jabref/preferences/NewLineSeperator.java  |  41 +++++
 11 files changed, 221 insertions(+), 150 deletions(-)
 create mode 100644 src/main/java/org/jabref/preferences/NewLineSeperator.java

diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
index 79774162d15..be1b2dca96c 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<?import javafx.geometry.Insets?>
 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.CheckBox?>
 <?import javafx.scene.control.ComboBox?>
@@ -11,87 +10,66 @@
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
 
-
 <fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
    <children>
         <Label styleClass="sectionHeader" text="%General" />
-        <CheckBox text="%Open last edited libraries at startup" />
-        <CheckBox text="%Backup old file when saving" />
+        <CheckBox fx:id="openLastStartup" text="%Open last edited libraries at startup" />
+        <CheckBox fx:id="backupOldFile" text="%Backup old file when saving" />
       <HBox spacing="8.0">
          <children>
               <Label text="%Do not wrap the following fields when saving" />
-            <TextField HBox.hgrow="ALWAYS" />
+            <TextField fx:id="noWrapFiles" HBox.hgrow="ALWAYS" />
          </children>
       </HBox>
-        <RadioButton text="%Resolve strings for standard BibTeX fields only">
+        <RadioButton fx:id="resolveStringsBibTex" text="%Resolve strings for standard BibTeX fields only">
          <toggleGroup>
                 <ToggleGroup fx:id="stringsResolveToggleGroup" />
          </toggleGroup>
         </RadioButton>
-        <RadioButton alignment="TOP_LEFT" maxWidth="1.7976931348623157E308" toggleGroup="$stringsResolveToggleGroup">
-         <graphic>
-            <HBox>
-               <children>
-                  <VBox maxWidth="1.7976931348623157E308" prefHeight="43.0" prefWidth="1581.0" spacing="10.0" HBox.hgrow="ALWAYS">
-                     <children>
-                        <Label text="\\%Resolve strings for all fields exception">
-                           <opaqueInsets>
-                              <Insets />
-                           </opaqueInsets>
-                        </Label>
-                          <TextField />
-                     </children>
-                  </VBox>
-               </children>
-               <opaqueInsets>
-                  <Insets left="4.0" />
-               </opaqueInsets>
-            </HBox>
-         </graphic>
-      </RadioButton>
+      <HBox alignment="CENTER_LEFT" spacing="10.0">
+         <children>
+              <RadioButton fx:id="resolveStringsAll" alignment="TOP_LEFT" maxWidth="Infinity" text="Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup" />
+             <TextField fx:id="resolvStringsExcept" HBox.hgrow="ALWAYS" />
+         </children>
+      </HBox>
       <HBox alignment="CENTER_LEFT" spacing="10.0">
          <children>
               <Label alignment="TOP_LEFT" text="%Newline separator" />
-              <ComboBox prefWidth="200.0" />
+              <ComboBox fx:id="newLineSeparator" prefWidth="100.0" />
          </children>
       </HBox>
-        <CheckBox text="%Always reformat BIB file on save and export" />
+        <CheckBox fx:id="alwaysReformatBib" text="%Always reformat BIB file on save and export" />
 
               <Label styleClass="sectionHeader" text="%External file links" />
       <HBox alignment="CENTER_LEFT" spacing="10.0">
          <children>
               <Label text="%Main file directory" />
-              <TextField HBox.hgrow="ALWAYS" />
-              <Button maxWidth="1.7976931348623157E308" text="%Browse" />
-         </children>
-      </HBox>
-      <HBox alignment="CENTER_LEFT">
-         <children>
-              <CheckBox text="%Use the BIB file location as primary file directory" />
-            <HBox HBox.hgrow="ALWAYS" />
-              <Button />
+              <TextField fx:id="mainFileDir" HBox.hgrow="ALWAYS" />
+              <Button onAction="#mainFileDirBrowse" text="%Browse" />
          </children>
       </HBox>
-        <RadioButton text="%Autolink files with names starting with the BibTeX key">
+        <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory" />
+        <RadioButton fx:id="autolinkFilesWithBibtex" text="%Autolink files with names starting with the BibTeX key">
          <toggleGroup>
                 <ToggleGroup fx:id="autolinkToggleGroup" />
          </toggleGroup>
         </RadioButton>
-        <RadioButton text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup" />
+        <RadioButton fx:id="autolinkFilesOnlyBibtex" text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup" />
       <HBox alignment="CENTER_LEFT" spacing="10.0">
          <children>
-              <RadioButton text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" />
-              <TextField HBox.hgrow="ALWAYS" />
+              <RadioButton fx:id="autolinkUseRegex" text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" />
+              <TextField fx:id="autolinkRegexTerm" HBox.hgrow="ALWAYS" />
+              <Button fx:id="autolinkRegexHelp" />
          </children>
       </HBox>
-        <CheckBox text="%When opening file link, search for matching file if no link is defined" />
-        <CheckBox text="%Automatically open browse dialog when creating new file link" />
+        <CheckBox fx:id="searchFilesOnOpen" text="%When opening file link, search for matching file if no link is defined" />
+        <CheckBox fx:id="openBrowseOnCreate" text="%Automatically open browse dialog when creating new file link" />
         <Label styleClass="sectionHeader" text="%Autosave" />
       <HBox>
          <children>
-              <CheckBox text="%Autosave local libraries" />
+              <CheckBox fx:id="autosaveLocalLibraries" text="%Autosave local libraries" />
             <HBox HBox.hgrow="ALWAYS" />
-              <Button />
+              <Button fx:id="autosaveLocalLibrariesHelp" />
          </children>
       </HBox>
    </children>
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
index dbe00e693ad..d5e2e9ae9e3 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -1,17 +1,51 @@
 package org.jabref.gui.preferences;
 
+import javafx.fxml.FXML;
 import javafx.scene.Node;
-import javafx.scene.layout.GridPane;
+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.control.ToggleGroup;
 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.logic.help.HelpFile;
 import org.jabref.logic.l10n.Localization;
 import org.jabref.preferences.JabRefPreferences;
+import org.jabref.preferences.NewLineSeperator;
 
 import com.airhacks.afterburner.views.ViewLoader;
 
 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 ToggleGroup stringsResolveToggleGroup;
+    @FXML private RadioButton resolveStringsAll;
+    @FXML private TextField resolvStringsExcept;
+    @FXML private ComboBox<NewLineSeperator> newLineSeparator;
+    @FXML private CheckBox alwaysReformatBib;
+    @FXML private TextField mainFileDir;
+    @FXML private CheckBox useBibLocationAsPrimary;
+    @FXML private Button autolinkRegexHelp;
+    @FXML private RadioButton autolinkFilesWithBibtex;
+    @FXML private ToggleGroup autolinkToggleGroup;
+    @FXML private RadioButton autolinkFilesOnlyBibtex;
+    @FXML private RadioButton autolinkUseRegex;
+    @FXML private TextField autolinkRegexTerm;
+    @FXML private CheckBox searchFilesOnOpen;
+    @FXML private CheckBox openBrowseOnCreate;
+    @FXML private CheckBox autosaveLocalLibraries;
+    @FXML private Button autosaveLocalLibrariesHelp;
+
     private final DialogService dialogService;
     private final JabRefPreferences preferences;
 
@@ -27,6 +61,10 @@ public FileTabView (DialogService dialogService, JabRefPreferences preferences)
 
     public void initialize() {
         viewModel = new FileTabViewModel(dialogService, preferences);
+
+        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);
     }
 
     @Override
@@ -54,4 +92,6 @@ public boolean validateSettings() {
     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
index 107e1affce9..a8b8b23b9c4 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -2,6 +2,7 @@
 
 import org.jabref.gui.DialogService;
 import org.jabref.preferences.JabRefPreferences;
+import org.jabref.preferences.NewLineSeperator;
 
 public class FileTabViewModel implements PreferenceTabViewModel {
 
@@ -25,5 +26,9 @@ public void storeSettings() {
     public boolean validateSettings() {
          return true;
     }
+
+    public void mainFileDirBrowse () {
+        // ToDo
+    }
 }
 
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
index 8d1aadf4605..982106652d2 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -1,85 +1,106 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<?import javafx.geometry.Insets?>
 <?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.control.Tooltip?>
 <?import javafx.scene.layout.ColumnConstraints?>
 <?import javafx.scene.layout.GridPane?>
+<?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.RowConstraints?>
+<?import javafx.scene.layout.VBox?>
 
-<?import javafx.scene.control.Tooltip?>
-<fx:root xmlns:fx="http://javafx.com/fxml/1"
-         type="GridPane"
-         xmlns="http://javafx.com/javafx/8.0.212"
-         fx:controller="org.jabref.gui.preferences.GeneralTabView">
-
-    <columnConstraints>
-        <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="10.0" prefWidth="250.0"/>
-        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="250.0"/>
-        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="80.0"/>
-        <ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="30.0" minWidth="30.0" prefWidth="30.0"/>
-    </columnConstraints>
-    <rowConstraints>
-        <RowConstraints valignment="CENTER" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-    </rowConstraints>
-    <children>
-        <Label styleClass="sectionHeader" text="%General" />
-        <Label text="%Language" GridPane.rowIndex="1" />
-        <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="1" />
-        <Label text="%Default encoding" GridPane.rowIndex="2" />
-        <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="2" />
-        <Label text="%Default bibliography mode" GridPane.rowIndex="3" />
-        <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="NEVER" GridPane.rowIndex="3" />
-        <CheckBox fx:id="inspectionWarningDuplicate" text="%Warn about unresolved duplicates when closing inspection window" GridPane.columnSpan="3" GridPane.rowIndex="4" />
-        <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries" GridPane.columnSpan="3" GridPane.rowIndex="5" />
-        <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys" GridPane.columnSpan="3" GridPane.rowIndex="6" />
-        <CheckBox fx:id="memoryStickMode" text="%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" GridPane.columnSpan="3" GridPane.rowIndex="7" />
-        <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef." GridPane.columnSpan="3" GridPane.rowIndex="8" />
-        <CheckBox fx:id="showAdvancedHints" text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" GridPane.columnSpan="3" GridPane.rowIndex="9" />
+<fx:root spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.GeneralTabView">
+   <children>
+        <Label prefWidth="650.0" styleClass="sectionHeader" text="%General" />
+      <GridPane>
+        <columnConstraints>
+          <ColumnConstraints hgrow="SOMETIMES" maxWidth="319.66668701171875" minWidth="10.0" prefWidth="197.0" />
+          <ColumnConstraints hgrow="SOMETIMES" maxWidth="466.33331298828125" minWidth="10.0" prefWidth="453.0" />
+        </columnConstraints>
+        <rowConstraints>
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+            <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+            <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
+          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        </rowConstraints>
+         <children>
+              <Label text="%Language" />
+              <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" />
+              <Label text="%Default encoding" GridPane.rowIndex="2" />
+              <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
+              <Label text="%Default bibliography mode" GridPane.rowIndex="4" />
+              <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
+         </children>
+      </GridPane>
+        <CheckBox fx:id="inspectionWarningDuplicate" text="%Warn about unresolved duplicates when closing inspection window" />
+        <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries" />
+        <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys" />
+        <CheckBox fx:id="memoryStickMode" text="%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" />
+        <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef." />
+        <CheckBox fx:id="showAdvancedHints" text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" />
 
-        <Label styleClass="sectionHeader" text="%Entry owner" GridPane.rowIndex="10" />
-        <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" GridPane.rowIndex="11" />
-        <TextField fx:id="markOwnerName" GridPane.columnIndex="1" GridPane.rowIndex="11" />
-        <CheckBox fx:id="markOwnerOverwrite" text="%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="11">
-            <GridPane.margin>
-                <Insets left="5.0" />
-            </GridPane.margin>
-            <tooltip><Tooltip text="%If a pasted or imported entry already has the field set, overwrite." /></tooltip>
-        </CheckBox>
-        <Button fx:id="markOwnerHelp" GridPane.columnIndex="3" GridPane.rowIndex="11" />
+              <Label styleClass="sectionHeader" text="%Entry owner" />
+      <HBox alignment="CENTER_LEFT" spacing="10.0">
+         <children>
+              <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" />
+              <TextField fx:id="markOwnerName" HBox.hgrow="ALWAYS" />
+              <CheckBox fx:id="markOwnerOverwrite" text="%Overwrite">
+                  <tooltip>
+                  <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+               </tooltip>
+              </CheckBox>
+              <Button fx:id="markOwnerHelp" prefWidth="20.0" />
+         </children>
+      </HBox>
 
-        <Label styleClass="sectionHeader" text="%Time stamp" GridPane.rowIndex="12" />
-        <CheckBox fx:id="markTimestamp" text="%Mark new entries with addition date" GridPane.columnSpan="3" GridPane.rowIndex="13" />
-        <Label text="%Date format" GridPane.rowIndex="14" />
-        <TextField fx:id="markTimeStampFormat" GridPane.columnIndex="1" GridPane.rowIndex="14" />
-        <CheckBox fx:id="markTimeStampOverwrite" text="%Overwrite" GridPane.columnIndex="2" GridPane.rowIndex="14">
-            <GridPane.margin>
-                <Insets left="5.0" />
-            </GridPane.margin>
-            <tooltip><Tooltip text="%If a pasted or imported entry already has the field set, overwrite." /></tooltip>
-        </CheckBox>
-        <Label text="%Field name" GridPane.rowIndex="15" />
-        <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="1" GridPane.rowIndex="15" />
-        <Button fx:id="markTimeStampHelp" GridPane.columnIndex="3" GridPane.rowIndex="15" />
-        <CheckBox fx:id="updateTimeStamp" text="%Update timestamp on modification" GridPane.rowIndex="16" />
-    </children>
+              <Label styleClass="sectionHeader" text="%Time stamp" />
+        <CheckBox fx:id="markTimestamp" prefWidth="650.0" text="%Mark new entries with addition date" />
+      <HBox spacing="10.0">
+         <children>
+            <GridPane HBox.hgrow="ALWAYS">
+               <columnConstraints>
+                  <ColumnConstraints hgrow="SOMETIMES" />
+                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="10.0" minWidth="10.0" prefWidth="10.0" />
+                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" />
+               </columnConstraints>
+               <rowConstraints>
+                  <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
+                  <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
+                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+               </rowConstraints>
+               <children>
+                    <TextField fx:id="markTimeStampFormat" GridPane.columnIndex="2" GridPane.hgrow="ALWAYS" />
+                    <Label text="%Field name" GridPane.rowIndex="2" />
+                    <Label text="%Date format" GridPane.hgrow="SOMETIMES" />
+                    <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="2" GridPane.rowIndex="2" />
+               </children>
+            </GridPane>
+            <GridPane>
+               <columnConstraints>
+                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
+                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
+                  <ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" prefWidth="20.0" />
+               </columnConstraints>
+               <rowConstraints>
+                  <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
+                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+               </rowConstraints>
+               <children>
+                    <CheckBox fx:id="markTimeStampOverwrite" text="%Overwrite">
+                        <tooltip>
+                        <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+                     </tooltip>
+                    </CheckBox>
+                    <Button fx:id="markTimeStampHelp" prefWidth="20.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
+               </children>
+            </GridPane>
+         </children>
+      </HBox>
+      <HBox spacing="10.0" />
+        <CheckBox fx:id="updateTimeStamp" prefWidth="650.0" text="%Update timestamp on modification" />
+   </children>
 </fx:root>
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
index aaf6560545a..582dc4d0c25 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -8,7 +8,7 @@
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.ComboBox;
 import javafx.scene.control.TextField;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.VBox;
 
 import org.jabref.Globals;
 import org.jabref.gui.DialogService;
@@ -23,7 +23,7 @@
 
 import com.airhacks.afterburner.views.ViewLoader;
 
-public class GeneralTabView extends GridPane implements PrefsTab {
+public class GeneralTabView extends VBox implements PrefsTab {
 
     @FXML private ComboBox<Language> language;
     @FXML private ComboBox<Charset> defaultEncoding;
@@ -99,7 +99,7 @@ public Node getBuilder() {
 
     @Override
     public void setValues() {
-        // Done by bindings
+        // ToDo: Remove this after conversion of all tabs
     }
 
     @Override
diff --git a/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
index 0a3507ad676..1d8d7f87e6e 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
@@ -6,6 +6,5 @@ public interface PreferenceTabViewModel {
 
     void storeSettings();
 
-    boolean validateSettings();
-
+    boolean validateSettings(); // ToDo: Remove this after implementation of MVVMFX Validator
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
index 48bf2979668..db350db3111 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
@@ -42,7 +42,7 @@
                         </VBox>
                     </children>
                 </VBox>
-                <ScrollPane fx:id="preferencePaneContainer" maxHeight="Infinity" maxWidth="Infinity" />
+                <ScrollPane fx:id="preferencePaneContainer" styleClass="preferencePaneContainer" maxHeight="Infinity" maxWidth="Infinity" />
             </items>
         </SplitPane>
     </content>
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
index 6da1cc06d96..e2ef91cc738 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -57,9 +57,7 @@ public PreferencesDialogView(JabRefFrame frame, TaskExecutor taskExecutor) {
 
     @FXML
     private void initialize () {
-        viewModel = new PreferencesDialogViewModel(dialogService, taskExecutor, frame, this);
-        getDialogPane().getScene().getStylesheets().add(this.getClass().getResource("PreferencesDialog.css").toExternalForm());
-        preferencePaneContainer.getStyleClass().add("preferencePaneContainer");
+        viewModel = new PreferencesDialogViewModel(dialogService, taskExecutor, frame);
 
         preferenceTabList.itemsProperty().setValue(viewModel.getPreferenceTabs());
 
@@ -86,7 +84,7 @@ private void initialize () {
                 .withText(PrefsTab::getTabName)
                 .install(preferenceTabList);
 
-        setValues();
+        viewModel.setValues(); // ToDo: Remove this after conversion of all tabs
     }
 
     @FXML
@@ -117,19 +115,4 @@ void showAllPreferences() {
     void resetPreferences() {
         viewModel.resetPreferences();
     }
-
-    /**
-     * Sets the values in each preference tab according to Globals.prefs.
-     * Currently the PreferenceDialogViewModel uses this method, which,
-     * I believe, is not allowed in the MVVM-model. Fixing this would
-     * probably require refactoring the JabRefPreferences to use
-     * Properties probably (?), which would go way beyond this PR.
-     * So this is just deprecated and awaits refactoring.
-     */
-    @Deprecated
-    public void setValues() {
-        for (PrefsTab prefsTab : viewModel.getPreferenceTabs()) {
-            prefsTab.setValues();
-        }
-    }
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index bf8ebcfc1e6..3da78bb6b96 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -36,15 +36,13 @@ public class PreferencesDialogViewModel extends AbstractViewModel {
     private final TaskExecutor taskExecutor;
     private final JabRefPreferences prefs;
     private final ObservableList<PrefsTab> preferenceTabs;
-    private final PreferencesDialogView view;
     private final JabRefFrame frame;
 
-    public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor taskExecutor, JabRefFrame frame, PreferencesDialogView view) {
+    public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor taskExecutor, JabRefFrame frame) {
         this.dialogService = dialogService;
         this.taskExecutor = taskExecutor;
         this.prefs = Globals.prefs;
         this.frame = frame;
-        this.view = view;
 
         preferenceTabs = FXCollections.observableArrayList();
         preferenceTabs.add(new GeneralTabView(dialogService, prefs));
@@ -136,7 +134,7 @@ public void resetPreferences() {
 
     private void updateAfterPreferenceChanges() {
 
-        view.setValues();
+        setValues();
 
         List<TemplateExporter> customExporters = prefs.getCustomExportFormats(Globals.journalAbbreviationLoader);
         LayoutFormatterPreferences layoutPreferences = prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader);
@@ -164,4 +162,10 @@ public void storeAllSettings() {
         frame.getGlobalSearchBar().updateHintVisibility();
         dialogService.notify(Localization.lang("Preferences recorded."));
     }
+
+    public void setValues() {
+        for (PrefsTab prefsTab : preferenceTabs) {
+            prefsTab.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..56c8f1149cc 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
 
     /**
      * 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: Call directly in ViewModel after conversion of all tabs
 
     /**
      * 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: Call directly in ViewModel after conversion of all tabs
 
     /**
      * Should return the localized identifier to use for the tab.
diff --git a/src/main/java/org/jabref/preferences/NewLineSeperator.java b/src/main/java/org/jabref/preferences/NewLineSeperator.java
new file mode 100644
index 00000000000..9084b97cc91
--- /dev/null
+++ b/src/main/java/org/jabref/preferences/NewLineSeperator.java
@@ -0,0 +1,41 @@
+package org.jabref.preferences;
+
+public enum NewLineSeperator {
+    CR,
+    LF,
+    CRLF;
+
+    /**
+     * An enum which contains the possible NewLineSeperators
+     * Possible are CR ("\n"), LF ("\r") and the windows standard CR/LF.
+     */
+
+    /**
+     * @return the name of the current mode as String
+     */
+    public String getEscapeSign() {
+        switch (this) {
+            case CR:
+                return "\r";
+            case LF:
+                return "\n";
+            default:
+                return "\r\n";
+        }
+    }
+
+    /**
+     * Returns the {@link NewLineSeperator} that equals the given string.
+     **/
+    public static NewLineSeperator parse(String data) {
+        switch (data) {
+            case "\r":
+                return CR;
+            case "\n":
+                return LF;
+            default:
+                return CRLF;
+        }
+    }
+}
+

From 083fb55ab82ae42acfd1381cb29170bfc2ea2077 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sat, 8 Jun 2019 02:59:47 +0200
Subject: [PATCH 12/22] Removed unused imports

---
 src/main/java/org/jabref/gui/preferences/FileTabViewModel.java | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
index a8b8b23b9c4..e2a36cd6bad 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -2,7 +2,6 @@
 
 import org.jabref.gui.DialogService;
 import org.jabref.preferences.JabRefPreferences;
-import org.jabref.preferences.NewLineSeperator;
 
 public class FileTabViewModel implements PreferenceTabViewModel {
 

From a2254445ff84d93163fa8e31c733602912f62ad9 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sat, 8 Jun 2019 17:50:49 +0200
Subject: [PATCH 13/22] Added FileTab and some minor corrections

---
 .../org/jabref/gui/preferences/FileTab.fxml   | 127 +++++++-------
 .../jabref/gui/preferences/FileTabView.java   |  48 ++++--
 .../gui/preferences/FileTabViewModel.java     | 142 +++++++++++++++-
 .../jabref/gui/preferences/GeneralTab.fxml    | 156 +++++++++---------
 .../PreferencesDialogViewModel.java           |  23 ++-
 .../jabref/preferences/JabRefPreferences.java |  20 +++
 ...neSeperator.java => NewLineSeparator.java} |  19 ++-
 7 files changed, 370 insertions(+), 165 deletions(-)
 rename src/main/java/org/jabref/preferences/{NewLineSeperator.java => NewLineSeparator.java} (62%)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
index be1b2dca96c..32ea9e2c659 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -10,67 +10,70 @@
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
 
-<fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
-   <children>
-        <Label styleClass="sectionHeader" text="%General" />
-        <CheckBox fx:id="openLastStartup" text="%Open last edited libraries at startup" />
-        <CheckBox fx:id="backupOldFile" text="%Backup old file when saving" />
-      <HBox spacing="8.0">
-         <children>
-              <Label text="%Do not wrap the following fields when saving" />
-            <TextField fx:id="noWrapFiles" HBox.hgrow="ALWAYS" />
-         </children>
-      </HBox>
-        <RadioButton fx:id="resolveStringsBibTex" text="%Resolve strings for standard BibTeX fields only">
-         <toggleGroup>
-                <ToggleGroup fx:id="stringsResolveToggleGroup" />
-         </toggleGroup>
-        </RadioButton>
-      <HBox alignment="CENTER_LEFT" spacing="10.0">
-         <children>
-              <RadioButton fx:id="resolveStringsAll" alignment="TOP_LEFT" maxWidth="Infinity" text="Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup" />
-             <TextField fx:id="resolvStringsExcept" HBox.hgrow="ALWAYS" />
-         </children>
-      </HBox>
-      <HBox alignment="CENTER_LEFT" spacing="10.0">
-         <children>
-              <Label alignment="TOP_LEFT" text="%Newline separator" />
-              <ComboBox fx:id="newLineSeparator" prefWidth="100.0" />
-         </children>
-      </HBox>
-        <CheckBox fx:id="alwaysReformatBib" text="%Always reformat BIB file on save and export" />
+<fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212"
+         xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
+    <fx:define>
+        <ToggleGroup fx:id="stringsResolveToggleGroup"/>
+        <ToggleGroup fx:id="autolinkToggleGroup"/>
+    </fx:define>
+    <children>
+        <Label styleClass="sectionHeader" text="%General"/>
+        <CheckBox fx:id="openLastStartup" text="%Open last edited libraries at startup"/>
+        <CheckBox fx:id="backupOldFile" text="%Backup old file when saving"/>
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <Label text="%Do not wrap the following fields when saving"/>
+                <TextField fx:id="noWrapFiles" HBox.hgrow="ALWAYS"/>
+            </children>
+        </HBox>
+        <RadioButton fx:id="resolveStringsBibTex" text="%Resolve strings for standard BibTeX fields only"
+                     toggleGroup="$stringsResolveToggleGroup"/>
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <RadioButton fx:id="resolveStringsAll" alignment="TOP_LEFT" maxWidth="Infinity"
+                             text="Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup"/>
+                <TextField fx:id="resolveStringsExcept" disable="${!resolveStringsAll.selected}" HBox.hgrow="ALWAYS"/>
+            </children>
+        </HBox>
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <Label alignment="TOP_LEFT" text="%Newline separator"/>
+                <ComboBox fx:id="newLineSeparator" prefWidth="100.0"/>
+            </children>
+        </HBox>
+        <CheckBox fx:id="alwaysReformatBib" text="%Always reformat BIB file on save and export"/>
 
-              <Label styleClass="sectionHeader" text="%External file links" />
-      <HBox alignment="CENTER_LEFT" spacing="10.0">
-         <children>
-              <Label text="%Main file directory" />
-              <TextField fx:id="mainFileDir" HBox.hgrow="ALWAYS" />
-              <Button onAction="#mainFileDirBrowse" text="%Browse" />
-         </children>
-      </HBox>
-        <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory" />
-        <RadioButton fx:id="autolinkFilesWithBibtex" text="%Autolink files with names starting with the BibTeX key">
-         <toggleGroup>
-                <ToggleGroup fx:id="autolinkToggleGroup" />
-         </toggleGroup>
-        </RadioButton>
-        <RadioButton fx:id="autolinkFilesOnlyBibtex" text="%Autolink only files that match the BibTeX key" toggleGroup="$autolinkToggleGroup" />
-      <HBox alignment="CENTER_LEFT" spacing="10.0">
-         <children>
-              <RadioButton fx:id="autolinkUseRegex" text="%Use regular expression search" toggleGroup="$autolinkToggleGroup" />
-              <TextField fx:id="autolinkRegexTerm" HBox.hgrow="ALWAYS" />
-              <Button fx:id="autolinkRegexHelp" />
-         </children>
-      </HBox>
-        <CheckBox fx:id="searchFilesOnOpen" text="%When opening file link, search for matching file if no link is defined" />
-        <CheckBox fx:id="openBrowseOnCreate" text="%Automatically open browse dialog when creating new file link" />
-        <Label styleClass="sectionHeader" text="%Autosave" />
-      <HBox>
-         <children>
-              <CheckBox fx:id="autosaveLocalLibraries" text="%Autosave local libraries" />
-            <HBox HBox.hgrow="ALWAYS" />
-              <Button fx:id="autosaveLocalLibrariesHelp" />
-         </children>
-      </HBox>
-   </children>
+        <Label styleClass="sectionHeader" text="%External file links"/>
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <Label text="%Main file directory"/>
+                <TextField fx:id="mainFileDir" HBox.hgrow="ALWAYS"/>
+                <Button onAction="#mainFileDirBrowse" text="%Browse"/>
+            </children>
+        </HBox>
+        <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory"/>
+        <RadioButton fx:id="autolinkFileStartsBibtex" text="%Autolink files with names starting with the BibTeX key"
+                     toggleGroup="$autolinkToggleGroup"/>
+        <RadioButton fx:id="autolinkFileExactBibtex" text="%Autolink only files that match the BibTeX key"
+                     toggleGroup="$autolinkToggleGroup"/>
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <RadioButton fx:id="autolinkUseRegex" text="%Use regular expression search"
+                             toggleGroup="$autolinkToggleGroup"/>
+                <TextField fx:id="autolinkRegexKey" disable="${!autolinkUseRegex.selected}" HBox.hgrow="ALWAYS"/>
+                <Button fx:id="autolinkRegexHelp"/>
+            </children>
+        </HBox>
+        <CheckBox fx:id="searchFilesOnOpen"
+                  text="%When opening file link, search for matching file if no link is defined"/>
+        <CheckBox fx:id="openBrowseOnCreate" text="%Automatically open browse dialog when creating new file link"/>
+        <Label styleClass="sectionHeader" text="%Autosave"/>
+        <HBox alignment="CENTER_LEFT">
+            <children>
+                <CheckBox fx:id="autosaveLocalLibraries" text="%Autosave local libraries"/>
+                <HBox HBox.hgrow="ALWAYS"/>
+                <Button fx:id="autosaveLocalLibrariesHelp"/>
+            </children>
+        </HBox>
+    </children>
 </fx:root>
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
index d5e2e9ae9e3..d27bfb54491 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -7,7 +7,6 @@
 import javafx.scene.control.ComboBox;
 import javafx.scene.control.RadioButton;
 import javafx.scene.control.TextField;
-import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.VBox;
 
 import org.jabref.Globals;
@@ -18,7 +17,7 @@
 import org.jabref.logic.help.HelpFile;
 import org.jabref.logic.l10n.Localization;
 import org.jabref.preferences.JabRefPreferences;
-import org.jabref.preferences.NewLineSeperator;
+import org.jabref.preferences.NewLineSeparator;
 
 import com.airhacks.afterburner.views.ViewLoader;
 
@@ -28,21 +27,21 @@ public class FileTabView extends VBox implements PrefsTab {
     @FXML private CheckBox backupOldFile;
     @FXML private TextField noWrapFiles;
     @FXML private RadioButton resolveStringsBibTex;
-    @FXML private ToggleGroup stringsResolveToggleGroup;
     @FXML private RadioButton resolveStringsAll;
-    @FXML private TextField resolvStringsExcept;
-    @FXML private ComboBox<NewLineSeperator> newLineSeparator;
+    @FXML private TextField resolveStringsExcept;
+    @FXML private ComboBox<NewLineSeparator> newLineSeparator;
     @FXML private CheckBox alwaysReformatBib;
+
     @FXML private TextField mainFileDir;
     @FXML private CheckBox useBibLocationAsPrimary;
     @FXML private Button autolinkRegexHelp;
-    @FXML private RadioButton autolinkFilesWithBibtex;
-    @FXML private ToggleGroup autolinkToggleGroup;
-    @FXML private RadioButton autolinkFilesOnlyBibtex;
+    @FXML private RadioButton autolinkFileStartsBibtex;
+    @FXML private RadioButton autolinkFileExactBibtex;
     @FXML private RadioButton autolinkUseRegex;
-    @FXML private TextField autolinkRegexTerm;
+    @FXML private TextField autolinkRegexKey;
     @FXML private CheckBox searchFilesOnOpen;
     @FXML private CheckBox openBrowseOnCreate;
+
     @FXML private CheckBox autosaveLocalLibraries;
     @FXML private Button autosaveLocalLibrariesHelp;
 
@@ -51,7 +50,7 @@ public class FileTabView extends VBox implements PrefsTab {
 
     private FileTabViewModel viewModel;
 
-    public FileTabView (DialogService dialogService, JabRefPreferences preferences) {
+    public FileTabView(DialogService dialogService, JabRefPreferences preferences) {
         this.dialogService = dialogService;
         this.preferences = preferences;
         ViewLoader.view(this)
@@ -62,9 +61,30 @@ public FileTabView (DialogService dialogService, JabRefPreferences preferences)
     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);
+        actionFactory.configureIconButton(StandardActions.HELP_REGEX_SEARCH, new HelpAction(HelpFile.REGEX_SEARCH), autolinkRegexHelp);
+        actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.AUTOSAVE), autosaveLocalLibrariesHelp);
     }
 
     @Override
@@ -93,5 +113,7 @@ public String getTabName() {
         return Localization.lang("File");
     }
 
-    public void mainFileDirBrowse() { viewModel.mainFileDirBrowse(); }
+    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
index e2a36cd6bad..2ebb35e93be 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -1,10 +1,50 @@
 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;
 
 public class FileTabViewModel implements PreferenceTabViewModel {
 
+    private BooleanProperty openLastStartupProperty = new SimpleBooleanProperty();
+    private BooleanProperty backupOldFileProperty = new SimpleBooleanProperty();
+    private StringProperty noWrapFilesProperty = new SimpleStringProperty("");
+    private BooleanProperty resolveStringsBibTexProperty = new SimpleBooleanProperty();
+    private BooleanProperty resolveStringsAllProperty = new SimpleBooleanProperty();
+    private StringProperty resolveStringsExceptProperty = new SimpleStringProperty("");
+    private final ListProperty<NewLineSeparator> newLineSeparatorListProperty = new SimpleListProperty<>();
+    private final ObjectProperty<NewLineSeparator> selectedNewLineSeparatorProperty = new SimpleObjectProperty<>();
+    private BooleanProperty alwaysReformatBibProperty = new SimpleBooleanProperty();
+
+    private StringProperty mainFileDirProperty = new SimpleStringProperty("");
+    private BooleanProperty useBibLocationAsPrimaryProperty = new SimpleBooleanProperty();
+    private BooleanProperty autolinkFileStartsBibtexProperty = new SimpleBooleanProperty();
+    private BooleanProperty autolinkFileExactBibtexProperty = new SimpleBooleanProperty();
+    private BooleanProperty autolinkUseRegexProperty = new SimpleBooleanProperty();
+    private StringProperty autolinkRegexKeyProperty = new SimpleStringProperty("");
+    private BooleanProperty searchFilesOnOpenProperty = new SimpleBooleanProperty();
+    private BooleanProperty openBrowseOnCreateProperty = new SimpleBooleanProperty();
+
+    private BooleanProperty autosaveLocalLibraries = new SimpleBooleanProperty();
+
     private final DialogService dialogService;
     private final JabRefPreferences preferences;
 
@@ -15,19 +55,115 @@ public FileTabViewModel(DialogService dialogService, JabRefPreferences preferenc
     }
 
     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());
     }
 
     public boolean validateSettings() {
-         return true;
+        Path path = Paths.get(mainFileDirProperty.getValue());
+        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;
     }
 
-    public void mainFileDirBrowse () {
-        // ToDo
+    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<NewLineSeparator> newLineSeparatorListProperty() { return newLineSeparatorListProperty; }
+
+    public ObjectProperty<NewLineSeparator> 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
index 982106652d2..533031cbe53 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -12,30 +12,30 @@
 <?import javafx.scene.layout.RowConstraints?>
 <?import javafx.scene.layout.VBox?>
 
-<fx:root spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.GeneralTabView">
-   <children>
+<fx:root spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.GeneralTabView">
+    <children>
         <Label prefWidth="650.0" styleClass="sectionHeader" text="%General" />
-      <GridPane>
-        <columnConstraints>
-          <ColumnConstraints hgrow="SOMETIMES" maxWidth="319.66668701171875" minWidth="10.0" prefWidth="197.0" />
-          <ColumnConstraints hgrow="SOMETIMES" maxWidth="466.33331298828125" minWidth="10.0" prefWidth="453.0" />
-        </columnConstraints>
-        <rowConstraints>
-          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-            <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
-          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-            <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
-          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-        </rowConstraints>
-         <children>
-              <Label text="%Language" />
-              <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" />
-              <Label text="%Default encoding" GridPane.rowIndex="2" />
-              <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
-              <Label text="%Default bibliography mode" GridPane.rowIndex="4" />
-              <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
-         </children>
-      </GridPane>
+        <GridPane>
+            <columnConstraints>
+                <ColumnConstraints hgrow="SOMETIMES" maxWidth="319.66668701171875" minWidth="10.0" prefWidth="197.0" />
+                <ColumnConstraints hgrow="SOMETIMES" maxWidth="466.33331298828125" minWidth="10.0" prefWidth="453.0" />
+            </columnConstraints>
+            <rowConstraints>
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+            </rowConstraints>
+            <children>
+                <Label text="%Language" />
+                <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" />
+                <Label text="%Default encoding" GridPane.rowIndex="2" />
+                <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
+                <Label text="%Default bibliography mode" GridPane.rowIndex="4" />
+                <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
+            </children>
+        </GridPane>
         <CheckBox fx:id="inspectionWarningDuplicate" text="%Warn about unresolved duplicates when closing inspection window" />
         <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries" />
         <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys" />
@@ -43,64 +43,64 @@
         <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef." />
         <CheckBox fx:id="showAdvancedHints" text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" />
 
-              <Label styleClass="sectionHeader" text="%Entry owner" />
-      <HBox alignment="CENTER_LEFT" spacing="10.0">
-         <children>
-              <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" />
-              <TextField fx:id="markOwnerName" HBox.hgrow="ALWAYS" />
-              <CheckBox fx:id="markOwnerOverwrite" text="%Overwrite">
-                  <tooltip>
-                  <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
-               </tooltip>
-              </CheckBox>
-              <Button fx:id="markOwnerHelp" prefWidth="20.0" />
-         </children>
-      </HBox>
+        <Label styleClass="sectionHeader" text="%Entry owner" />
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
+            <children>
+                <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" />
+                <TextField fx:id="markOwnerName" disable="${!markOwner.selected}" HBox.hgrow="ALWAYS" />
+                <CheckBox fx:id="markOwnerOverwrite" disable="${!markOwner.selected}" text="%Overwrite">
+                    <tooltip>
+                        <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+                    </tooltip>
+                </CheckBox>
+                <Button fx:id="markOwnerHelp" prefWidth="20.0" />
+            </children>
+        </HBox>
 
-              <Label styleClass="sectionHeader" text="%Time stamp" />
+        <Label styleClass="sectionHeader" text="%Time stamp" />
         <CheckBox fx:id="markTimestamp" prefWidth="650.0" text="%Mark new entries with addition date" />
-      <HBox spacing="10.0">
-         <children>
-            <GridPane HBox.hgrow="ALWAYS">
-               <columnConstraints>
-                  <ColumnConstraints hgrow="SOMETIMES" />
-                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="10.0" minWidth="10.0" prefWidth="10.0" />
-                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" />
-               </columnConstraints>
-               <rowConstraints>
-                  <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
-                  <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
-                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-               </rowConstraints>
-               <children>
-                    <TextField fx:id="markTimeStampFormat" GridPane.columnIndex="2" GridPane.hgrow="ALWAYS" />
-                    <Label text="%Field name" GridPane.rowIndex="2" />
-                    <Label text="%Date format" GridPane.hgrow="SOMETIMES" />
-                    <TextField fx:id="markTimeStampFieldName" GridPane.columnIndex="2" GridPane.rowIndex="2" />
-               </children>
-            </GridPane>
-            <GridPane>
-               <columnConstraints>
-                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
+        <HBox spacing="10.0">
+            <children>
+                <GridPane disable="${!markTimestamp.selected}">
+                    <columnConstraints>
+                        <ColumnConstraints hgrow="SOMETIMES" />
                   <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
-                  <ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" prefWidth="20.0" />
-               </columnConstraints>
-               <rowConstraints>
+                        <ColumnConstraints hgrow="SOMETIMES" />
+                    </columnConstraints>
+                    <rowConstraints>
+                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
                   <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
-                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-               </rowConstraints>
-               <children>
-                    <CheckBox fx:id="markTimeStampOverwrite" text="%Overwrite">
-                        <tooltip>
-                        <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
-                     </tooltip>
-                    </CheckBox>
-                    <Button fx:id="markTimeStampHelp" prefWidth="20.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
-               </children>
-            </GridPane>
-         </children>
-      </HBox>
-      <HBox spacing="10.0" />
+                    </rowConstraints>
+                    <children>
+                        <Label text="%Date format" />
+                        <TextField fx:id="markTimeStampFormat" prefWidth="200.0" GridPane.columnIndex="2" />
+                        <Label text="%Field name" GridPane.rowIndex="1" />
+                        <TextField fx:id="markTimeStampFieldName" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
+                    </children>
+                </GridPane>
+            <HBox maxWidth="Infinity" HBox.hgrow="ALWAYS" />
+                <GridPane>
+                    <columnConstraints>
+                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
+                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
+                        <ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" prefWidth="20.0" />
+                    </columnConstraints>
+                    <rowConstraints>
+                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
+                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+                    </rowConstraints>
+                    <children>
+                        <CheckBox disable="${!markTimestamp.selected}" fx:id="markTimeStampOverwrite"  text="%Overwrite">
+                            <tooltip>
+                                <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+                            </tooltip>
+                        </CheckBox>
+                        <Button fx:id="markTimeStampHelp" prefWidth="20.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
+                    </children>
+                </GridPane>
+            </children>
+        </HBox>
+        <HBox spacing="10.0" />
         <CheckBox fx:id="updateTimeStamp" prefWidth="650.0" text="%Update timestamp on modification" />
-   </children>
+    </children>
 </fx:root>
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index 3da78bb6b96..6b32c013f6d 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -132,8 +132,10 @@ public void resetPreferences() {
         }
     }
 
+    /**
+     * Reloads the JabRefPreferences into the UI
+     */
     private void updateAfterPreferenceChanges() {
-
         setValues();
 
         List<TemplateExporter> customExporters = prefs.getCustomExportFormats(Globals.journalAbbreviationLoader);
@@ -144,16 +146,24 @@ private void updateAfterPreferenceChanges() {
         prefs.updateEntryEditorTabList();
     }
 
+    /**
+     * Checks if all tabs are ready to close and stores settings.
+     *
+     * ToDo:
+     * After conversion to MVVM, validation checks will be run by
+     * mvvmfx.utils.validation, so this needs to be removed.
+     */
     public void storeAllSettings() {
-        // First check that all tabs are ready to close:
+        // Run validation checks
         for (PrefsTab tab : preferenceTabs) {
             if (!tab.validateSettings()) {
                 return; // If not, break off.
             }
         }
-        // Then store settings and close:
+
+        // Store settings
         for (PrefsTab tab : preferenceTabs) {
-            tab.storeSettings();
+            tab.storeSettings(); // ToDo: After conversion of all tabs: prefsTab.getViewModel().storeSettings();
         }
         prefs.flush();
 
@@ -163,9 +173,12 @@ public void storeAllSettings() {
         dialogService.notify(Localization.lang("Preferences recorded."));
     }
 
+    /**
+     * Inserts the JabRefPreferences-values into the the Properties of the ViewModel
+     */
     public void setValues() {
         for (PrefsTab prefsTab : preferenceTabs) {
-            prefsTab.setValues();
+            prefsTab.setValues(); // ToDo: After conversion of all tabs: prefsTab.getViewModel().setValues();
         }
     }
 }
diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java
index 253b64cb8e4..39eb01599de 100644
--- a/src/main/java/org/jabref/preferences/JabRefPreferences.java
+++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java
@@ -2118,4 +2118,24 @@ public void setActivePushToApplication(PushToApplication application, PushToAppl
             manager.updateApplicationAction();
         }
     }
+
+    public NewLineSeparator getNewLineSeparator() {
+        String newline = get(JabRefPreferences.NEWLINE);
+        if ("\r".equals(newline)) {
+            return NewLineSeparator.CR;
+        } else if ("\n".equals(newline)) {
+            return NewLineSeparator.LF;
+        } else {
+            // fallback: windows standard
+            return NewLineSeparator.CRLF;
+        }
+    }
+
+    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/NewLineSeperator.java b/src/main/java/org/jabref/preferences/NewLineSeparator.java
similarity index 62%
rename from src/main/java/org/jabref/preferences/NewLineSeperator.java
rename to src/main/java/org/jabref/preferences/NewLineSeparator.java
index 9084b97cc91..9de216f7a70 100644
--- a/src/main/java/org/jabref/preferences/NewLineSeperator.java
+++ b/src/main/java/org/jabref/preferences/NewLineSeparator.java
@@ -1,6 +1,6 @@
 package org.jabref.preferences;
 
-public enum NewLineSeperator {
+public enum NewLineSeparator {
     CR,
     LF,
     CRLF;
@@ -10,10 +10,21 @@ public enum NewLineSeperator {
      * Possible are CR ("\n"), LF ("\r") and the windows standard CR/LF.
      */
 
+    public String toString() {
+        switch (this) {
+            case CR:
+                return "CR";
+            case LF:
+                return "LF";
+            default:
+                return "CR/LF";
+        }
+    }
+
     /**
      * @return the name of the current mode as String
      */
-    public String getEscapeSign() {
+    public String getEscapeChars() {
         switch (this) {
             case CR:
                 return "\r";
@@ -25,9 +36,9 @@ public String getEscapeSign() {
     }
 
     /**
-     * Returns the {@link NewLineSeperator} that equals the given string.
+     * Returns the {@link NewLineSeparator} that equals the given string.
      **/
-    public static NewLineSeperator parse(String data) {
+    public static NewLineSeparator parse(String data) {
         switch (data) {
             case "\r":
                 return CR;

From 64d6712e8a7058bdb4366dcce7fb31cc4437dc0e Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sat, 8 Jun 2019 17:57:47 +0200
Subject: [PATCH 14/22] Removed old FileTab

---
 .../org/jabref/gui/preferences/FileTab.java   | 274 ------------------
 1 file changed, 274 deletions(-)
 delete mode 100644 src/main/java/org/jabref/gui/preferences/FileTab.java

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<String> 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");
-    }
-
-}

From c91af3a970d310cf13fc9370776d48ad5b8dfc36 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sat, 8 Jun 2019 18:33:11 +0200
Subject: [PATCH 15/22] Fixed checkstyle

---
 src/main/java/org/jabref/gui/preferences/FileTab.fxml | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
index 32ea9e2c659..3b12ee7b542 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -10,6 +10,7 @@
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
 
+<?import javafx.scene.control.Tooltip?>
 <fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212"
          xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
     <fx:define>
@@ -31,7 +32,7 @@
         <HBox alignment="CENTER_LEFT" spacing="10.0">
             <children>
                 <RadioButton fx:id="resolveStringsAll" alignment="TOP_LEFT" maxWidth="Infinity"
-                             text="Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup"/>
+                             text="%Resolve strings for all fields except" toggleGroup="$stringsResolveToggleGroup"/>
                 <TextField fx:id="resolveStringsExcept" disable="${!resolveStringsAll.selected}" HBox.hgrow="ALWAYS"/>
             </children>
         </HBox>
@@ -51,7 +52,11 @@
                 <Button onAction="#mainFileDirBrowse" text="%Browse"/>
             </children>
         </HBox>
-        <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory"/>
+        <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory">
+            <tooltip>
+                <Tooltip text="%When downloading files, or moving linked files to the file directory, prefer the BIB file location rather than the file directory set above" />
+            </tooltip>
+        </CheckBox>
         <RadioButton fx:id="autolinkFileStartsBibtex" text="%Autolink files with names starting with the BibTeX key"
                      toggleGroup="$autolinkToggleGroup"/>
         <RadioButton fx:id="autolinkFileExactBibtex" text="%Autolink only files that match the BibTeX key"

From 414f00faf443163a78734076c246f59442447d79 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sun, 9 Jun 2019 20:38:13 +0200
Subject: [PATCH 16/22] Added Validators and some clean-ups

---
 .../org/jabref/gui/preferences/FileTab.fxml   |  16 +--
 .../jabref/gui/preferences/FileTabView.java   |   7 +-
 .../gui/preferences/FileTabViewModel.java     |  39 +++++--
 .../jabref/gui/preferences/GeneralTab.fxml    | 109 +++++++++---------
 .../gui/preferences/GeneralTabView.java       |  13 ++-
 .../gui/preferences/GeneralTabViewModel.java  |  45 ++++++--
 .../preferences/PreferenceTabViewModel.java   |   2 +-
 .../gui/preferences/PreferencesDialog.fxml    |  31 +++--
 .../preferences/PreferencesDialogView.java    |  35 ++++--
 .../PreferencesDialogViewModel.java           |  25 ++--
 .../jabref/preferences/NewLineSeparator.java  |   6 +-
 src/main/resources/l10n/JabRef_en.properties  |   1 -
 12 files changed, 203 insertions(+), 126 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.fxml b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
index 3b12ee7b542..3eec679c4f4 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.fxml
@@ -7,12 +7,13 @@
 <?import javafx.scene.control.RadioButton?>
 <?import javafx.scene.control.TextField?>
 <?import javafx.scene.control.ToggleGroup?>
+<?import javafx.scene.control.Tooltip?>
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
 
-<?import javafx.scene.control.Tooltip?>
-<fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212"
-         xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.FileTabView">
+<fx:root prefWidth="650.0" spacing="10.0" type="VBox"
+         xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1"
+         fx:controller="org.jabref.gui.preferences.FileTabView">
     <fx:define>
         <ToggleGroup fx:id="stringsResolveToggleGroup"/>
         <ToggleGroup fx:id="autolinkToggleGroup"/>
@@ -39,11 +40,10 @@
         <HBox alignment="CENTER_LEFT" spacing="10.0">
             <children>
                 <Label alignment="TOP_LEFT" text="%Newline separator"/>
-                <ComboBox fx:id="newLineSeparator" prefWidth="100.0"/>
+                <ComboBox fx:id="newLineSeparator" prefWidth="120.0"/>
             </children>
         </HBox>
         <CheckBox fx:id="alwaysReformatBib" text="%Always reformat BIB file on save and export"/>
-
         <Label styleClass="sectionHeader" text="%External file links"/>
         <HBox alignment="CENTER_LEFT" spacing="10.0">
             <children>
@@ -54,7 +54,8 @@
         </HBox>
         <CheckBox fx:id="useBibLocationAsPrimary" text="%Use the BIB file location as primary file directory">
             <tooltip>
-                <Tooltip text="%When downloading files, or moving linked files to the file directory, prefer the BIB file location rather than the file directory set above" />
+                <Tooltip
+                        text="%When downloading files, or moving linked files to the file directory, prefer the BIB file location rather than the file directory set above"/>
             </tooltip>
         </CheckBox>
         <RadioButton fx:id="autolinkFileStartsBibtex" text="%Autolink files with names starting with the BibTeX key"
@@ -73,10 +74,9 @@
                   text="%When opening file link, search for matching file if no link is defined"/>
         <CheckBox fx:id="openBrowseOnCreate" text="%Automatically open browse dialog when creating new file link"/>
         <Label styleClass="sectionHeader" text="%Autosave"/>
-        <HBox alignment="CENTER_LEFT">
+        <HBox alignment="CENTER_LEFT" spacing="10.0">
             <children>
                 <CheckBox fx:id="autosaveLocalLibraries" text="%Autosave local libraries"/>
-                <HBox HBox.hgrow="ALWAYS"/>
                 <Button fx:id="autosaveLocalLibrariesHelp"/>
             </children>
         </HBox>
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
index d27bfb54491..885e0c798db 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -54,8 +54,8 @@ public FileTabView(DialogService dialogService, JabRefPreferences preferences) {
         this.dialogService = dialogService;
         this.preferences = preferences;
         ViewLoader.view(this)
-                  .root(this)
-                  .load();
+                .root(this)
+                .load();
     }
 
     public void initialize() {
@@ -85,6 +85,8 @@ public void initialize() {
         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);
+
+        PreferencesDialogView.createValidationVisualization(viewModel.mainFileDirValidationStatus(), mainFileDir);
     }
 
     @Override
@@ -102,7 +104,6 @@ public void storeSettings() {
         viewModel.storeSettings();
     }
 
-    @Deprecated
     @Override
     public boolean validateSettings() {
         return viewModel.validateSettings();
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
index 2ebb35e93be..c97bc327c3a 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -22,6 +22,10 @@
 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 BooleanProperty openLastStartupProperty = new SimpleBooleanProperty();
@@ -45,6 +49,8 @@ public class FileTabViewModel implements PreferenceTabViewModel {
 
     private BooleanProperty autosaveLocalLibraries = new SimpleBooleanProperty();
 
+    private FunctionBasedValidator mainFileDirValidator;
+
     private final DialogService dialogService;
     private final JabRefPreferences preferences;
 
@@ -52,6 +58,21 @@ public FileTabViewModel(DialogService dialogService, JabRefPreferences preferenc
         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: %s",
+                        Localization.lang("File"),
+                        Localization.lang("External file links"),
+                        Localization.lang("Main file directory"),
+                        Localization.lang("Directory not found"),
+                        mainFileDirProperty.getValue())
+                )
+        );
     }
 
     public void setValues() {
@@ -106,22 +127,24 @@ public void storeSettings() {
         preferences.putBoolean(JabRefPreferences.LOCAL_AUTO_SAVE, autosaveLocalLibraries.getValue());
     }
 
+    ValidationStatus mainFileDirValidationStatus() {
+        return mainFileDirValidator.getValidationStatus();
+    }
+
     public boolean validateSettings() {
-        Path path = Paths.get(mainFileDirProperty.getValue());
-        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));
+        ValidationStatus status = mainFileDirValidationStatus();
+        if (!status.isValid()) {
+            dialogService.showErrorDialogAndWait(status.getHighestMessage().get().getMessage());
+            return false;
         }
-        return valid;
+        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()));
+                .ifPresent(f -> mainFileDirProperty.setValue(f.toString()));
     }
 
     // General
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
index 533031cbe53..63eb4929140 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.fxml
@@ -12,95 +12,92 @@
 <?import javafx.scene.layout.RowConstraints?>
 <?import javafx.scene.layout.VBox?>
 
-<fx:root spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.GeneralTabView">
+<fx:root prefWidth="650.0" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.212"
+         xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.GeneralTabView">
     <children>
-        <Label prefWidth="650.0" styleClass="sectionHeader" text="%General" />
+        <Label styleClass="sectionHeader" text="%General"/>
         <GridPane>
             <columnConstraints>
-                <ColumnConstraints hgrow="SOMETIMES" maxWidth="319.66668701171875" minWidth="10.0" prefWidth="197.0" />
-                <ColumnConstraints hgrow="SOMETIMES" maxWidth="466.33331298828125" minWidth="10.0" prefWidth="453.0" />
+                <ColumnConstraints hgrow="SOMETIMES" percentWidth="30.0"/>
+                <ColumnConstraints hgrow="SOMETIMES"/>
             </columnConstraints>
             <rowConstraints>
-                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
-                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
-                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES"/>
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
+                <RowConstraints minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES"/>
+                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
             </rowConstraints>
             <children>
-                <Label text="%Language" />
-                <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1" />
-                <Label text="%Default encoding" GridPane.rowIndex="2" />
-                <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
-                <Label text="%Default bibliography mode" GridPane.rowIndex="4" />
-                <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
+                <Label text="%Language"/>
+                <ComboBox fx:id="language" prefWidth="200.0" GridPane.columnIndex="1"/>
+                <Label text="%Default encoding" GridPane.rowIndex="2"/>
+                <ComboBox fx:id="defaultEncoding" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
+                <Label text="%Default bibliography mode" GridPane.rowIndex="4"/>
+                <ComboBox fx:id="biblatexMode" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
             </children>
         </GridPane>
-        <CheckBox fx:id="inspectionWarningDuplicate" text="%Warn about unresolved duplicates when closing inspection window" />
-        <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries" />
-        <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys" />
-        <CheckBox fx:id="memoryStickMode" text="%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)" />
-        <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef." />
-        <CheckBox fx:id="showAdvancedHints" text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)" />
+        <CheckBox fx:id="inspectionWarningDuplicate"
+                  text="%Warn about unresolved duplicates when closing inspection window"/>
+        <CheckBox fx:id="confirmDelete" text="%Show confirmation dialog when deleting entries"/>
+        <CheckBox fx:id="enforceLegalKeys" text="%Enforce legal characters in BibTeX keys"/>
+        <CheckBox fx:id="memoryStickMode"
+                  text="%Load and Save preferences from/to jabref.xml on start-up (memory stick mode)"/>
+        <CheckBox fx:id="collectTelemetry" text="%Collect and share telemetry data to help improve JabRef."/>
+        <CheckBox fx:id="showAdvancedHints"
+                  text="%Show advanced hints (i.e. helpful tooltips, suggestions and explanation)"/>
 
-        <Label styleClass="sectionHeader" text="%Entry owner" />
+        <Label styleClass="sectionHeader" text="%Entry owner"/>
         <HBox alignment="CENTER_LEFT" spacing="10.0">
             <children>
-                <CheckBox fx:id="markOwner" text="%Mark new entries with owner name" />
-                <TextField fx:id="markOwnerName" disable="${!markOwner.selected}" HBox.hgrow="ALWAYS" />
+                <CheckBox fx:id="markOwner" text="%Mark new entries with owner name"/>
+                <TextField fx:id="markOwnerName" disable="${!markOwner.selected}" HBox.hgrow="ALWAYS"/>
                 <CheckBox fx:id="markOwnerOverwrite" disable="${!markOwner.selected}" text="%Overwrite">
                     <tooltip>
-                        <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+                        <Tooltip text="%If a pasted or imported entry already has the field set, overwrite."/>
                     </tooltip>
                 </CheckBox>
-                <Button fx:id="markOwnerHelp" prefWidth="20.0" />
+                <Button fx:id="markOwnerHelp" prefWidth="20.0"/>
             </children>
         </HBox>
 
-        <Label styleClass="sectionHeader" text="%Time stamp" />
-        <CheckBox fx:id="markTimestamp" prefWidth="650.0" text="%Mark new entries with addition date" />
+        <Label styleClass="sectionHeader" text="%Time stamp"/>
+        <CheckBox fx:id="markTimestamp" text="%Mark new entries with addition date"/>
         <HBox spacing="10.0">
             <children>
-                <GridPane disable="${!markTimestamp.selected}">
-                    <columnConstraints>
-                        <ColumnConstraints hgrow="SOMETIMES" />
-                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
-                        <ColumnConstraints hgrow="SOMETIMES" />
-                    </columnConstraints>
-                    <rowConstraints>
-                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
-                  <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
-                    </rowConstraints>
-                    <children>
-                        <Label text="%Date format" />
-                        <TextField fx:id="markTimeStampFormat" prefWidth="200.0" GridPane.columnIndex="2" />
-                        <Label text="%Field name" GridPane.rowIndex="1" />
-                        <TextField fx:id="markTimeStampFieldName" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
-                    </children>
-                </GridPane>
-            <HBox maxWidth="Infinity" HBox.hgrow="ALWAYS" />
                 <GridPane>
                     <columnConstraints>
-                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
-                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
-                        <ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" prefWidth="20.0" />
+                        <ColumnConstraints hgrow="SOMETIMES"/>
+                        <ColumnConstraints hgrow="SOMETIMES" prefWidth="10.0"/>
+                        <ColumnConstraints hgrow="SOMETIMES"/>
+                        <ColumnConstraints hgrow="SOMETIMES" prefWidth="10.0"/>
+                        <ColumnConstraints hgrow="SOMETIMES"/>
+                        <ColumnConstraints hgrow="SOMETIMES" prefWidth="10.0"/>
+                        <ColumnConstraints hgrow="SOMETIMES"/>
                     </columnConstraints>
                     <rowConstraints>
-                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
-                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
+                        <RowConstraints prefHeight="10.0" vgrow="SOMETIMES"/>
+                        <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
                     </rowConstraints>
                     <children>
-                        <CheckBox disable="${!markTimestamp.selected}" fx:id="markTimeStampOverwrite"  text="%Overwrite">
+                        <Label disable="${!markTimestamp.selected}" text="%Date format"/>
+                        <TextField fx:id="markTimeStampFormat" disable="${!markTimestamp.selected}" prefWidth="200.0"
+                                   GridPane.columnIndex="2"/>
+                        <CheckBox fx:id="markTimeStampOverwrite" disable="${!markTimestamp.selected}" text="%Overwrite"
+                                  GridPane.columnIndex="4">
                             <tooltip>
-                                <Tooltip text="%If a pasted or imported entry already has the field set, overwrite." />
+                                <Tooltip text="%If a pasted or imported entry already has the field set, overwrite."/>
                             </tooltip>
                         </CheckBox>
-                        <Button fx:id="markTimeStampHelp" prefWidth="20.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
+                        <Button fx:id="markTimeStampHelp" prefWidth="20.0" GridPane.columnIndex="6"/>
+                        <Label disable="${!markTimestamp.selected}" text="%Field name" GridPane.rowIndex="2"/>
+                        <TextField fx:id="markTimeStampFieldName" disable="${!markTimestamp.selected}" prefWidth="200.0"
+                                   GridPane.columnIndex="2" GridPane.rowIndex="2"/>
                     </children>
                 </GridPane>
             </children>
         </HBox>
-        <HBox spacing="10.0" />
-        <CheckBox fx:id="updateTimeStamp" prefWidth="650.0" text="%Update timestamp on modification" />
+        <CheckBox fx:id="updateTimeStamp" text="%Update timestamp on modification"/>
     </children>
 </fx:root>
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
index 582dc4d0c25..9f2fbd913dc 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -50,12 +50,12 @@ public class GeneralTabView extends VBox implements PrefsTab {
 
     private GeneralTabViewModel viewModel;
 
-    public GeneralTabView (DialogService dialogService, JabRefPreferences preferences) {
+    public GeneralTabView(DialogService dialogService, JabRefPreferences preferences) {
         this.dialogService = dialogService;
         this.preferences = preferences;
         ViewLoader.view(this)
-                  .root(this)
-                  .load();
+                .root(this)
+                .load();
     }
 
     public void initialize() {
@@ -88,8 +88,10 @@ public void initialize() {
         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);
+        actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.OWNER), markOwnerHelp);
+        actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.TIMESTAMP), markTimeStampHelp);
+
+        PreferencesDialogView.createValidationVisualization(viewModel.markTimeStampFormatValidationStatus(), markTimeStampFormat);
     }
 
     @Override
@@ -107,7 +109,6 @@ public void storeSettings() {
         viewModel.storeSettings();
     }
 
-    @Deprecated
     @Override
     public boolean validateSettings() {
         return viewModel.validateSettings();
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
index 76fff2c1cf1..c8f9e27c6d7 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -15,7 +15,6 @@
 
 import org.jabref.gui.AbstractViewModel;
 import org.jabref.gui.DialogService;
-import org.jabref.gui.util.DefaultTaskExecutor;
 import org.jabref.logic.l10n.Encodings;
 import org.jabref.logic.l10n.Language;
 import org.jabref.logic.l10n.Localization;
@@ -23,6 +22,10 @@
 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 extends AbstractViewModel {
     private final ListProperty<Language> languagesListProperty = new SimpleListProperty<>();
     private final ObjectProperty<Language> selectedLanguageProperty = new SimpleObjectProperty<>();
@@ -46,13 +49,34 @@ public class GeneralTabViewModel extends AbstractViewModel {
     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) {
+    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: %s",
+                        Localization.lang("General"),
+                        Localization.lang("Time stamp"),
+                        Localization.lang("Date format"),
+                        Localization.lang("Invalid date format"),
+                        markTimeStampFormatProperty.getValue())
+                )
+        );
     }
 
     private void setValues() {
@@ -94,8 +118,8 @@ public void storeSettings() {
 
             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.")));
+                            .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);
@@ -126,13 +150,14 @@ public void storeSettings() {
         InternalBibtexFields.updateTimeStampField(preferences.get(JabRefPreferences.TIME_STAMP_FIELD));
     }
 
+    public ValidationStatus markTimeStampFormatValidationStatus() {
+        return markTimeStampFormatValidator.getValidationStatus();
+    }
+
     public boolean validateSettings() {
-        try {
-            // Test if date format is legal:
-            DateTimeFormatter.ofPattern(markTimeStampFormatProperty.getValue());
-        } catch (IllegalArgumentException exception) {
-            DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showErrorDialogAndWait(Localization.lang("Invalid date format"),
-                    Localization.lang("The chosen date format for new entries is not valid")));
+        ValidationStatus status = markTimeStampFormatValidationStatus();
+        if (!status.isValid()) {
+            dialogService.showErrorDialogAndWait(status.getHighestMessage().get().getMessage());
             return false;
         }
         return true;
diff --git a/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
index 1d8d7f87e6e..b3396fe2eec 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferenceTabViewModel.java
@@ -6,5 +6,5 @@ public interface PreferenceTabViewModel {
 
     void storeSettings();
 
-    boolean validateSettings(); // ToDo: Remove this after implementation of MVVMFX Validator
+    boolean validateSettings();
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
index db350db3111..7a90f13ef60 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml
@@ -12,7 +12,9 @@
 
 <?import org.controlsfx.control.textfield.CustomTextField?>
 
-<DialogPane prefHeight="700.0" prefWidth="1100.0" minHeight="400" minWidth="600" xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jabref.gui.preferences.PreferencesDialogView">
+<DialogPane prefHeight="700.0" prefWidth="1100.0" minHeight="400" minWidth="600"
+            xmlns="http://javafx.com/javafx/8.0.212" xmlns:fx="http://javafx.com/fxml/1"
+            fx:controller="org.jabref.gui.preferences.PreferencesDialogView">
     <content>
         <SplitPane dividerPositions="0.2">
             <items>
@@ -20,34 +22,39 @@
                     <children>
                         <CustomTextField fx:id="searchBox" promptText="%Search" VBox.vgrow="NEVER">
                             <VBox.margin>
-                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
+                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0"/>
                             </VBox.margin>
                         </CustomTextField>
-                        <ListView fx:id="preferenceTabList" VBox.vgrow="ALWAYS" />
-                        <VBox prefHeight="10.0" VBox.vgrow="SOMETIMES" />
+                        <ListView fx:id="preferenceTabList" VBox.vgrow="ALWAYS"/>
+                        <VBox prefHeight="10.0" VBox.vgrow="SOMETIMES"/>
                         <VBox alignment="BOTTOM_LEFT" spacing="3.0">
                             <children>
                                 <Button maxWidth="Infinity" onAction="#importPreferences" text="%Import preferences">
-                                    <tooltip><Tooltip text="%Import preferences from file" /></tooltip>
+                                    <tooltip>
+                                        <Tooltip text="%Import preferences from file"/>
+                                    </tooltip>
                                 </Button>
                                 <Button maxWidth="Infinity" onAction="#exportPreferences" text="%Export preferences">
-                                    <tooltip><Tooltip text="%Export preferences to file" /></tooltip>
+                                    <tooltip>
+                                        <Tooltip text="%Export preferences to file"/>
+                                    </tooltip>
                                 </Button>
-                                <Button maxWidth="Infinity" onAction="#showAllPreferences" text="%Show preferences" />
-                                <Button maxWidth="Infinity" onAction="#resetPreferences" text="%Reset preferences" />
+                                <Button maxWidth="Infinity" onAction="#showAllPreferences" text="%Show preferences"/>
+                                <Button maxWidth="Infinity" onAction="#resetPreferences" text="%Reset preferences"/>
                             </children>
                             <padding>
-                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
+                                <Insets bottom="3.0" left="3.0" right="3.0" top="3.0"/>
                             </padding>
                         </VBox>
                     </children>
                 </VBox>
-                <ScrollPane fx:id="preferencePaneContainer" styleClass="preferencePaneContainer" maxHeight="Infinity" maxWidth="Infinity" />
+                <ScrollPane fx:id="preferencePaneContainer" styleClass="preferencePaneContainer" maxHeight="Infinity"
+                            maxWidth="Infinity"/>
             </items>
         </SplitPane>
     </content>
     <buttonTypes>
-        <ButtonType fx:id="saveButton" text="%Save" buttonData="OK_DONE" />
-        <ButtonType fx:constant="CANCEL" />
+        <ButtonType fx:id="saveButton" text="%Save" buttonData="OK_DONE"/>
+        <ButtonType fx:constant="CANCEL"/>
     </buttonTypes>
 </DialogPane>
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
index e2ef91cc738..4cc6c971dd5 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -6,6 +6,7 @@
 
 import javafx.fxml.FXML;
 import javafx.scene.control.ButtonType;
+import javafx.scene.control.Control;
 import javafx.scene.control.ListView;
 import javafx.scene.control.ScrollPane;
 
@@ -14,12 +15,14 @@
 import org.jabref.gui.icon.IconTheme;
 import org.jabref.gui.util.BaseDialog;
 import org.jabref.gui.util.ControlHelper;
+import org.jabref.gui.util.IconValidationDecorator;
 import org.jabref.gui.util.TaskExecutor;
 import org.jabref.gui.util.ViewModelListCellFactory;
 import org.jabref.logic.l10n.Localization;
-import org.jabref.preferences.PreferencesService;
 
 import com.airhacks.afterburner.views.ViewLoader;
+import de.saxsys.mvvmfx.utils.validation.ValidationStatus;
+import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
 import org.controlsfx.control.textfield.CustomTextField;
 import org.fxmisc.easybind.EasyBind;
 
@@ -35,7 +38,6 @@ public class PreferencesDialogView extends BaseDialog<PreferencesDialogViewModel
     @FXML private ButtonType saveButton;
 
     @Inject private DialogService dialogService;
-    @Inject private PreferencesService preferences;
 
     private JabRefFrame frame;
     private TaskExecutor taskExecutor;
@@ -47,16 +49,21 @@ public PreferencesDialogView(JabRefFrame frame, TaskExecutor taskExecutor) {
         this.setTitle(Localization.lang("JabRef preferences"));
 
         ViewLoader.view(this)
-                  .load()
-                  .setAsDialogPane(this);
+                .load()
+                .setAsDialogPane(this);
 
         ControlHelper.setAction(saveButton, getDialogPane(), event -> savePreferencesAndCloseDialog());
+
+        // ToDo: After conversion of all tabs to mvvm, make validSettings bindable
+        // ControlHelper.getButton(saveButton, getDialogPane()).disableProperty().bind(viewModel.validSettings().not());
     }
 
-    public PreferencesDialogViewModel getViewModel() { return viewModel; }
+    public PreferencesDialogViewModel getViewModel() {
+        return viewModel;
+    }
 
     @FXML
-    private void initialize () {
+    private void initialize() {
         viewModel = new PreferencesDialogViewModel(dialogService, taskExecutor, frame);
 
         preferenceTabList.itemsProperty().setValue(viewModel.getPreferenceTabs());
@@ -88,12 +95,16 @@ private void initialize () {
     }
 
     @FXML
-    private void closeDialog() { close(); }
+    private void closeDialog() {
+        close();
+    }
 
     @FXML
     private void savePreferencesAndCloseDialog() {
-        viewModel.storeAllSettings();
-        closeDialog();
+        if (viewModel.validSettings()) {
+            viewModel.storeAllSettings();
+            closeDialog();
+        }
     }
 
     @FXML
@@ -115,4 +126,10 @@ void showAllPreferences() {
     void resetPreferences() {
         viewModel.resetPreferences();
     }
+
+    public static void createValidationVisualization(final ValidationStatus status, final Control control) {
+        ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+        validationVisualizer.initVisualization(status, control);
+        validationVisualizer.setDecoration(new IconValidationDecorator());
+    }
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index 6b32c013f6d..0513d7ccfae 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -49,7 +49,7 @@ public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor task
         preferenceTabs.add(new FileTabView(dialogService, prefs));
         preferenceTabs.add(new TablePrefsTab(prefs));
         preferenceTabs.add(new TableColumnsTab(prefs, frame));
-        preferenceTabs.add(new PreviewPreferencesTab(dialogService, taskExecutor));
+        preferenceTabs.add(new PreviewPreferencesTab(dialogService, this.taskExecutor));
         preferenceTabs.add(new ExternalTab(frame, prefs));
         preferenceTabs.add(new GroupsPrefsTab(prefs));
         preferenceTabs.add(new EntryEditorPrefsTab(prefs));
@@ -147,19 +147,25 @@ private void updateAfterPreferenceChanges() {
     }
 
     /**
-     * Checks if all tabs are ready to close and stores settings.
-     *
-     * ToDo:
-     * After conversion to MVVM, validation checks will be run by
-     * mvvmfx.utils.validation, so this needs to be removed.
+     * 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 void storeAllSettings() {
-        // Run validation checks
+
+    public boolean validSettings() {
         for (PrefsTab tab : preferenceTabs) {
             if (!tab.validateSettings()) {
-                return; // If not, break off.
+                return false;
             }
         }
+        return true;
+    }
+
+    public void storeAllSettings() {
+        // Run validation checks
+        if (!validSettings()) {
+            return;
+        }
 
         // Store settings
         for (PrefsTab tab : preferenceTabs) {
@@ -175,6 +181,7 @@ public void storeAllSettings() {
 
     /**
      * 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) {
diff --git a/src/main/java/org/jabref/preferences/NewLineSeparator.java b/src/main/java/org/jabref/preferences/NewLineSeparator.java
index 9de216f7a70..c300c7d3680 100644
--- a/src/main/java/org/jabref/preferences/NewLineSeparator.java
+++ b/src/main/java/org/jabref/preferences/NewLineSeparator.java
@@ -13,11 +13,11 @@ public enum NewLineSeparator {
     public String toString() {
         switch (this) {
             case CR:
-                return "CR";
+                return "CR ( \\r )";
             case LF:
-                return "LF";
+                return "LF ( \\n )";
             default:
-                return "CR/LF";
+                return "CR/LF ( \\r\\n )";
         }
     }
 
diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties
index c3c8ed1fc31..11aaee5c846 100644
--- a/src/main/resources/l10n/JabRef_en.properties
+++ b/src/main/resources/l10n/JabRef_en.properties
@@ -894,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:
 

From a12a7c788c53d7c429b48be31100bc6824a55c82 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sun, 9 Jun 2019 22:18:58 +0200
Subject: [PATCH 17/22] Refactor minor corrections

---
 .../org/jabref/gui/preferences/FileTabView.java   |  8 +++++++-
 .../jabref/gui/preferences/FileTabViewModel.java  |  6 +++---
 .../jabref/gui/preferences/GeneralTabView.java    |  8 +++++++-
 .../gui/preferences/GeneralTabViewModel.java      |  6 +++---
 .../gui/preferences/PreferencesDialogView.java    | 15 +++------------
 .../java/org/jabref/gui/preferences/PrefsTab.java |  6 +++---
 6 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
index 885e0c798db..d0a72ce59cd 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -1,5 +1,6 @@
 package org.jabref.gui.preferences;
 
+import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
 import javafx.scene.control.Button;
@@ -14,12 +15,14 @@
 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 {
 
@@ -50,6 +53,8 @@ public class FileTabView extends VBox implements PrefsTab {
 
     private FileTabViewModel viewModel;
 
+    private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+
     public FileTabView(DialogService dialogService, JabRefPreferences preferences) {
         this.dialogService = dialogService;
         this.preferences = preferences;
@@ -86,7 +91,8 @@ public void initialize() {
         actionFactory.configureIconButton(StandardActions.HELP_REGEX_SEARCH, new HelpAction(HelpFile.REGEX_SEARCH), autolinkRegexHelp);
         actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.AUTOSAVE), autosaveLocalLibrariesHelp);
 
-        PreferencesDialogView.createValidationVisualization(viewModel.mainFileDirValidationStatus(), mainFileDir);
+        validationVisualizer.setDecoration(new IconValidationDecorator());
+        Platform.runLater(() -> validationVisualizer.initVisualization(viewModel.mainFileDirValidationStatus(), mainFileDir));
     }
 
     @Override
diff --git a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
index c97bc327c3a..18dcef5e629 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -65,12 +65,12 @@ public FileTabViewModel(DialogService dialogService, JabRefPreferences preferenc
                     Path path = Paths.get(mainFileDirProperty.getValue());
                     return (Files.exists(path) && Files.isDirectory(path));
                 },
-                ValidationMessage.error(String.format("%s > %s > %s %n %n %s: %s",
+                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"),
-                        mainFileDirProperty.getValue())
+                        Localization.lang("Directory not found")
+                        )
                 )
         );
     }
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
index 9f2fbd913dc..bd3ccf24427 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -2,6 +2,7 @@
 
 import java.nio.charset.Charset;
 
+import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
 import javafx.scene.control.Button;
@@ -15,6 +16,7 @@
 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;
@@ -22,6 +24,7 @@
 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 {
 
@@ -50,6 +53,8 @@ public class GeneralTabView extends VBox implements PrefsTab {
 
     private GeneralTabViewModel viewModel;
 
+    private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
+
     public GeneralTabView(DialogService dialogService, JabRefPreferences preferences) {
         this.dialogService = dialogService;
         this.preferences = preferences;
@@ -91,7 +96,8 @@ public void initialize() {
         actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.OWNER), markOwnerHelp);
         actionFactory.configureIconButton(StandardActions.HELP, new HelpAction(HelpFile.TIMESTAMP), markTimeStampHelp);
 
-        PreferencesDialogView.createValidationVisualization(viewModel.markTimeStampFormatValidationStatus(), markTimeStampFormat);
+        validationVisualizer.setDecoration(new IconValidationDecorator());
+        Platform.runLater(() -> validationVisualizer.initVisualization(viewModel.markTimeStampFormatValidationStatus(), markTimeStampFormat));
     }
 
     @Override
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
index c8f9e27c6d7..b42d1f18e2b 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -69,12 +69,12 @@ public GeneralTabViewModel(DialogService dialogService, JabRefPreferences prefer
                     }
                     return true;
                 },
-                ValidationMessage.error(String.format("%s > %s > %s %n %n %s: %s",
+                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"),
-                        markTimeStampFormatProperty.getValue())
+                        Localization.lang("Invalid date format")
+                        )
                 )
         );
     }
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
index 4cc6c971dd5..7fb30a48067 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogView.java
@@ -6,7 +6,6 @@
 
 import javafx.fxml.FXML;
 import javafx.scene.control.ButtonType;
-import javafx.scene.control.Control;
 import javafx.scene.control.ListView;
 import javafx.scene.control.ScrollPane;
 
@@ -15,14 +14,11 @@
 import org.jabref.gui.icon.IconTheme;
 import org.jabref.gui.util.BaseDialog;
 import org.jabref.gui.util.ControlHelper;
-import org.jabref.gui.util.IconValidationDecorator;
 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 de.saxsys.mvvmfx.utils.validation.ValidationStatus;
-import de.saxsys.mvvmfx.utils.validation.visualization.ControlsFxVisualizer;
 import org.controlsfx.control.textfield.CustomTextField;
 import org.fxmisc.easybind.EasyBind;
 
@@ -54,8 +50,9 @@ public PreferencesDialogView(JabRefFrame frame, TaskExecutor taskExecutor) {
 
         ControlHelper.setAction(saveButton, getDialogPane(), event -> savePreferencesAndCloseDialog());
 
-        // ToDo: After conversion of all tabs to mvvm, make validSettings bindable
-        // ControlHelper.getButton(saveButton, getDialogPane()).disableProperty().bind(viewModel.validSettings().not());
+        // 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() {
@@ -126,10 +123,4 @@ void showAllPreferences() {
     void resetPreferences() {
         viewModel.resetPreferences();
     }
-
-    public static void createValidationVisualization(final ValidationStatus status, final Control control) {
-        ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
-        validationVisualizer.initVisualization(status, control);
-        validationVisualizer.setDecoration(new IconValidationDecorator());
-    }
 }
diff --git a/src/main/java/org/jabref/gui/preferences/PrefsTab.java b/src/main/java/org/jabref/gui/preferences/PrefsTab.java
index 56c8f1149cc..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(); // ToDo: Remove this after conversion of all tabs
+    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(); // ToDo: Call directly in ViewModel after conversion of all tabs
+    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(); // ToDo: Call directly in ViewModel after conversion of all tabs
+    boolean validateSettings(); // ToDo: After conversion of all tabs: viewModel.validateSettings()
 
     /**
      * Should return the localized identifier to use for the tab.

From ee1387d896fd761c0ff683badd2eabf70ecdba23 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Sun, 9 Jun 2019 23:35:05 +0200
Subject: [PATCH 18/22] Refactor final

---
 .../gui/preferences/FileTabViewModel.java     | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
index 18dcef5e629..56266c8fb20 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabViewModel.java
@@ -28,28 +28,28 @@
 
 public class FileTabViewModel implements PreferenceTabViewModel {
 
-    private BooleanProperty openLastStartupProperty = new SimpleBooleanProperty();
-    private BooleanProperty backupOldFileProperty = new SimpleBooleanProperty();
-    private StringProperty noWrapFilesProperty = new SimpleStringProperty("");
-    private BooleanProperty resolveStringsBibTexProperty = new SimpleBooleanProperty();
-    private BooleanProperty resolveStringsAllProperty = new SimpleBooleanProperty();
-    private StringProperty resolveStringsExceptProperty = new SimpleStringProperty("");
+    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<NewLineSeparator> newLineSeparatorListProperty = new SimpleListProperty<>();
     private final ObjectProperty<NewLineSeparator> selectedNewLineSeparatorProperty = new SimpleObjectProperty<>();
-    private BooleanProperty alwaysReformatBibProperty = new SimpleBooleanProperty();
+    private final BooleanProperty alwaysReformatBibProperty = new SimpleBooleanProperty();
 
-    private StringProperty mainFileDirProperty = new SimpleStringProperty("");
-    private BooleanProperty useBibLocationAsPrimaryProperty = new SimpleBooleanProperty();
-    private BooleanProperty autolinkFileStartsBibtexProperty = new SimpleBooleanProperty();
-    private BooleanProperty autolinkFileExactBibtexProperty = new SimpleBooleanProperty();
-    private BooleanProperty autolinkUseRegexProperty = new SimpleBooleanProperty();
-    private StringProperty autolinkRegexKeyProperty = new SimpleStringProperty("");
-    private BooleanProperty searchFilesOnOpenProperty = new SimpleBooleanProperty();
-    private BooleanProperty openBrowseOnCreateProperty = 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 BooleanProperty autosaveLocalLibraries = new SimpleBooleanProperty();
+    private final BooleanProperty autosaveLocalLibraries = new SimpleBooleanProperty();
 
-    private FunctionBasedValidator mainFileDirValidator;
+    private final FunctionBasedValidator mainFileDirValidator;
 
     private final DialogService dialogService;
     private final JabRefPreferences preferences;

From 3570c9eda3e19236602b8d69bebcbf56927c446d Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Wed, 12 Jun 2019 11:06:32 +0200
Subject: [PATCH 19/22] Refactor

---
 .../java/org/jabref/preferences/JabRefPreferences.java | 10 +---------
 .../java/org/jabref/preferences/NewLineSeparator.java  |  6 +++---
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java
index 39eb01599de..e002caa979b 100644
--- a/src/main/java/org/jabref/preferences/JabRefPreferences.java
+++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java
@@ -2120,15 +2120,7 @@ public void setActivePushToApplication(PushToApplication application, PushToAppl
     }
 
     public NewLineSeparator getNewLineSeparator() {
-        String newline = get(JabRefPreferences.NEWLINE);
-        if ("\r".equals(newline)) {
-            return NewLineSeparator.CR;
-        } else if ("\n".equals(newline)) {
-            return NewLineSeparator.LF;
-        } else {
-            // fallback: windows standard
-            return NewLineSeparator.CRLF;
-        }
+        return NewLineSeparator.parse(get(JabRefPreferences.NEWLINE));
     }
 
     public void setNewLineSeparator(NewLineSeparator newLineSeparator) {
diff --git a/src/main/java/org/jabref/preferences/NewLineSeparator.java b/src/main/java/org/jabref/preferences/NewLineSeparator.java
index c300c7d3680..975bdcd88fc 100644
--- a/src/main/java/org/jabref/preferences/NewLineSeparator.java
+++ b/src/main/java/org/jabref/preferences/NewLineSeparator.java
@@ -13,11 +13,11 @@ public enum NewLineSeparator {
     public String toString() {
         switch (this) {
             case CR:
-                return "CR ( \\r )";
+                return "CR (\"\\r\")";
             case LF:
-                return "LF ( \\n )";
+                return "LF (\"\\n\")";
             default:
-                return "CR/LF ( \\r\\n )";
+                return "CR/LF (\"\\r\\n\")";
         }
     }
 

From 4fd959d6427484f1544cb612e23b9d578ec3847c Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Fri, 14 Jun 2019 16:03:18 +0200
Subject: [PATCH 20/22] Added Injection of dialogService

---
 src/main/java/org/jabref/gui/preferences/FileTabView.java  | 7 ++++---
 .../java/org/jabref/gui/preferences/GeneralTabView.java    | 7 ++++---
 .../jabref/gui/preferences/PreferencesDialogViewModel.java | 4 ++--
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/FileTabView.java b/src/main/java/org/jabref/gui/preferences/FileTabView.java
index d0a72ce59cd..c980e561518 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTabView.java
@@ -1,5 +1,7 @@
 package org.jabref.gui.preferences;
 
+import javax.inject.Inject;
+
 import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
@@ -48,15 +50,14 @@ public class FileTabView extends VBox implements PrefsTab {
     @FXML private CheckBox autosaveLocalLibraries;
     @FXML private Button autosaveLocalLibrariesHelp;
 
-    private final DialogService dialogService;
+    @Inject private DialogService dialogService;
     private final JabRefPreferences preferences;
 
     private FileTabViewModel viewModel;
 
     private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
 
-    public FileTabView(DialogService dialogService, JabRefPreferences preferences) {
-        this.dialogService = dialogService;
+    public FileTabView(JabRefPreferences preferences) {
         this.preferences = preferences;
         ViewLoader.view(this)
                 .root(this)
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
index bd3ccf24427..3138230d7cd 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabView.java
@@ -2,6 +2,8 @@
 
 import java.nio.charset.Charset;
 
+import javax.inject.Inject;
+
 import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
@@ -48,15 +50,14 @@ public class GeneralTabView extends VBox implements PrefsTab {
     @FXML private Button markTimeStampHelp;
     @FXML private CheckBox updateTimeStamp;
 
-    private final DialogService dialogService;
+    @Inject private DialogService dialogService;
     private final JabRefPreferences preferences;
 
     private GeneralTabViewModel viewModel;
 
     private ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer();
 
-    public GeneralTabView(DialogService dialogService, JabRefPreferences preferences) {
-        this.dialogService = dialogService;
+    public GeneralTabView(JabRefPreferences preferences) {
         this.preferences = preferences;
         ViewLoader.view(this)
                 .root(this)
diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
index 0513d7ccfae..2e62aed97be 100644
--- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java
@@ -45,8 +45,8 @@ public PreferencesDialogViewModel(DialogService dialogService, TaskExecutor task
         this.frame = frame;
 
         preferenceTabs = FXCollections.observableArrayList();
-        preferenceTabs.add(new GeneralTabView(dialogService, prefs));
-        preferenceTabs.add(new FileTabView(dialogService, prefs));
+        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));

From 6e2e445a730a3f5fc9a7a1cbe4f2c5d73b5aeabe Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Fri, 14 Jun 2019 16:17:44 +0200
Subject: [PATCH 21/22] Fixed two glitches

---
 .../org/jabref/gui/preferences/GeneralTabViewModel.java     | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
index b42d1f18e2b..03ee74d1b0f 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -26,7 +26,7 @@
 import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
 import de.saxsys.mvvmfx.utils.validation.ValidationStatus;
 
-public class GeneralTabViewModel extends AbstractViewModel {
+public class GeneralTabViewModel implements PreferenceTabViewModel {
     private final ListProperty<Language> languagesListProperty = new SimpleListProperty<>();
     private final ObjectProperty<Language> selectedLanguageProperty = new SimpleObjectProperty<>();
     private final ListProperty<Charset> encodingsListProperty = new SimpleListProperty<>();
@@ -79,7 +79,7 @@ public GeneralTabViewModel(DialogService dialogService, JabRefPreferences prefer
         );
     }
 
-    private void setValues() {
+    public void setValues() {
         languagesListProperty.setValue(FXCollections.observableArrayList(Language.values()));
         selectedLanguageProperty.setValue(preferences.getLanguage());
 
@@ -136,7 +136,7 @@ public void storeSettings() {
         preferences.setShouldCollectTelemetry(collectTelemetryProperty.getValue());
         preferences.putBoolean(JabRefPreferences.SHOW_ADVANCED_HINTS, showAdvancedHintsProperty.getValue());
 
-        preferences.putBoolean(JabRefPreferences.USE_OWNER, markOwnerOverwriteProperty.getValue());
+        preferences.putBoolean(JabRefPreferences.USE_OWNER, markOwnerProperty.getValue());
         preferences.put(JabRefPreferences.DEFAULT_OWNER, markOwnerNameProperty.getValue().trim());
         preferences.putBoolean(JabRefPreferences.OVERWRITE_OWNER, markOwnerOverwriteProperty.getValue());
 

From 9776df23c5c155643929bd55ed3dcba5fca5e555 Mon Sep 17 00:00:00 2001
From: Carl Christian Snethlage <cc.snethlage@gmail.com>
Date: Fri, 14 Jun 2019 16:52:32 +0200
Subject: [PATCH 22/22] Removed unused import

---
 .../java/org/jabref/gui/preferences/GeneralTabViewModel.java     | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
index 03ee74d1b0f..4b801f54ee3 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTabViewModel.java
@@ -13,7 +13,6 @@
 import javafx.beans.property.StringProperty;
 import javafx.collections.FXCollections;
 
-import org.jabref.gui.AbstractViewModel;
 import org.jabref.gui.DialogService;
 import org.jabref.logic.l10n.Encodings;
 import org.jabref.logic.l10n.Language;