From 90b21f5fba0a8865b74144b4c0610db1e73b65c3 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Thu, 25 Oct 2018 22:32:48 -0500 Subject: [PATCH] Add a preference to add files in entry editor (#4356) --- AUTHORS | 1 + CHANGELOG.md | 2 +- .../jabref/gui/entryeditor/EntryEditor.java | 11 ++- .../entryeditor/FileDragDropPreferences.java | 39 ++++++++ .../gui/fieldeditors/LinkedFilesEditor.java | 94 +------------------ .../gui/preferences/EntryEditorPrefsTab.java | 48 ++++++++++ .../jabref/preferences/JabRefPreferences.java | 23 +++++ src/main/resources/l10n/JabRef_en.properties | 5 + 8 files changed, 124 insertions(+), 99 deletions(-) create mode 100644 src/main/java/org/jabref/gui/entryeditor/FileDragDropPreferences.java diff --git a/AUTHORS b/AUTHORS index 04adf86cb9df..05f6f4111da4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,6 +13,7 @@ Alexsandro Lauber Ali Ayan Alick Zhao Ambrogio Oliva +Amish Shah Andreas Amann Andreas Buhr Andreas Rudert diff --git a/CHANGELOG.md b/CHANGELOG.md index adc97d7c5074..77bfad199c6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We added a minimal height for the entry editor so that it can no longer be hidden by accident. [#4279](https://github.com/JabRef/jabref/issues/4279) - We added a new keyboard shortcut so that the entry editor could be closed by Ctrl + E. [#4222] (https://github.com/JabRef/jabref/issues/4222) - We added an option in the preference dialog box, that allows user to pick the dark or light theme option. [#4130] (https://github.com/JabRef/jabref/issues/4130) - +- Allow the user to choose behavior after dragging and dropping files in Entry Editor using Preferences. [#4356] diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 75070434db06..9dfafce63306 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -144,18 +144,19 @@ public EntryEditor(BasePanel panel, EntryEditorPreferences preferences, FileUpda if (event.getDragboard().hasContent(DataFormat.FILES)) { List files = event.getDragboard().getFiles().stream().map(File::toPath).collect(Collectors.toList()); - if (event.getTransferMode() == TransferMode.MOVE) { + FileDragDropPreferences dragDropPreferences = Globals.prefs.getEntryEditorFileLinkPreference(); + if (dragDropPreferences.isRenameCopyFile()) { LOGGER.debug("Mode MOVE"); //shift on win or no modifier fileHandler.addToEntryRenameAndMoveToFileDir(entry, files); } - if (event.getTransferMode() == TransferMode.LINK) { - LOGGER.debug("Node LINK"); //alt on win + if (dragDropPreferences.isLinkFile()) { + LOGGER.debug("Mode LINK"); //alt on win fileHandler.addToEntry(entry, files); } - if (event.getTransferMode() == TransferMode.COPY) { - LOGGER.debug("Mode Copy"); //ctrl on win, no modifier on Xubuntu + if (dragDropPreferences.isCopyFile()) { + LOGGER.debug("Mode COPY"); //ctrl on win, no modifier on Xubuntu fileHandler.copyFilesToFileDirAndAddToEntry(entry, files); } } diff --git a/src/main/java/org/jabref/gui/entryeditor/FileDragDropPreferences.java b/src/main/java/org/jabref/gui/entryeditor/FileDragDropPreferences.java new file mode 100644 index 000000000000..37616db82bfa --- /dev/null +++ b/src/main/java/org/jabref/gui/entryeditor/FileDragDropPreferences.java @@ -0,0 +1,39 @@ +package org.jabref.gui.entryeditor; + +public class FileDragDropPreferences { + + private boolean copyFile; + private boolean linkFile; + private boolean renameCopyFile; + + public FileDragDropPreferences(boolean copyFile, boolean linkFile, boolean renameCopyFile) { + this.copyFile = copyFile; + this.linkFile = linkFile; + this.renameCopyFile = renameCopyFile; + } + + public boolean isCopyFile() { + return copyFile; + } + + public boolean isLinkFile() { + return linkFile; + } + + public boolean isRenameCopyFile() { + return renameCopyFile; + } + + public void setCopyFile(boolean copyFile) { + this.copyFile = copyFile; + } + + public void setLinkFile(boolean linkFile) { + this.linkFile = linkFile; + } + + public void setRenameCopyFile(boolean renameCopyFile) { + this.renameCopyFile = renameCopyFile; + } + +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java index 8c4a94d3517c..965e087609e7 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java @@ -1,12 +1,7 @@ package org.jabref.gui.fieldeditors; -import java.io.File; -import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; - import javafx.beans.binding.Bindings; -import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Node; @@ -18,19 +13,14 @@ import javafx.scene.control.ProgressBar; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.Tooltip; -import javafx.scene.input.ClipboardContent; -import javafx.scene.input.DragEvent; -import javafx.scene.input.Dragboard; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; -import javafx.scene.input.TransferMode; import javafx.scene.layout.HBox; import javafx.scene.text.Text; import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.DragAndDropDataFormats; import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.util.TaskExecutor; @@ -39,7 +29,6 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.LinkedFile; import org.jabref.preferences.JabRefPreferences; import com.airhacks.afterburner.views.ViewLoader; @@ -64,95 +53,14 @@ public LinkedFilesEditor(String fieldName, DialogService dialogService, BibDatab .withTooltip(LinkedFileViewModel::getDescription) .withGraphic(LinkedFilesEditor::createFileDisplay) .withContextMenu(this::createContextMenuForFile) - .withOnMouseClickedEvent(this::handleItemMouseClick) - .setOnDragDetected(this::handleOnDragDetected) - .setOnDragDropped(this::handleOnDragDropped) - .setOnDragOver(this::handleOnDragOver); + .withOnMouseClickedEvent(this::handleItemMouseClick); listView.setCellFactory(cellFactory); - setUpFilesDragAndDrop(); Bindings.bindContentBidirectional(listView.itemsProperty().get(), viewModel.filesProperty()); setUpKeyBindings(); } - private void setUpFilesDragAndDrop() { - listView.setOnDragOver(event -> { - if (event.getDragboard().hasFiles()) { - event.acceptTransferModes(TransferMode.COPY, TransferMode.LINK); - } - }); - - listView.setOnDragDropped(event -> { - Dragboard dragboard = event.getDragboard(); - boolean success = false; - ObservableList items = listView.itemsProperty().get(); - - if (dragboard.hasFiles()) { - List linkedFiles = dragboard.getFiles().stream().map(File::toPath).map(viewModel::fromFile).collect(Collectors.toList()); - items.addAll(linkedFiles); - success = true; - } - event.setDropCompleted(success); - event.consume(); - }); - - } - - private void handleOnDragOver(LinkedFileViewModel originalItem, DragEvent event) { - if ((event.getGestureSource() != originalItem) && event.getDragboard().hasContent(DragAndDropDataFormats.LINKED_FILE)) { - event.acceptTransferModes(TransferMode.MOVE); - } - if (event.getDragboard().hasFiles()) { - event.acceptTransferModes(TransferMode.COPY, TransferMode.LINK); - } - } - - private void handleOnDragDetected(@SuppressWarnings("unused") LinkedFileViewModel linkedFile, MouseEvent event) { - LinkedFile selectedItem = listView.getSelectionModel().getSelectedItem().getFile(); - if (selectedItem != null) { - ClipboardContent content = new ClipboardContent(); - Dragboard dragboard = listView.startDragAndDrop(TransferMode.MOVE); - //We have to use the model class here, as the content of the dragboard must be serializable - content.put(DragAndDropDataFormats.LINKED_FILE, selectedItem); - dragboard.setContent(content); - } - event.consume(); - } - - private void handleOnDragDropped(LinkedFileViewModel originalItem, DragEvent event) { - Dragboard dragboard = event.getDragboard(); - boolean success = false; - - ObservableList items = listView.itemsProperty().get(); - - if (dragboard.hasContent(DragAndDropDataFormats.LINKED_FILE)) { - - LinkedFile linkedFile = (LinkedFile) dragboard.getContent(DragAndDropDataFormats.LINKED_FILE); - LinkedFileViewModel transferedItem = null; - int draggedIdx = 0; - for (int i = 0; i < items.size(); i++) { - if (items.get(i).getFile().equals(linkedFile)) { - draggedIdx = i; - transferedItem = items.get(i); - break; - } - } - int thisIdx = items.indexOf(originalItem); - items.set(draggedIdx, originalItem); - items.set(thisIdx, transferedItem); - success = true; - } - if (dragboard.hasFiles()) { - List linkedFiles = dragboard.getFiles().stream().map(File::toPath).map(viewModel::fromFile).collect(Collectors.toList()); - items.addAll(linkedFiles); - success = true; - } - event.setDropCompleted(success); - event.consume(); - - } - private static Node createFileDisplay(LinkedFileViewModel linkedFile) { Node icon = linkedFile.getTypeIcon().getGraphicNode(); icon.setOnMouseClicked(event -> linkedFile.open()); diff --git a/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java index 4530cb881579..8fca8fa8d97b 100644 --- a/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java @@ -6,11 +6,13 @@ 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.Pane; import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; +import org.jabref.gui.entryeditor.FileDragDropPreferences; import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -40,10 +42,16 @@ class EntryEditorPrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private final AutoCompletePreferences autoCompletePreferences; + private final FileDragDropPreferences dragDropPreferences; + private final RadioButton copyFile; + private final RadioButton linkFile; + private final RadioButton renameCopyFile; public EntryEditorPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; autoCompletePreferences = prefs.getAutoCompletePreferences(); + dragDropPreferences = prefs.getEntryEditorFileLinkPreference(); + autoOpenForm = new CheckBox(Localization.lang("Open editor when a new entry is created")); defSource = new CheckBox(Localization.lang("Show BibTeX source by default")); emacsMode = new CheckBox(Localization.lang("Use Emacs key bindings")); @@ -111,8 +119,24 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) { builder.add(firstNameModeAbbr, 1, 20); builder.add(firstNameModeFull, 1, 21); builder.add(firstNameModeBoth, 1, 22); + + final ToggleGroup group = new ToggleGroup(); + Label linkFileOptions = new Label(Localization.lang("Options to add file")); + linkFileOptions.getStyleClass().add("sectionHeader"); + copyFile = new RadioButton(Localization.lang("Copy file to current location")); + linkFile = new RadioButton(Localization.lang("Link file (without copying)")); + renameCopyFile = new RadioButton(Localization.lang("Copy, rename and link file")); + builder.add(linkFileOptions, 1, 23); + builder.add(copyFile, 1, 24); + builder.add(linkFile, 1, 25); + builder.add(renameCopyFile, 1, 26); + copyFile.setToggleGroup(group); + linkFile.setToggleGroup(group); + renameCopyFile.setToggleGroup(group); + } + @Override public Node getBuilder() { return builder; } @@ -158,6 +182,14 @@ public void setValues() { break; } + if (dragDropPreferences.isCopyFile()) { + copyFile.setSelected(true); + } else if (dragDropPreferences.isLinkFile()) { + linkFile.setSelected(true); + } else { + renameCopyFile.setSelected(true); + } + // similar for emacs CTRL-a and emacs mode emacsRebindCtrlA.setDisable(!emacsMode.isSelected()); // Autocomplete fields is only enabled when autocompletion is selected @@ -215,6 +247,22 @@ else if (autoCompFF.isSelected()) { } else { autoCompletePreferences.setFirstNameMode(AutoCompleteFirstNameMode.BOTH); } + + if (copyFile.isSelected()) { + dragDropPreferences.setCopyFile(true); + dragDropPreferences.setLinkFile(false); + dragDropPreferences.setRenameCopyFile(false); + } else if (linkFile.isSelected()) { + dragDropPreferences.setCopyFile(false); + dragDropPreferences.setLinkFile(true); + dragDropPreferences.setRenameCopyFile(false); + } else { + dragDropPreferences.setCopyFile(false); + dragDropPreferences.setLinkFile(false); + dragDropPreferences.setRenameCopyFile(true); + } + + prefs.storeEntryEditorFileLinkPreference(dragDropPreferences); prefs.storeAutoCompletePreferences(autoCompletePreferences); } diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 79d0afc5a5ff..ef65fd69b46f 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -44,6 +44,7 @@ import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.desktop.JabRefDesktop; +import org.jabref.gui.entryeditor.FileDragDropPreferences; import org.jabref.gui.entryeditor.EntryEditorPreferences; import org.jabref.gui.entryeditor.EntryEditorTabList; import org.jabref.gui.groups.GroupViewMode; @@ -401,6 +402,11 @@ public class JabRefPreferences implements PreferencesService { private static final String PROTECTED_TERMS_ENABLED_INTERNAL = "protectedTermsEnabledInternal"; private static final String PROTECTED_TERMS_DISABLED_INTERNAL = "protectedTermsDisabledInternal"; + //File linking Options for entry editor + private static final String ENTRY_EDITOR_COPY_FILE = "copyFile"; + private static final String ENTRY_EDITOR_LINK_FILE = "linkFile"; + private static final String ENTRY_EDITOR_RENAME_COPY_FILE = "renameCopyFile"; + //GroupViewMode private static final String GROUP_INTERSECT_UNION_VIEW_MODE = "groupIntersectUnionViewModes"; @@ -409,6 +415,7 @@ public class JabRefPreferences implements PreferencesService { // Helper string private static final String USER_HOME = System.getProperty("user.home"); + // The only instance of this class: private static JabRefPreferences singleton; /** @@ -783,6 +790,11 @@ private JabRefPreferences() { // set default theme defaults.put(JabRefPreferences.FX_THEME, ThemeLoader.DEFAULT_MAIN_CSS); + + defaults.put(ENTRY_EDITOR_COPY_FILE, Boolean.TRUE); + defaults.put(ENTRY_EDITOR_LINK_FILE, Boolean.FALSE); + defaults.put(ENTRY_EDITOR_RENAME_COPY_FILE, Boolean.FALSE); + setLanguageDependentDefaultValues(); } @@ -2015,4 +2027,15 @@ public Map getMainTableColumnSortTypes() { } return map; } + + public FileDragDropPreferences getEntryEditorFileLinkPreference() { + return new FileDragDropPreferences(getBoolean(ENTRY_EDITOR_COPY_FILE), getBoolean(ENTRY_EDITOR_LINK_FILE), + getBoolean(ENTRY_EDITOR_RENAME_COPY_FILE)); + } + + public void storeEntryEditorFileLinkPreference(FileDragDropPreferences dragDropPreferences) { + putBoolean(ENTRY_EDITOR_COPY_FILE, dragDropPreferences.isCopyFile()); + putBoolean(ENTRY_EDITOR_LINK_FILE, dragDropPreferences.isLinkFile()); + putBoolean(ENTRY_EDITOR_RENAME_COPY_FILE, dragDropPreferences.isRenameCopyFile()); + } } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 529922c4b94f..29eefd2821ed 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2217,3 +2217,8 @@ Keystore\:=Keystore\: Password\:=Password\: Remember\ Password=Remember Password Use\ SSL=Use SSL + +Options\ to\ add\ file=Options to add file +Copy\ file\ to\ current\ location=Copy file to current location +Link\ file\ (without\ copying)=Link file (without copying) +Copy,\ rename\ and\ link\ file=Copy, rename and link file \ No newline at end of file