From 7564862cf5fdfa43bdc17bbb4cc2ccbd6eee2614 Mon Sep 17 00:00:00 2001 From: Tobias Boceck Date: Fri, 6 May 2016 12:38:24 +0200 Subject: [PATCH 1/2] Initial port of the keybindings dialog to javafx --- CHANGELOG.md | 1 + src/main/java/net/sf/jabref/gui/FXAlert.java | 16 +- .../java/net/sf/jabref/gui/FXDialogs.java | 135 ++++++++++++ .../java/net/sf/jabref/gui/IconTheme.java | 4 + .../java/net/sf/jabref/gui/JabRefFrame.java | 24 +- .../net/sf/jabref/gui/help/AboutAction.java | 4 +- .../sf/jabref/gui/help/AboutDialogView.java | 5 +- .../jabref/gui/help/AboutDialogViewModel.java | 11 +- .../sf/jabref/gui/keyboard/KeyBinding.java | 179 ++++++++------- .../jabref/gui/keyboard/KeyBindingAction.java | 31 +++ .../gui/keyboard/KeyBindingCategory.java | 33 +++ .../gui/keyboard/KeyBindingPreferences.java | 49 ++++- .../jabref/gui/keyboard/KeyBindingTable.java | 17 -- .../gui/keyboard/KeyBindingTableModel.java | 65 ------ .../gui/keyboard/KeyBindingViewModel.java | 139 ++++++++++++ .../gui/keyboard/KeyBindingsDialog.java | 153 ------------- .../gui/keyboard/KeyBindingsDialogView.java | 30 +++ .../keyboard/KeyBindingsDialogViewModel.java | 207 ++++++++++++++++++ .../gui/keyboard/KeyBindingsListener.java | 66 ------ src/main/resources/l10n/JabRef_da.properties | 3 + src/main/resources/l10n/JabRef_de.properties | 3 + src/main/resources/l10n/JabRef_en.properties | 3 + src/main/resources/l10n/JabRef_es.properties | 3 + src/main/resources/l10n/JabRef_fa.properties | 3 + src/main/resources/l10n/JabRef_fr.properties | 3 + src/main/resources/l10n/JabRef_in.properties | 3 + src/main/resources/l10n/JabRef_it.properties | 3 + src/main/resources/l10n/JabRef_ja.properties | 3 + src/main/resources/l10n/JabRef_nl.properties | 3 + src/main/resources/l10n/JabRef_no.properties | 3 + .../resources/l10n/JabRef_pt_BR.properties | 3 + src/main/resources/l10n/JabRef_ru.properties | 3 + src/main/resources/l10n/JabRef_sv.properties | 3 + src/main/resources/l10n/JabRef_tr.properties | 3 + src/main/resources/l10n/JabRef_vi.properties | 3 + src/main/resources/l10n/JabRef_zh.properties | 3 + .../jabref/gui/keyboard/KeyBindingsDialog.css | 22 ++ .../gui/keyboard/KeyBindingsDialog.fxml | 40 ++++ .../KeyBindingsDialogViewModelTest.java | 163 ++++++++++++++ 39 files changed, 1029 insertions(+), 416 deletions(-) create mode 100644 src/main/java/net/sf/jabref/gui/FXDialogs.java create mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingAction.java create mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingCategory.java delete mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTable.java delete mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTableModel.java create mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingViewModel.java delete mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialog.java create mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogView.java create mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogViewModel.java delete mode 100644 src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsListener.java create mode 100644 src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.css create mode 100644 src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.fxml create mode 100644 src/test/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc380a495b..d2f9b2a47da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ to [sourceforge feature requests](https://sourceforge.net/p/jabref/features/) by - Added an option in the about dialog to easily copy the version information of JabRef - Integrity check table can be sorted by clicking on column headings - Add tab which shows the MathSciNet review website if the `MRNumber` field is present. +- Partly switched to new UI technology (JavaFX). Redesigned key bindings dialog. ### Fixed - Fixed [#473](https://github.com/JabRef/jabref/issues/473): Values in an entry containing symbols like ' are now properly escaped for exporting to the database diff --git a/src/main/java/net/sf/jabref/gui/FXAlert.java b/src/main/java/net/sf/jabref/gui/FXAlert.java index c14b911da59..254383ed8f6 100644 --- a/src/main/java/net/sf/jabref/gui/FXAlert.java +++ b/src/main/java/net/sf/jabref/gui/FXAlert.java @@ -19,13 +19,17 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import net.sf.jabref.Globals; +import net.sf.jabref.JabRefGUI; +import net.sf.jabref.gui.keyboard.KeyBinding; +import net.sf.jabref.gui.keyboard.KeyBindingPreferences; + import javafx.application.Platform; +import javafx.fxml.FXMLLoader; import javafx.scene.control.Alert; import javafx.scene.image.Image; import javafx.stage.Stage; -import net.sf.jabref.JabRefGUI; - /** * This class shall provide a super class for future dialogs implemented in java fx. * It mimics the behavior of a swing JDialog which means once a object of this class @@ -67,6 +71,7 @@ public void windowGainedFocus(WindowEvent e) { } }; + public FXAlert(AlertType type, String title, Image image) { this(type, title); setDialogIcon(image); @@ -89,6 +94,13 @@ public FXAlert(AlertType type) { fxDialogWindow.setOnHiding(evt -> setSwingWindowsEnabledAndFocusable(true)); fxDialogWindow.setOnCloseRequest(evt -> this.close()); + + fxDialogWindow.getScene().setOnKeyPressed(evt -> { + KeyBindingPreferences keyPreferences = Globals.getKeyPrefs(); + if (keyPreferences.checkKeyCombinationEquality(KeyBinding.CLOSE_DIALOG, evt)) { + fxDialogWindow.close(); + } + }); } public void setDialogStyle(String pathToStyleSheet) { diff --git a/src/main/java/net/sf/jabref/gui/FXDialogs.java b/src/main/java/net/sf/jabref/gui/FXDialogs.java new file mode 100644 index 00000000000..25fcec6fd52 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/FXDialogs.java @@ -0,0 +1,135 @@ +/* Copyright (C) 2016 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.gui; + +import java.util.Optional; + +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; + +/** + * This class provides static methods to create default + * JavaFX dialogs which will also work on top of swing + * windows. The created dialogs are instances of the + * {@link FXAlert} class. The available dialogs in this class + * are useful for displaying small information graphic dialogs + * rather than complex windows. For more complex dialogs it is + * advised to rather create a new sub class of {@link FXAlert}. + * + */ +public abstract class FXDialogs { + + /** + * This will create and display a new information dialog. + * It will include a blue information icon on the left and + * a single OK Button. To create a information dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(AlertType, String, String, ButtonType...)} + * + * @param title as String + * @param content as String + */ + public static void showInformationDialogAndWait(String title, String content) { + FXAlert alert = createDialog(AlertType.INFORMATION, title, content); + alert.showAndWait(); + } + + /** + * This will create and display a new information dialog. + * It will include a yellow warning icon on the left and + * a single OK Button. To create a warning dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(AlertType, String, String, ButtonType...)} + * + * @param title as String + * @param content as String + */ + public static void showWarningDialogAndWait(String title, String content) { + FXAlert alert = createDialog(AlertType.WARNING, title, content); + alert.showAndWait(); + } + + /** + * This will create and display a new error dialog. + * It will include a red error icon on the left and + * a single OK Button. To create a error dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(AlertType, String, String, ButtonType...)} + * + * @param title as String + * @param content as String + */ + public static void showErrorDialogAndWait(String title, String content) { + FXAlert alert = createDialog(AlertType.ERROR, title, content); + alert.showAndWait(); + } + + /** + * This will create and display a new confirmation dialog. + * It will include a blue question icon on the left and + * a OK and Cancel Button. To create a confirmation dialog with custom + * buttons see also {@link #showCustomButtonDialogAndWait(AlertType, String, String, ButtonType...)} + * + * @param title as String + * @param content as String + * @return Optional with the pressed Button as ButtonType + */ + public static Optional showConfirmationDialogAndWait(String title, String content) { + FXAlert alert = createDialog(AlertType.CONFIRMATION, title, content); + return alert.showAndWait(); + } + + /** + * This will create and display a new dialog of the specified + * {@link AlertType} but with user defined buttons as optional + * {@link ButtonType}s. + * + * @param type as {@link AlertType} + * @param title as String + * @param content as String + * @param buttonTypes + * @return Optional with the pressed Button as ButtonType + */ + public static Optional showCustomButtonDialogAndWait(AlertType type, String title, String content, + ButtonType... buttonTypes) { + FXAlert alert = createDialog(type, title, content); + alert.getButtonTypes().setAll(buttonTypes); + return alert.showAndWait(); + } + + /** + * This will create and display a new dialog showing a custom {@link DialogPane} + * and using custom {@link ButtonType}s. + * + * @param title as String + * @param contentPane as DialogPane + * @param buttonTypes as ButtonType + * @return Optional with the pressed Button as ButtonType + */ + public static Optional showCustomDialogAndWait(String title, DialogPane contentPane, + ButtonType... buttonTypes) { + FXAlert alert = new FXAlert(AlertType.NONE, title); + alert.setDialogPane(contentPane); + alert.getButtonTypes().setAll(buttonTypes); + return alert.showAndWait(); + } + + private static FXAlert createDialog(AlertType type, String title, String content) { + FXAlert alert = new FXAlert(type, title); + alert.setHeaderText(null); + alert.setContentText(content); + return alert; + } + +} diff --git a/src/main/java/net/sf/jabref/gui/IconTheme.java b/src/main/java/net/sf/jabref/gui/IconTheme.java index 1a159f1ee1b..405c9861a39 100644 --- a/src/main/java/net/sf/jabref/gui/IconTheme.java +++ b/src/main/java/net/sf/jabref/gui/IconTheme.java @@ -44,6 +44,7 @@ public class IconTheme { public static Font FONT; public static Font FONT_16; + public static javafx.scene.text.Font FX_FONT; /* Colors */ @@ -70,6 +71,9 @@ public class IconTheme { try (InputStream stream = FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf")) { FONT = Font.createFont(Font.TRUETYPE_FONT, stream); FONT_16 = FONT.deriveFont(Font.PLAIN, 16f); + try (InputStream stream2 = FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf")) { + FX_FONT = javafx.scene.text.Font.loadFont(stream2, DEFAULT_SIZE); + } } catch (FontFormatException | IOException e) { LOGGER.warn("Error loading font", e); } diff --git a/src/main/java/net/sf/jabref/gui/JabRefFrame.java b/src/main/java/net/sf/jabref/gui/JabRefFrame.java index 154a672d1cb..d4a8bc884ef 100644 --- a/src/main/java/net/sf/jabref/gui/JabRefFrame.java +++ b/src/main/java/net/sf/jabref/gui/JabRefFrame.java @@ -104,8 +104,7 @@ import net.sf.jabref.gui.help.HelpFiles; import net.sf.jabref.gui.journals.ManageJournalsAction; import net.sf.jabref.gui.keyboard.KeyBinding; -import net.sf.jabref.gui.keyboard.KeyBindingRepository; -import net.sf.jabref.gui.keyboard.KeyBindingsDialog; +import net.sf.jabref.gui.keyboard.KeyBindingAction; import net.sf.jabref.gui.menus.ChangeEntryTypeMenu; import net.sf.jabref.gui.menus.FileHistoryMenu; import net.sf.jabref.gui.menus.RightClickMenu; @@ -206,7 +205,7 @@ public class JabRefFrame extends JFrame implements OutputPrinter { private final OpenDatabaseAction open = new OpenDatabaseAction(this, true); private final EditModeAction editModeAction = new EditModeAction(); private final AbstractAction quit = new CloseAction(); - private final AbstractAction selectKeys = new SelectKeysAction(); + private final AbstractAction keyBindingAction = new KeyBindingAction(); private final AbstractAction newBibtexDatabaseAction = new NewDatabaseAction(this, BibDatabaseMode.BIBTEX); private final AbstractAction newBiblatexDatabaseAction = new NewDatabaseAction(this, BibDatabaseMode.BIBLATEX); private final AbstractAction newSubDatabaseAction = new NewSubDatabaseAction(this); @@ -1341,7 +1340,7 @@ private void fillMenu() { options.add(customFileTypesAction); options.add(manageJournals); options.add(manageSelectors); - options.add(selectKeys); + options.add(keyBindingAction); mb.add(options); helpMenu.add(help); @@ -1664,23 +1663,6 @@ public void createDisabledIconsForMenuEntries(MenuElement menuElement) { } } - private class SelectKeysAction extends AbstractAction { - - public SelectKeysAction() { - super(Localization.lang("Customize key bindings")); - this.putValue(Action.SMALL_ICON, IconTheme.JabRefIcon.KEY_BINDINGS.getSmallIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - KeyBindingsDialog d = new KeyBindingsDialog(new KeyBindingRepository(Globals.getKeyPrefs().getKeyBindings())); - d.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - d.pack(); //setSize(300,500); - d.setLocationRelativeTo(JabRefFrame.this); - d.setVisible(true); - } - } - /** * The action concerned with closing the window. */ diff --git a/src/main/java/net/sf/jabref/gui/help/AboutAction.java b/src/main/java/net/sf/jabref/gui/help/AboutAction.java index 82cb79f6a9c..62208777caf 100644 --- a/src/main/java/net/sf/jabref/gui/help/AboutAction.java +++ b/src/main/java/net/sf/jabref/gui/help/AboutAction.java @@ -20,10 +20,10 @@ import javax.swing.Action; import javax.swing.Icon; -import javafx.application.Platform; - import net.sf.jabref.gui.actions.MnemonicAwareAction; +import javafx.application.Platform; + public class AboutAction extends MnemonicAwareAction { public AboutAction(String title, String tooltip, Icon iconFile) { diff --git a/src/main/java/net/sf/jabref/gui/help/AboutDialogView.java b/src/main/java/net/sf/jabref/gui/help/AboutDialogView.java index 4a0b2c62928..4980f4906a9 100644 --- a/src/main/java/net/sf/jabref/gui/help/AboutDialogView.java +++ b/src/main/java/net/sf/jabref/gui/help/AboutDialogView.java @@ -15,13 +15,12 @@ */ package net.sf.jabref.gui.help; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.DialogPane; - import net.sf.jabref.gui.FXAlert; import net.sf.jabref.logic.l10n.Localization; import com.airhacks.afterburner.views.FXMLView; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.DialogPane; public class AboutDialogView extends FXMLView { diff --git a/src/main/java/net/sf/jabref/gui/help/AboutDialogViewModel.java b/src/main/java/net/sf/jabref/gui/help/AboutDialogViewModel.java index cbd4791fec8..fc0735fa463 100644 --- a/src/main/java/net/sf/jabref/gui/help/AboutDialogViewModel.java +++ b/src/main/java/net/sf/jabref/gui/help/AboutDialogViewModel.java @@ -17,18 +17,17 @@ import java.io.IOException; -import javafx.beans.property.ReadOnlyStringProperty; -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.stage.Stage; - import net.sf.jabref.Globals; import net.sf.jabref.JabRefGUI; import net.sf.jabref.gui.ClipBoardManager; import net.sf.jabref.gui.desktop.JabRefDesktop; import net.sf.jabref.logic.l10n.Localization; +import javafx.beans.property.ReadOnlyStringProperty; +import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.stage.Stage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBinding.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBinding.java index 7399218a840..868daaa7d0a 100644 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBinding.java +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBinding.java @@ -5,98 +5,113 @@ public enum KeyBinding { ABBREVIATE( - "Abbreviate", Localization.lang("Abbreviate journal names"), "ctrl alt A"), - AUTOGENERATE_BIBTEX_KEYS("Autogenerate BibTeX keys", Localization.lang("Autogenerate BibTeX keys"), "ctrl G"), + "Abbreviate", Localization.lang("Abbreviate journal names"), "ctrl alt A", KeyBindingCategory.TOOLS), + AUTOGENERATE_BIBTEX_KEYS( + "Autogenerate BibTeX keys", Localization + .lang("Autogenerate BibTeX keys"), "ctrl G", KeyBindingCategory.QUALITY), AUTOMATICALLY_LINK_FILES( - "Automatically link files", Localization.lang("Automatically set file links"), "alt F"), - BACK("Back", Localization.lang("Back"), "alt LEFT"), + "Automatically link files", Localization.lang("Automatically set file links"), "alt F", KeyBindingCategory.QUALITY), + BACK("Back", Localization.lang("Back"), "alt LEFT", KeyBindingCategory.VIEW), CLEANUP( - "Cleanup", Localization.lang("Cleanup entries"), "ctrl shift F7"), - CLEAR_SEARCH("Clear search", Localization.lang("Clear search"), "ESCAPE"), - CLOSE_DATABASE("Close database", Localization.lang("Close database"), "ctrl W"), - CLOSE_DIALOG("Close dialog", Localization.lang("Close dialog"), "ESCAPE"), - CLOSE_ENTRY_EDITOR("Close entry editor", Localization.lang("Close entry editor"), "ESCAPE"), - COPY("Copy", Localization.lang("Copy"), "ctrl C"), - COPY_CITE_BIBTEX_KEY("Copy \\cite{BibTeX key}", Localization.lang("Copy \\cite{BibTeX key}"), "ctrl K"), - COPY_BIBTEX_KEY("Copy BibTeX key", Localization.lang("Copy BibTeX key"), "ctrl shift K"), - COPY_BIBTEX_KEY_AND_TITLE("Copy BibTeX key and title", Localization.lang("Copy BibTeX key and title"), "ctrl shift alt K"), - COPY_PREVIEW("Copy preview", Localization.lang("Copy preview"), "ctrl shift C"), - CUT("Cut", Localization.lang("Cut"), "ctrl X"), - DECREASE_TABLE_FONT_SIZE("Decrease table font size", Localization.lang("Decrease table font size"), "ctrl MINUS"), - DELETE_ENTRY("Delete entry", Localization.lang("Delete entry"), "DELETE"), - EDIT_ENTRY("Edit entry", Localization.lang("Edit entry"), "ctrl E"), - EDIT_PREAMBLE("Edit preamble", Localization.lang("Edit preamble"), "ctrl P"), - EDIT_STRINGS("Edit strings", Localization.lang("Edit strings"), "ctrl T"), - ENTRY_EDITOR_NEXT_ENTRY("Entry editor, next entry", Localization.lang("Entry editor, next entry"), "ctrl shift DOWN"), - ENTRY_EDITOR_NEXT_PANEL("Entry editor, next panel", Localization.lang("Entry editor, next panel"), "ctrl TAB"), - ENTRY_EDITOR_NEXT_PANEL_2("Entry editor, next panel 2", Localization.lang("Entry editor, next panel 2"), "ctrl PLUS"), - ENTRY_EDITOR_PREVIOUS_ENTRY("Entry editor, previous entry", Localization.lang("Entry editor, previous entry"), "ctrl shift UP"), - ENTRY_EDITOR_PREVIOUS_PANEL("Entry editor, previous panel", Localization.lang("Entry editor, previous panel"), "ctrl shift TAB"), - ENTRY_EDITOR_PREVIOUS_PANEL_2("Entry editor, previous panel 2", Localization.lang("Entry editor, previous panel 2"), "ctrl MINUS"), - ENTRY_EDITOR_STORE_FIELD("Entry editor, store field", Localization.lang("Entry editor, store field"), "alt S"), - FILE_LIST_EDITOR_MOVE_ENTRY_DOWN("File list editor, move entry down", Localization.lang("File list editor, move entry down"), "ctrl DOWN"), - FILE_LIST_EDITOR_MOVE_ENTRY_UP("File list editor, move entry up", Localization.lang("File list editor, move entry up"), "ctrl UP"), - FIND_UNLINKED_FILES("Find unlinked files", Localization.lang("Find unlinked files"), "shift F7"), - FOCUS_ENTRY_TABLE("Focus entry table", Localization.lang("Focus entry table"), "ctrl shift E"), - FORWARD("Forward", Localization.lang("Forward"), "alt RIGHT"), - HELP("Help", Localization.lang("Help"), "F1"), - HIDE_SHOW_TOOLBAR("Hide/show toolbar", Localization.lang("Hide/show toolbar"), "ctrl alt T"), - IMPORT_INTO_CURRENT_DATABASE("Import into current database", Localization.lang("Import into current database"), "ctrl I"), - IMPORT_INTO_NEW_DATABASE("Import into new database", Localization.lang("Import into new database"), "ctrl alt I"), - INCREASE_TABLE_FONT_SIZE("Increase table font size", Localization.lang("Increase table font size"), "ctrl PLUS"), - MARK_ENTRIES("Mark entries", Localization.lang("Mark entries"), "ctrl M"), - NEW_ARTICLE("New article", Localization.lang("New article"), "ctrl shift A"), - NEW_BOOK("New book", Localization.lang("New book"), "ctrl shift B"), - NEW_ENTRY("New entry", Localization.lang("New entry"), "ctrl N"), - NEW_FROM_PLAIN_TEXT("New from plain text", Localization.lang("New from plain text"), "ctrl shift N"), - NEW_INBOOK("New inbook", Localization.lang("New inbook"), "ctrl shift I"), - NEW_MASTERSTHESIS("New mastersthesis", Localization.lang("New mastersthesis"), "ctrl shift M"), - NEW_PHDTHESIS("New phdthesis", Localization.lang("New phdthesis"), "ctrl shift T"), - NEW_PROCEEDINGS("New proceedings", Localization.lang("New proceedings"), "ctrl shift P"), - NEW_UNPUBLISHED("New unpublished", Localization.lang("New unpublished"), "ctrl shift U"), - NEXT_TAB("Next tab", Localization.lang("Next tab"), "ctrl PAGE_DOWN"), - OPEN_CONSOLE("Open terminal here", Localization.lang("Open terminal here"), "ctrl shift J"), - OPEN_DATABASE("Open database", Localization.lang("Open database"), "ctrl O"), - OPEN_FILE("Open file", Localization.lang("Open file"), "F4"), - OPEN_FOLDER("Open folder", Localization.lang("Open folder"), "ctrl shift O"), - OPEN_URL_OR_DOI("Open URL or DOI", Localization.lang("Open URL or DOI"), "F3"), - PASTE("Paste", Localization.lang("Paste"), "ctrl V"), - PREAMBLE_EDITOR_STORE_CHANGES("Preamble editor, store changes", Localization.lang("Preamble editor, store changes"), "alt S"), - PREVIOUS_TAB("Previous tab", Localization.lang("Previous tab"), "ctrl PAGE_UP"), - PRINT_ENTRY_PREVIEW("Print entry preview", Localization.lang("Print entry preview"), "alt P"), - PUSH_TO_APPLICATION("Push to application", Localization.lang("Push to application"), "ctrl L"), - QUIT_JABREF("Quit JabRef", Localization.lang("Quit JabRef"), "ctrl Q"), - REDO("Redo", Localization.lang("Redo"), "ctrl Y"), + "Cleanup", Localization.lang("Cleanup entries"), "ctrl shift F7", KeyBindingCategory.QUALITY), + CLEAR_SEARCH("Clear search", Localization.lang("Clear search"), "ESCAPE", KeyBindingCategory.SEARCH), + CLOSE_DATABASE("Close database", Localization.lang("Close database"), "ctrl W", KeyBindingCategory.FILE), + CLOSE_DIALOG("Close dialog", Localization.lang("Close dialog"), "ESCAPE", KeyBindingCategory.FILE), + CLOSE_ENTRY_EDITOR( + "Close entry editor", Localization.lang("Close entry editor"), "ESCAPE", KeyBindingCategory.VIEW), + COPY("Copy", Localization.lang("Copy"), "ctrl C", KeyBindingCategory.EDIT), + COPY_CITE_BIBTEX_KEY("Copy \\cite{BibTeX key}", Localization.lang("Copy \\cite{BibTeX key}"), "ctrl K", KeyBindingCategory.EDIT), + COPY_BIBTEX_KEY("Copy BibTeX key", Localization.lang("Copy BibTeX key"), "ctrl shift K", KeyBindingCategory.EDIT), + COPY_BIBTEX_KEY_AND_TITLE("Copy BibTeX key and title", Localization.lang("Copy BibTeX key and title"), "ctrl shift alt K", KeyBindingCategory.EDIT), + COPY_PREVIEW( + "Copy preview", Localization.lang("Copy preview"), "ctrl shift C", KeyBindingCategory.VIEW), + CUT("Cut", Localization.lang("Cut"), "ctrl X", KeyBindingCategory.EDIT), + DECREASE_TABLE_FONT_SIZE("Decrease table font size", Localization.lang("Decrease table font size"), "ctrl MINUS", KeyBindingCategory.VIEW), + DELETE_ENTRY("Delete entry", Localization.lang("Delete entry"), "DELETE", KeyBindingCategory.BIBTEX), + EDIT_ENTRY("Edit entry", Localization.lang("Edit entry"), "ctrl E", KeyBindingCategory.BIBTEX), + EDIT_PREAMBLE("Edit preamble", Localization.lang("Edit preamble"), "ctrl P", KeyBindingCategory.BIBTEX), + EDIT_STRINGS("Edit strings", Localization.lang("Edit strings"), "ctrl T", KeyBindingCategory.BIBTEX), + ENTRY_EDITOR_NEXT_ENTRY("Entry editor, next entry", Localization.lang("Entry editor, next entry"), "ctrl shift DOWN", KeyBindingCategory.VIEW), + ENTRY_EDITOR_NEXT_PANEL("Entry editor, next panel", Localization.lang("Entry editor, next panel"), "ctrl TAB", KeyBindingCategory.VIEW), + ENTRY_EDITOR_NEXT_PANEL_2("Entry editor, next panel 2", Localization.lang("Entry editor, next panel 2"), "ctrl PLUS", KeyBindingCategory.VIEW), + ENTRY_EDITOR_PREVIOUS_ENTRY("Entry editor, previous entry", Localization.lang("Entry editor, previous entry"), "ctrl shift UP", KeyBindingCategory.VIEW), + ENTRY_EDITOR_PREVIOUS_PANEL("Entry editor, previous panel", Localization.lang("Entry editor, previous panel"), "ctrl shift TAB", KeyBindingCategory.VIEW), + ENTRY_EDITOR_PREVIOUS_PANEL_2("Entry editor, previous panel 2", Localization.lang("Entry editor, previous panel 2"), "ctrl MINUS", KeyBindingCategory.VIEW), + ENTRY_EDITOR_STORE_FIELD("Entry editor, store field", Localization.lang("Entry editor, store field"), "alt S", KeyBindingCategory.TOOLS), + FILE_LIST_EDITOR_MOVE_ENTRY_DOWN("File list editor, move entry down", Localization.lang("File list editor, move entry down"), "ctrl DOWN", KeyBindingCategory.VIEW), + FILE_LIST_EDITOR_MOVE_ENTRY_UP("File list editor, move entry up", Localization.lang("File list editor, move entry up"), "ctrl UP", KeyBindingCategory.VIEW), + FIND_UNLINKED_FILES( + "Find unlinked files", Localization.lang("Find unlinked files"), "shift F7", KeyBindingCategory.QUALITY), + FOCUS_ENTRY_TABLE("Focus entry table", Localization.lang("Focus entry table"), "ctrl shift E", KeyBindingCategory.VIEW), + FORWARD("Forward", Localization.lang("Forward"), "alt RIGHT", KeyBindingCategory.VIEW), + HELP("Help", Localization.lang("Help"), "F1", KeyBindingCategory.FILE), + HIDE_SHOW_TOOLBAR( + "Hide/show toolbar", Localization.lang("Hide/show toolbar"), "ctrl alt T", KeyBindingCategory.VIEW), + IMPORT_INTO_CURRENT_DATABASE("Import into current database", Localization.lang("Import into current database"), "ctrl I", KeyBindingCategory.FILE), + IMPORT_INTO_NEW_DATABASE("Import into new database", Localization.lang("Import into new database"), "ctrl alt I", KeyBindingCategory.FILE), + INCREASE_TABLE_FONT_SIZE( + "Increase table font size", Localization + .lang("Increase table font size"), "ctrl PLUS", KeyBindingCategory.VIEW), + MARK_ENTRIES("Mark entries", Localization.lang("Mark entries"), "ctrl M", KeyBindingCategory.EDIT), + NEW_ARTICLE("New article", Localization.lang("New article"), "ctrl shift A", KeyBindingCategory.BIBTEX), + NEW_BOOK("New book", Localization.lang("New book"), "ctrl shift B", KeyBindingCategory.BIBTEX), + NEW_ENTRY("New entry", Localization.lang("New entry"), "ctrl N", KeyBindingCategory.BIBTEX), + NEW_FROM_PLAIN_TEXT("New from plain text", Localization.lang("New from plain text"), "ctrl shift N", KeyBindingCategory.BIBTEX), + NEW_INBOOK("New inbook", Localization.lang("New inbook"), "ctrl shift I", KeyBindingCategory.BIBTEX), + NEW_MASTERSTHESIS("New mastersthesis", Localization.lang("New mastersthesis"), "ctrl shift M", KeyBindingCategory.BIBTEX), + NEW_PHDTHESIS("New phdthesis", Localization.lang("New phdthesis"), "ctrl shift T", KeyBindingCategory.BIBTEX), + NEW_PROCEEDINGS("New proceedings", Localization.lang("New proceedings"), "ctrl shift P", KeyBindingCategory.BIBTEX), + NEW_UNPUBLISHED("New unpublished", Localization.lang("New unpublished"), "ctrl shift U", KeyBindingCategory.BIBTEX), + NEXT_TAB( + "Next tab", Localization.lang("Next tab"), "ctrl PAGE_DOWN", KeyBindingCategory.VIEW), + OPEN_CONSOLE("Open terminal here", Localization.lang("Open terminal here"), "ctrl shift J", KeyBindingCategory.TOOLS), + OPEN_DATABASE("Open database", Localization.lang("Open database"), "ctrl O", KeyBindingCategory.FILE), + OPEN_FILE("Open file", Localization.lang("Open file"), "F4", KeyBindingCategory.TOOLS), + OPEN_FOLDER("Open folder", Localization.lang("Open folder"), "ctrl shift O", KeyBindingCategory.TOOLS), + OPEN_URL_OR_DOI("Open URL or DOI", Localization.lang("Open URL or DOI"), "F3", KeyBindingCategory.TOOLS), + PASTE("Paste", Localization.lang("Paste"), "ctrl V", KeyBindingCategory.EDIT), + PREAMBLE_EDITOR_STORE_CHANGES("Preamble editor, store changes", Localization.lang("Preamble editor, store changes"), "alt S", KeyBindingCategory.FILE), + PREVIOUS_TAB( + "Previous tab", Localization.lang("Previous tab"), "ctrl PAGE_UP", KeyBindingCategory.VIEW), + PRINT_ENTRY_PREVIEW("Print entry preview", Localization.lang("Print entry preview"), "alt P", KeyBindingCategory.FILE), + PUSH_TO_APPLICATION("Push to application", Localization.lang("Push to application"), "ctrl L", KeyBindingCategory.TOOLS), + QUIT_JABREF("Quit JabRef", Localization.lang("Quit JabRef"), "ctrl Q", KeyBindingCategory.FILE), + REDO("Redo", Localization.lang("Redo"), "ctrl Y", KeyBindingCategory.EDIT), REFRESH_OO( - "Refresh OO", Localization.lang("Refresh OpenOffice/LibreOffice"), "ctrl alt O"), - REPLACE_STRING("Replace string", Localization.lang("Replace string"), "ctrl R"), - RESOLVE_DUPLICATE_BIBTEX_KEYS("Resolve duplicate BibTeX keys", Localization.lang("Resolve duplicate BibTeX keys"), "ctrl shift D"), - SAVE_ALL("Save all", Localization.lang("Save all"), "ctrl alt S"), - SAVE_DATABASE("Save database", Localization.lang("Save database"), "ctrl S"), + "Refresh OO", Localization.lang("Refresh OpenOffice/LibreOffice"), "ctrl alt O", KeyBindingCategory.TOOLS), + REPLACE_STRING("Replace string", Localization.lang("Replace string"), "ctrl R", KeyBindingCategory.SEARCH), + RESOLVE_DUPLICATE_BIBTEX_KEYS("Resolve duplicate BibTeX keys", Localization.lang("Resolve duplicate BibTeX keys"), "ctrl shift D", KeyBindingCategory.BIBTEX), + SAVE_ALL("Save all", Localization.lang("Save all"), "ctrl alt S", KeyBindingCategory.FILE), + SAVE_DATABASE("Save database", Localization.lang("Save database"), "ctrl S", KeyBindingCategory.FILE), SAVE_DATABASE_AS( - "Save database as ...", Localization.lang("Save database as..."), "ctrl shift S"), - SEARCH("Search", Localization.lang("Search"), "ctrl F"), - SELECT_ALL("Select all", Localization.lang("Select all"), "ctrl A"), - STRING_DIALOG_ADD_STRING("String dialog, add string", Localization.lang("String dialog, add string"), "ctrl N"), - STRING_DIALOG_REMOVE_STRING("String dialog, remove string", Localization.lang("String dialog, remove string"), "shift DELETE"), - SWITCH_PREVIEW_LAYOUT("Switch preview layout", Localization.lang("Switch preview layout"), "F9"), - SYNCHRONIZE_FILES("Synchronize files", Localization.lang("Synchronize files"), "ctrl F4"), - TOGGLE_ENTRY_PREVIEW("Toggle entry preview", Localization.lang("Toggle entry preview"), "ctrl F9"), - TOGGLE_GROUPS_INTERFACE("Toggle groups interface", Localization.lang("Toggle groups interface"), "ctrl shift G"), - UNABBREVIATE("Unabbreviate", Localization.lang("Unabbreviate"), "ctrl alt shift A"), - UNDO("Undo", Localization.lang("Undo"), "ctrl Z"), - UNMARK_ENTRIES("Unmark entries", Localization.lang("Unmark entries"), "ctrl shift M"), - WEB_SEARCH("Web search", Localization.lang("Web search"), "F5"), - WRITE_XMP("Write XMP", Localization.lang("Write XMP"), "ctrl F7"),; + "Save database as ...", Localization.lang("Save database as..."), "ctrl shift S", KeyBindingCategory.FILE), + SEARCH("Search", Localization.lang("Search"), "ctrl F", KeyBindingCategory.SEARCH), + SELECT_ALL("Select all", Localization.lang("Select all"), "ctrl A", KeyBindingCategory.EDIT), + STRING_DIALOG_ADD_STRING("String dialog, add string", Localization.lang("String dialog, add string"), "ctrl N", KeyBindingCategory.FILE), + STRING_DIALOG_REMOVE_STRING("String dialog, remove string", Localization.lang("String dialog, remove string"), "shift DELETE", KeyBindingCategory.FILE), + SWITCH_PREVIEW_LAYOUT( + "Switch preview layout", Localization.lang("Switch preview layout"), "F9", KeyBindingCategory.VIEW), + SYNCHRONIZE_FILES("Synchronize files", Localization.lang("Synchronize files"), "ctrl F4", KeyBindingCategory.QUALITY), + TOGGLE_ENTRY_PREVIEW( + "Toggle entry preview", Localization.lang("Toggle entry preview"), "ctrl F9", KeyBindingCategory.VIEW), + TOGGLE_GROUPS_INTERFACE("Toggle groups interface", Localization.lang("Toggle groups interface"), "ctrl shift G", KeyBindingCategory.VIEW), + UNABBREVIATE("Unabbreviate", Localization.lang("Unabbreviate"), "ctrl alt shift A", KeyBindingCategory.TOOLS), + UNDO("Undo", Localization.lang("Undo"), "ctrl Z", KeyBindingCategory.EDIT), + UNMARK_ENTRIES("Unmark entries", Localization.lang("Unmark entries"), "ctrl shift M", KeyBindingCategory.EDIT), + WEB_SEARCH("Web search", Localization.lang("Web search"), "F5", KeyBindingCategory.SEARCH), + WRITE_XMP("Write XMP", Localization.lang("Write XMP"), "ctrl F7", KeyBindingCategory.TOOLS),; private final String key; private final String localization; private final String defaultBinding; + private final KeyBindingCategory category; - KeyBinding(String key, String localization, String defaultBinding) { + + KeyBinding(String key, String localization, String defaultBinding, KeyBindingCategory category) { this.key = key; this.localization = localization; this.defaultBinding = defaultBinding; + this.category = category; } public String getKey() { @@ -111,4 +126,8 @@ public String getDefaultBinding() { return defaultBinding; } + public KeyBindingCategory getCategory() { + return category; + } + } diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingAction.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingAction.java new file mode 100644 index 00000000000..316462aeef7 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingAction.java @@ -0,0 +1,31 @@ +package net.sf.jabref.gui.keyboard; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import net.sf.jabref.Globals; +import net.sf.jabref.gui.IconTheme; +import net.sf.jabref.logic.l10n.Localization; + +import javafx.application.Platform; + + +public class KeyBindingAction extends AbstractAction { + + + public KeyBindingAction() { + super(Localization.lang("Customize key bindings")); + this.putValue(Action.SMALL_ICON, IconTheme.JabRefIcon.KEY_BINDINGS.getSmallIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + Platform.runLater(() -> { + KeyBindingsDialogView view = new KeyBindingsDialogView(); + view.show(Globals.getKeyPrefs()); + }); + } + +} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingCategory.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingCategory.java new file mode 100644 index 00000000000..fad5ff9a4c8 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingCategory.java @@ -0,0 +1,33 @@ +package net.sf.jabref.gui.keyboard; + +import net.sf.jabref.logic.l10n.Localization; + +public enum KeyBindingCategory { + + FILE( + Localization.lang("File")), + EDIT( + Localization.lang("Edit")), + SEARCH( + Localization.lang("Search")), + VIEW( + Localization.lang("View")), + BIBTEX( + Localization.lang("BibTeX")), + QUALITY( + Localization.lang("Quality")), + TOOLS( + Localization.lang("Tools")); + + private final String name; + + + private KeyBindingCategory(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingPreferences.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingPreferences.java index 2671adc9432..761ec1a0d23 100644 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingPreferences.java +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingPreferences.java @@ -15,6 +15,9 @@ import net.sf.jabref.JabRefPreferences; import net.sf.jabref.logic.util.OS; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCombination; +import javafx.scene.input.KeyEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -48,6 +51,51 @@ public KeyStroke getKey(KeyBinding bindName) { } } + public KeyCombination getKeyCombination(KeyBinding bindName) { + String binding = keyBindingRepository.get(bindName.getKey()); + return KeyCombination.valueOf(binding); + } + + /** + * Check if the given keyCombination equals the given keyEvent + * + * @param combination as KeyCombination + * @param keyEvent as KeEvent + * @return true if matching, else false + */ + public boolean checkKeyCombinationEquality(KeyCombination combination, KeyEvent keyEvent) { + KeyCode code = keyEvent.getCode(); + if (code == KeyCode.UNDEFINED) { + return false; + } + // gather the pressed modifier keys + String modifiers = ""; + if (keyEvent.isControlDown()) { + modifiers = "ctrl"; + } + if (keyEvent.isShiftDown()) { + modifiers += " shift"; + } + if (keyEvent.isAltDown()) { + modifiers += " alt"; + } + modifiers = modifiers.trim(); + String newShortcut = (modifiers.isEmpty()) ? code.toString() : modifiers + " " + code; + KeyCombination pressedCombination = KeyCombination.valueOf(newShortcut); + return combination.equals(pressedCombination); + } + + /** + * Check if the given KeyBinding equals the given keyEvent + * + * @param binding as KeyBinding + * @param keyEvent as KeEvent + * @return true if matching, else false + */ + public boolean checkKeyCombinationEquality(KeyBinding binding, KeyEvent keyEvent) { + KeyCombination keyCombination = getKeyCombination(binding); + return checkKeyCombinationEquality(keyCombination, keyEvent); + } /** * Returns the KeyStroke for this binding, as defined by the defaults, or in the Preferences, but adapted for Mac @@ -82,7 +130,6 @@ private KeyStroke getKeyForMac(KeyStroke ks) { } } - /** * Stores new key bindings into Preferences, provided they actually differ from the old ones. */ diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTable.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTable.java deleted file mode 100644 index 3562d8496ea..00000000000 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTable.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.sf.jabref.gui.keyboard; - -import javax.swing.JTable; - -@SuppressWarnings("serial") -public class KeyBindingTable extends JTable { - - @Override - public boolean isCellEditable(int row, int col) { - return false; - } - - public String getOriginalName(int row) { - return ((KeyBindingTableModel) getModel()).getOriginalName(row); - } - -} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTableModel.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTableModel.java deleted file mode 100644 index bf4c9fb8b3d..00000000000 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingTableModel.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.sf.jabref.gui.keyboard; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import javax.swing.table.AbstractTableModel; - -import net.sf.jabref.logic.l10n.Localization; - -@SuppressWarnings("serial") -public class KeyBindingTableModel extends AbstractTableModel { - - private final KeyBindingRepository keyBindingRepository; - - public KeyBindingTableModel(KeyBindingRepository keyBindingRepository) { - this.keyBindingRepository = keyBindingRepository; - } - - @Override - public boolean isCellEditable(int row, int col) { - return false; - } - - @Override - public String getColumnName(int col) { - return col == 0 ? Localization.lang("Action") : Localization.lang("Shortcut"); - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public int getRowCount() { - return keyBindingRepository.size(); - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - Map.Entry row = getRowData(rowIndex); - if(columnIndex == 0) { - return row.getKey().getLocalization(); - } else { - return row.getValue(); - } - } - - public String getOriginalName(int rowIndex) { - return getRowData(rowIndex).getKey().getKey(); - } - - private Map.Entry getRowData(int rowIndex) { - List> entries = new LinkedList<>(keyBindingRepository.getKeyBindings().entrySet()); - return entries.get(rowIndex); - } - - @Override - public void setValueAt(Object o, int row, int col) { - if(col == 1) { - keyBindingRepository.put(getRowData(row).getKey(), String.valueOf(o)); - } - } -} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingViewModel.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingViewModel.java new file mode 100644 index 00000000000..60545aaa401 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingViewModel.java @@ -0,0 +1,139 @@ +/* Copyright (C) 2016 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.gui.keyboard; + +import com.google.common.base.CaseFormat; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +/** + * This class represents a view model for objects of the KeyBinding + * class. It has two properties representing the localized name of an + * action and its key bind. It can also represent a key binding category + * instead of a key bind itself. + * + */ +public class KeyBindingViewModel { + + private KeyBinding keyBinding = null; + private String realBinding = ""; + private final SimpleStringProperty displayName = new SimpleStringProperty(); + private final SimpleStringProperty shownBinding = new SimpleStringProperty(); + private final KeyBindingCategory category; + + + public KeyBindingViewModel(KeyBinding keyBinding, String binding) { + this(keyBinding.getCategory()); + this.keyBinding = keyBinding; + setDisplayName(); + setBinding(binding); + } + + public KeyBindingViewModel(KeyBindingCategory category) { + this.category = category; + setDisplayName(); + } + + public KeyBinding getKeyBinding() { + return keyBinding; + } + + public StringProperty shownBindingProperty() { + return this.shownBinding; + } + + public String getBinding() { + return realBinding; + } + + private void setBinding(String bind) { + this.realBinding = bind; + String[] parts = bind.split(" "); + String displayBind = ""; + for (String part : parts) { + displayBind += CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, part) + " "; + } + this.shownBinding.set(displayBind.trim().replace(" ", " + ")); + } + + private void setDisplayName() { + this.displayName.set((keyBinding == null) ? this.category.getName() : keyBinding.getLocalization()); + } + + public StringProperty nameProperty() { + return this.displayName; + } + + public boolean isCategory() { + return (keyBinding == null) ? true : false; + } + + /** + * Sets a a new key bind to this objects key binding object if + * the given key event is a valid combination of keys. + * + * @param evt as KeyEvent + * @return true if the KeyEvent is a valid binding, false else + */ + public boolean setNewBinding(KeyEvent evt) { + // validate the shortcut is no modifier key + KeyCode code = evt.getCode(); + if (code.isModifierKey() || (code == KeyCode.BACK_SPACE) || (code == KeyCode.SPACE) || (code == KeyCode.TAB) + || (code == KeyCode.ENTER) || (code == KeyCode.UNDEFINED)) { + return false; + } + + // gather the pressed modifier keys + String modifiers = ""; + if (evt.isControlDown()) { + modifiers = "ctrl "; + } + if (evt.isShiftDown()) { + modifiers += "shift "; + } + if (evt.isAltDown()) { + modifiers += "alt "; + } + + // if no modifier keys are pressed, only special keys can be shortcuts + if (modifiers.isEmpty()) { + if (!(code.isFunctionKey() || (code == KeyCode.ESCAPE) || (code == KeyCode.DELETE))) { + return false; + } + } + + String newShortcut = modifiers + code; + setBinding(newShortcut); + + return true; + } + + /** + * This method will reset the key bind of this models KeyBinding object to it's default bind + * + * @param keyBindingRepository as KeyBindingRepository + */ + public void resetToDefault(KeyBindingRepository keyBindingRepository) { + if (!isCategory()) { + String key = getKeyBinding().getKey(); + keyBindingRepository.resetToDefault(key); + setBinding(keyBindingRepository.get(key)); + } + } + +} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialog.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialog.java deleted file mode 100644 index ef4acdb98b4..00000000000 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialog.java +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2003-2015 JabRef contributors. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -package net.sf.jabref.gui.keyboard; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JOptionPane; -import javax.swing.JScrollPane; -import javax.swing.ListSelectionModel; -import javax.swing.table.TableColumnModel; - -import net.sf.jabref.Globals; -import net.sf.jabref.gui.GUIGlobals; -import net.sf.jabref.logic.l10n.Localization; - -/** - * Dialog to customize key bindings - */ -@SuppressWarnings("serial") -public class KeyBindingsDialog extends JDialog { - - private final JButton ok = new JButton(Localization.lang("OK")); - - private final JButton cancel = new JButton(Localization.lang("Cancel")); - private final JButton resetToDefaultKeyBindings = new JButton(Localization.lang("Default")); - private final JButton grabB = new JButton(Localization.lang("Grab")); - private final Box buttonBox = new Box(BoxLayout.X_AXIS); - - // stores the user-selected key bindings - private final KeyBindingRepository keyBindingRepository; - - private final KeyBindingTable table; - - public KeyBindingsDialog(KeyBindingRepository keyBindingRepository) { - super(); - setTitle(Localization.lang("Key bindings")); - setModal(true); //this needs to be modal so that client knows when ok or cancel was clicked - getContentPane().setLayout(new BorderLayout()); - this.keyBindingRepository = keyBindingRepository; - this.table = setupTable(); - updateTableData(); - //JScrollPane listScroller = new JScrollPane(list); - JScrollPane listScroller = new JScrollPane(table); - listScroller.setPreferredSize(new Dimension(250, 400)); - getContentPane().add(listScroller, BorderLayout.CENTER); - - grabB.addKeyListener(new KeyBindingsListener(table)); - buttonBox.add(grabB); - buttonBox.add(resetToDefaultKeyBindings); - buttonBox.add(ok); - buttonBox.add(cancel); - - getContentPane().add(buttonBox, BorderLayout.SOUTH); - //setTop(); - activateListeners(); - - KeyBinder.bindCloseDialogKeyToCancelAction(getRootPane(), cancel.getAction()); - - addWindowListener(new WindowAdapter() { - - @Override - public void windowClosing(WindowEvent e) { - dispose(); - } - }); - } - - private KeyBindingTable setupTable() { - KeyBindingTable table = new KeyBindingTable(); - table.setRowSelectionAllowed(true); - table.setColumnSelectionAllowed(false); - table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - table.setAutoCreateRowSorter(true); - return table; - } - - private void updateTableData() { - KeyBindingTableModel tableModel = new KeyBindingTableModel(keyBindingRepository); - table.setModel(tableModel); - - // has to be done each time as the columnModel is dependent on the tableModel - TableColumnModel cm = table.getColumnModel(); - cm.getColumn(0).setPreferredWidth(GUIGlobals.KEYBIND_COL_0); - cm.getColumn(1).setPreferredWidth(GUIGlobals.KEYBIND_COL_1); - } - - private void activateListeners() { - ok.addActionListener(e -> { - // save all the key bindings - Globals.getKeyPrefs().setNewKeyBindings(keyBindingRepository.getKeyBindings()); - - // show message - JOptionPane.showMessageDialog - (KeyBindingsDialog.this, - Localization.lang("Your new key bindings have been stored.") + '\n' - + Localization.lang("You must restart JabRef for the new key " - + "bindings to work properly."), - Localization.lang("Key bindings changed"), - JOptionPane.INFORMATION_MESSAGE); - - dispose(); - }); - cancel.addActionListener(e -> dispose()); - resetToDefaultKeyBindings.addActionListener(e -> { - int[] selected = table.getSelectedRows(); - boolean hasNothingSelected = selected.length == 0; - if (hasNothingSelected) { - int answer = JOptionPane.showOptionDialog(KeyBindingsDialog.this, - Localization.lang("All key bindings will be reset to their defaults.") + " " + - Localization.lang("Continue?"), - Localization.lang("Resetting all key bindings"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, null, - new String[] {Localization.lang("OK"), - Localization.lang("Cancel")}, - Localization.lang("OK")); - if (answer == JOptionPane.YES_OPTION) { - keyBindingRepository.resetToDefault(); - updateTableData(); - } - } else { - for (int row : selected) { - String name = String.valueOf(table.getValueAt(row, 0)); - keyBindingRepository.resetToDefault(name); - String newKey = keyBindingRepository.get(name); - table.setValueAt(newKey, row, 1); - table.repaint(); - } - } - }); - - } -} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogView.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogView.java new file mode 100644 index 00000000000..9638ebbdd36 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogView.java @@ -0,0 +1,30 @@ +package net.sf.jabref.gui.keyboard; + +import net.sf.jabref.gui.FXAlert; +import net.sf.jabref.logic.l10n.Localization; + +import com.airhacks.afterburner.views.FXMLView; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.DialogPane; +import javafx.stage.Stage; + +public class KeyBindingsDialogView extends FXMLView { + + public KeyBindingsDialogView() { + super(); + bundle = Localization.getMessages(); + } + + public void show(KeyBindingPreferences keyBindingPreferences) { + FXAlert keyBindingsDialog = new FXAlert(AlertType.INFORMATION, Localization.lang("Key bindings")); + keyBindingsDialog.setDialogPane((DialogPane) this.getView()); + KeyBindingsDialogViewModel controller = (KeyBindingsDialogViewModel) fxmlLoader.getController(); + controller.setKeyBindingPreferences(keyBindingPreferences); + controller.initializeView(); + keyBindingsDialog.setResizable(true); + ((Stage) keyBindingsDialog.getDialogPane().getScene().getWindow()).setMinHeight(475); + ((Stage) keyBindingsDialog.getDialogPane().getScene().getWindow()).setMinWidth(375); + keyBindingsDialog.show(); + } + +} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogViewModel.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogViewModel.java new file mode 100644 index 00000000000..5b7e36b2763 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsDialogViewModel.java @@ -0,0 +1,207 @@ +/* Copyright (C) 2016 JabRef contributors. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +package net.sf.jabref.gui.keyboard; + +import net.sf.jabref.gui.FXDialogs; +import net.sf.jabref.gui.IconTheme; +import net.sf.jabref.logic.l10n.Localization; + +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonBar; +import javafx.scene.control.ButtonBar.ButtonData; +import javafx.scene.control.ButtonType; +import javafx.scene.control.SelectionMode; +import javafx.scene.control.TreeItem; +import javafx.scene.control.TreeTableCell; +import javafx.scene.control.TreeTableColumn; +import javafx.scene.control.TreeTableView; +import javafx.scene.input.KeyEvent; +import javafx.scene.text.Text; +import javafx.stage.Stage; +import javafx.util.Callback; + +public class KeyBindingsDialogViewModel { + + private KeyBindingRepository keyBindingRepository; + private KeyBindingPreferences keyBindingPreferences; + private final ObjectProperty> selectedKeyBinding = new SimpleObjectProperty<>(); + + + @FXML + private TreeTableView keyBindingsTable; + + @FXML + private TreeTableColumn actionColumn; + + @FXML + private TreeTableColumn shortcutColumn; + + @FXML + private TreeTableColumn resetColumn; + + @FXML + private Button closeButton; + + @FXML + private Button resetButton; + + + @FXML + private void initialize() { + keyBindingsTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); + ButtonBar.setButtonData(resetButton, ButtonData.LEFT); + selectedKeyBinding.bind(keyBindingsTable.getSelectionModel().selectedItemProperty()); + } + + public void initializeView() { + registerKeyEvents(); + populateTable(); + bindColumnValues(); + } + + /** + * Read all keybindings from the keybinding repository and create table keybinding + * models for them + */ + private void populateTable() { + TreeItem root = new TreeItem<>(new KeyBindingViewModel(KeyBindingCategory.FILE)); + for (KeyBindingCategory category : KeyBindingCategory.values()) { + TreeItem categoryItem = new TreeItem<>(new KeyBindingViewModel(category)); + keyBindingRepository.getKeyBindings().forEach((keyBinding, bind) -> { + if (keyBinding.getCategory() == category) { + KeyBindingViewModel keyBindViewModel = new KeyBindingViewModel(keyBinding, bind); + TreeItem keyBindTreeItem = new TreeItem<>(keyBindViewModel); + categoryItem.getChildren().add(keyBindTreeItem); + } + }); + categoryItem.setExpanded(true); + root.getChildren().add(categoryItem); + } + root.setExpanded(true); + keyBindingsTable.setRoot(root); + } + + private void bindColumnValues() { + actionColumn.setCellValueFactory(cellData -> cellData.getValue().getValue().nameProperty()); + shortcutColumn.setCellValueFactory(cellData -> cellData.getValue().getValue().shownBindingProperty()); + resetColumn.setCellFactory( + new Callback, TreeTableCell>() { + + @Override + public TreeTableCell call( + TreeTableColumn p) { + return new TreeTableCell() { + + @Override + public void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + KeyBindingViewModel viewModel = getTreeTableRow().getItem(); + if ((viewModel != null) && !viewModel.isCategory()) { + Text graphic = new Text(IconTheme.JabRefIcon.CLEANUP_ENTRIES.getCode()); + graphic.getStyleClass().add("icon"); + setGraphic(graphic); + setOnMouseClicked(evt -> { + getTreeTableRow().getItem().resetToDefault(keyBindingRepository); + }); + + } + keyBindingsTable.refresh(); + } + }; + } + }); + } + + private void registerKeyEvents() { + keyBindingsTable.setOnKeyPressed(evt -> grabKey(evt)); + } + + private Stage getDialogStage() { + return (Stage) closeButton.getScene().getWindow(); + } + + @FXML + private void closeDialog() { + Stage stage = getDialogStage(); + stage.close(); + } + + public void saveKeyBindings() { + keyBindingPreferences.setNewKeyBindings(keyBindingRepository.getKeyBindings()); + } + + @FXML + private void saveKeyBindingsAndCloseDialog() { + saveKeyBindings(); + + String title = Localization.lang("Key bindings changed"); + String content = Localization.lang("Your new key bindings have been stored.") + '\n' + + Localization.lang("You must restart JabRef for the new key bindings to work properly."); + FXDialogs.showInformationDialogAndWait(title, content); + closeDialog(); + } + + @FXML + private void setDefaultBindings() { + String title = Localization.lang("Resetting all key bindings"); + String content = Localization.lang("All key bindings will be reset to their defaults."); + ButtonType resetButtonType = new ButtonType("Reset", ButtonData.OK_DONE); + FXDialogs.showCustomButtonDialogAndWait(AlertType.INFORMATION, title, content, resetButtonType, + ButtonType.CANCEL).ifPresent(response -> { + if (response == resetButtonType) { + resetKeyBindingsToDefault(); + populateTable(); + } + }); + } + + public void resetKeyBindingsToDefault() { + keyBindingRepository.resetToDefault(); + } + + public void grabKey(KeyEvent evt) { + // first check if a valid entry is selected + if (selectedKeyBinding.isNull().get()) { + return; + } + KeyBindingViewModel selectedEntry = selectedKeyBinding.get().getValue(); + if ((selectedEntry == null) || (selectedEntry.isCategory())) { + return; + } + + if (selectedEntry.setNewBinding(evt)) { + keyBindingRepository.put(selectedEntry.getKeyBinding(), selectedEntry.getBinding()); + } + } + + public void setKeyBindingPreferences(KeyBindingPreferences keyBindingPreferences) { + this.keyBindingPreferences = keyBindingPreferences; + this.keyBindingRepository = new KeyBindingRepository(keyBindingPreferences.getKeyBindings()); + } + + public ObjectProperty> getSelectedKeyBinding() { + return selectedKeyBinding; + } + + public KeyBindingRepository getKeyBindingRepository() { + return keyBindingRepository; + } + +} diff --git a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsListener.java b/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsListener.java deleted file mode 100644 index 21816534477..00000000000 --- a/src/main/java/net/sf/jabref/gui/keyboard/KeyBindingsListener.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.sf.jabref.gui.keyboard; - -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; - -/** - * respond to grabKey and display the key binding - */ -public class KeyBindingsListener extends KeyAdapter { - - private final KeyBindingTable table; - - public KeyBindingsListener(KeyBindingTable table) { - this.table = table; - } - - @Override - public void keyPressed(KeyEvent evt) { - // first check if anything is selected if not the return - final int selRow = table.getSelectedRow(); - boolean isAnyRowSelected = selRow >= 0; - if (!isAnyRowSelected) { - return; - } - - final String modifier = KeyEvent.getKeyModifiersText(evt.getModifiers()); - - // VALIDATE code and modifier - // all key bindings must have a modifier: ctrl alt etc - if ("".equals(modifier)) { - int kc = evt.getKeyCode(); - boolean isFunctionKey = (kc >= KeyEvent.VK_F1) && (kc <= KeyEvent.VK_F12); - boolean isEscapeKey = kc == KeyEvent.VK_ESCAPE; - boolean isDeleteKey = kc == KeyEvent.VK_DELETE; - if (!(isFunctionKey || isEscapeKey || isDeleteKey)) { - return; // need a modifier except for function, escape and delete keys - } - } - - final String code = KeyEvent.getKeyText(evt.getKeyCode()); - // second key cannot be a modifiers - if ("Tab".equals(code) - || "Backspace".equals(code) - || "Enter".equals(code) - || "Space".equals(code) - || "Ctrl".equals(code) - || "Shift".equals(code) - || "Alt".equals(code)) { - return; - } - - // COMPUTE new key binding - String newKey; - if ("".equals(modifier)) { - newKey = code; - } else { - newKey = modifier.toLowerCase().replace("+", " ") + " " + code; - } - - // SHOW new key binding - //find which key is selected and set its value - table.setValueAt(newKey, selRow, 1); - table.revalidate(); - table.repaint(); - } -} diff --git a/src/main/resources/l10n/JabRef_da.properties b/src/main/resources/l10n/JabRef_da.properties index 35365fee5d9..82256f27e7a 100644 --- a/src/main/resources/l10n/JabRef_da.properties +++ b/src/main/resources/l10n/JabRef_da.properties @@ -1695,3 +1695,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_de.properties b/src/main/resources/l10n/JabRef_de.properties index 69dc6eea8be..bb2c242406b 100644 --- a/src/main/resources/l10n/JabRef_de.properties +++ b/src/main/resources/l10n/JabRef_de.properties @@ -2410,3 +2410,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings=Schnellzugriffe_zurücksetzten +BibTeX=BibTeX +Tools=Werkzeuge diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index ec91bcaee72..8983c2c9f80 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2273,3 +2273,6 @@ BibTeX_key=BibTeX_key Message=Message MathSciNet_Review=MathSciNet_Review +Reset_Bindings=Reset_Bindings +BibTeX=BibTeX +Tools=Tools diff --git a/src/main/resources/l10n/JabRef_es.properties b/src/main/resources/l10n/JabRef_es.properties index 9ea2af30447..f6a2445ae55 100644 --- a/src/main/resources/l10n/JabRef_es.properties +++ b/src/main/resources/l10n/JabRef_es.properties @@ -1595,3 +1595,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_fa.properties b/src/main/resources/l10n/JabRef_fa.properties index c7758b5f908..38f70b5877d 100644 --- a/src/main/resources/l10n/JabRef_fa.properties +++ b/src/main/resources/l10n/JabRef_fa.properties @@ -2381,3 +2381,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_fr.properties b/src/main/resources/l10n/JabRef_fr.properties index 72be164bc7e..6380b1f9eb9 100644 --- a/src/main/resources/l10n/JabRef_fr.properties +++ b/src/main/resources/l10n/JabRef_fr.properties @@ -1638,3 +1638,6 @@ booktitle_ends_with_'conference_on'= BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_in.properties b/src/main/resources/l10n/JabRef_in.properties index 91164e55ec1..803b402cf45 100644 --- a/src/main/resources/l10n/JabRef_in.properties +++ b/src/main/resources/l10n/JabRef_in.properties @@ -1614,3 +1614,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_it.properties b/src/main/resources/l10n/JabRef_it.properties index e374dac1b18..ade6cc046a1 100644 --- a/src/main/resources/l10n/JabRef_it.properties +++ b/src/main/resources/l10n/JabRef_it.properties @@ -1715,3 +1715,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_ja.properties b/src/main/resources/l10n/JabRef_ja.properties index 93ec782a520..ab52383860a 100644 --- a/src/main/resources/l10n/JabRef_ja.properties +++ b/src/main/resources/l10n/JabRef_ja.properties @@ -2360,3 +2360,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_nl.properties b/src/main/resources/l10n/JabRef_nl.properties index c54513991da..17fd28ff628 100644 --- a/src/main/resources/l10n/JabRef_nl.properties +++ b/src/main/resources/l10n/JabRef_nl.properties @@ -2390,3 +2390,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_no.properties b/src/main/resources/l10n/JabRef_no.properties index 268b0498054..91c89dde816 100644 --- a/src/main/resources/l10n/JabRef_no.properties +++ b/src/main/resources/l10n/JabRef_no.properties @@ -2787,3 +2787,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_pt_BR.properties b/src/main/resources/l10n/JabRef_pt_BR.properties index c4e01aa71cc..1ef17457dd8 100644 --- a/src/main/resources/l10n/JabRef_pt_BR.properties +++ b/src/main/resources/l10n/JabRef_pt_BR.properties @@ -1609,3 +1609,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_ru.properties b/src/main/resources/l10n/JabRef_ru.properties index ff48cafe599..73aed760678 100644 --- a/src/main/resources/l10n/JabRef_ru.properties +++ b/src/main/resources/l10n/JabRef_ru.properties @@ -2358,3 +2358,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_sv.properties b/src/main/resources/l10n/JabRef_sv.properties index f501ac64e55..90a2ce9cc5c 100644 --- a/src/main/resources/l10n/JabRef_sv.properties +++ b/src/main/resources/l10n/JabRef_sv.properties @@ -1554,3 +1554,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_tr.properties b/src/main/resources/l10n/JabRef_tr.properties index 5903ff43293..f3539563c1e 100644 --- a/src/main/resources/l10n/JabRef_tr.properties +++ b/src/main/resources/l10n/JabRef_tr.properties @@ -1628,3 +1628,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_vi.properties b/src/main/resources/l10n/JabRef_vi.properties index ca38158c5f8..7e8b4fff719 100644 --- a/src/main/resources/l10n/JabRef_vi.properties +++ b/src/main/resources/l10n/JabRef_vi.properties @@ -2382,3 +2382,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index ff4b3000e53..de41e3dd289 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -1621,3 +1621,6 @@ BibTeX_key= Message= MathSciNet_Review= +Reset_Bindings= +BibTeX= +Tools= diff --git a/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.css b/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.css new file mode 100644 index 00000000000..d09aa2ece29 --- /dev/null +++ b/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.css @@ -0,0 +1,22 @@ +.keybinding-table { + -fx-table-cell-border-color: transparent; +} + +.tree-table-row-cell:empty { + visibility: hidden; +} + +.tree-table-row-cell > .tree-table-cell > .icon { + -fx-font-family: 'Material Design Icons'; + -fx-font-size: 16; + -fx-fill: #5e5f5e; +} + +.tree-table-row-cell:selected > .tree-table-cell > .icon, .tree-table-row-cell:pressed > .tree-table-cell > .icon { + -fx-fill: white; +} + +.dialog-pane *.button-bar { + -fx-max-height: 0; + -fx-pref-height: 0; +} diff --git a/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.fxml b/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.fxml new file mode 100644 index 00000000000..4c3ffdabd54 --- /dev/null +++ b/src/main/resources/net/sf/jabref/gui/keyboard/KeyBindingsDialog.fxml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + +