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;