diff --git a/build.gradle b/build.gradle index 69a9283deb0..790f84c8269 100644 --- a/build.gradle +++ b/build.gradle @@ -119,8 +119,6 @@ dependencies { compile 'org.postgresql:postgresql:42.2.6' - compile 'net.java.dev.glazedlists:glazedlists_java15:1.9.1' - compile 'com.google.guava:guava:28.0-jre' // JavaFX stuff diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 5aaffe6c20f..aa0b1aa6188 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.StringReader; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; @@ -14,7 +13,6 @@ import java.util.Set; import java.util.stream.Collectors; -import javax.swing.SwingUtilities; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; @@ -45,12 +43,8 @@ import org.jabref.gui.exporter.SaveDatabaseAction; import org.jabref.gui.exporter.WriteXMPAction; import org.jabref.gui.externalfiles.FindFullTextAction; -import org.jabref.gui.externalfiletype.ExternalFileMenuItem; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; -import org.jabref.gui.filelist.FileListEntry; -import org.jabref.gui.filelist.FileListTableModel; -import org.jabref.gui.icon.JabRefIcon; import org.jabref.gui.importer.actions.AppendDatabaseAction; import org.jabref.gui.journals.AbbreviateAction; import org.jabref.gui.journals.UnabbreviateAction; @@ -92,6 +86,7 @@ import org.jabref.model.database.shared.DatabaseLocation; import org.jabref.model.database.shared.DatabaseSynchronizer; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FileFieldParser; import org.jabref.model.entry.LinkedFile; import org.jabref.model.entry.event.EntryChangedEvent; import org.jabref.model.entry.event.EntryEventSource; @@ -342,25 +337,25 @@ private void setupActions() { actions.put(Actions.REPLACE_ALL, () -> (new ReplaceStringAction(this)).execute()); actions.put(new SpecialFieldValueViewModel(SpecialField.RELEVANCE.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.RELEVANCE, undoManager).getSpecialFieldAction(SpecialField.RELEVANCE.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.RELEVANCE, undoManager).getSpecialFieldAction(SpecialField.RELEVANCE.getValues().get(0), frame)); actions.put(new SpecialFieldValueViewModel(SpecialField.QUALITY.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.QUALITY, undoManager).getSpecialFieldAction(SpecialField.QUALITY.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.QUALITY, undoManager).getSpecialFieldAction(SpecialField.QUALITY.getValues().get(0), frame)); actions.put(new SpecialFieldValueViewModel(SpecialField.PRINTED.getValues().get(0)).getCommand(), - new SpecialFieldViewModel(SpecialField.PRINTED, undoManager).getSpecialFieldAction(SpecialField.PRINTED.getValues().get(0), frame)); + new SpecialFieldViewModel(SpecialField.PRINTED, undoManager).getSpecialFieldAction(SpecialField.PRINTED.getValues().get(0), frame)); for (SpecialFieldValue prio : SpecialField.PRIORITY.getValues()) { actions.put(new SpecialFieldValueViewModel(prio).getCommand(), - new SpecialFieldViewModel(SpecialField.PRIORITY, undoManager).getSpecialFieldAction(prio, this.frame)); + new SpecialFieldViewModel(SpecialField.PRIORITY, undoManager).getSpecialFieldAction(prio, this.frame)); } for (SpecialFieldValue rank : SpecialField.RANKING.getValues()) { actions.put(new SpecialFieldValueViewModel(rank).getCommand(), - new SpecialFieldViewModel(SpecialField.RANKING, undoManager).getSpecialFieldAction(rank, this.frame)); + new SpecialFieldViewModel(SpecialField.RANKING, undoManager).getSpecialFieldAction(rank, this.frame)); } for (SpecialFieldValue status : SpecialField.READ_STATUS.getValues()) { actions.put(new SpecialFieldValueViewModel(status).getCommand(), - new SpecialFieldViewModel(SpecialField.READ_STATUS, undoManager).getSpecialFieldAction(status, this.frame)); + new SpecialFieldViewModel(SpecialField.READ_STATUS, undoManager).getSpecialFieldAction(status, this.frame)); } actions.put(Actions.TOGGLE_PREVIEW, () -> { @@ -532,7 +527,7 @@ private void copyKeyAndTitle() { Layout layout; try { layout = new LayoutHelper(sr, Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader)) - .getLayoutFromText(); + .getLayoutFromText(); } catch (IOException e) { LOGGER.info("Could not get layout", e); return; @@ -579,16 +574,21 @@ private void openExternalFile() { new SearchAndOpenFile(entry, BasePanel.this).searchAndOpen(); return; } - FileListTableModel fileListTableModel = new FileListTableModel(); - entry.getField(StandardField.FILE).ifPresent(fileListTableModel::setContent); - if (fileListTableModel.getRowCount() == 0) { + + List files = new ArrayList<>(); + entry.getField(StandardField.FILE).map(FileFieldParser::parse).ifPresent(files::addAll); + + if (files.isEmpty()) { // content in BibTeX field is not readable new SearchAndOpenFile(entry, BasePanel.this).searchAndOpen(); return; } - FileListEntry flEntry = fileListTableModel.getEntry(0); - ExternalFileMenuItem item = new ExternalFileMenuItem(frame(), "", flEntry.getLink(), flEntry.getType().map(ExternalFileType::getIcon).map(JabRefIcon::getSmallIcon).orElse(null), bibDatabaseContext, flEntry.getType()); - item.doClick(); + LinkedFile flEntry = files.get(0); + try { + JabRefDesktop.openExternalFileAnyFormat(this.getBibDatabaseContext(), flEntry.getLink(), ExternalFileTypes.getInstance().fromLinkedFile(flEntry, true)); + } catch (IOException ex) { + dialogService.showErrorDialogAndWait(ex); + } }); } @@ -828,9 +828,8 @@ public EntryEditor getEntryEditor() { } /** - * Sets the entry editor as the bottom component in the split pane. If an entry editor already was shown, - * makes sure that the divider doesn't move. Updates the mode to SHOWING_EDITOR. - * Then shows the given entry. + * Sets the entry editor as the bottom component in the split pane. If an entry editor already was shown, makes sure + * that the divider doesn't move. Updates the mode to SHOWING_EDITOR. Then shows the given entry. * * @param entry The entry to edit. */ @@ -949,8 +948,7 @@ public void entryEditorClosing(EntryEditor editor) { * Closes the entry editor or preview panel if it is showing the given entry. */ public void ensureNotShowingBottomPanel(BibEntry entry) { - if (((mode == BasePanelMode.SHOWING_EDITOR) && (entryEditor.getEntry() == entry)) - || ((mode == BasePanelMode.SHOWING_PREVIEW))) { + if (((mode == BasePanelMode.SHOWING_EDITOR) && (entryEditor.getEntry() == entry)) || ((mode == BasePanelMode.SHOWING_PREVIEW))) { closeBottomPane(); } } @@ -964,16 +962,7 @@ public void updateEntryEditorIfShowing() { public void markBaseChanged() { baseChanged = true; - - if (SwingUtilities.isEventDispatchThread()) { - markBasedChangedInternal(); - } else { - try { - SwingUtilities.invokeAndWait(() -> markBasedChangedInternal()); - } catch (InvocationTargetException | InterruptedException e) { - LOGGER.info("Problem marking database as changed", e); - } - } + markBasedChangedInternal(); } private void markBasedChangedInternal() { @@ -1021,18 +1010,19 @@ public boolean showDeleteConfirmationDialog(int numberOfEntries) { } return dialogService.showConfirmationDialogWithOptOutAndWait(title, - message, - okButton, - cancelButton, - Localization.lang("Disable this confirmation dialog"), - optOut -> Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, !optOut)); + message, + okButton, + cancelButton, + Localization.lang("Disable this confirmation dialog"), + optOut -> Globals.prefs.putBoolean(JabRefPreferences.CONFIRM_DELETE, !optOut)); } else { return true; } } /** - * Depending on whether a preview or an entry editor is showing, save the current divider location in the correct preference setting. + * Depending on whether a preview or an entry editor is showing, save the current divider location in the correct + * preference setting. */ private void saveDividerLocation(Number position) { if (position == null) { @@ -1224,7 +1214,7 @@ public void listen(EntryAddedEvent addedEntryEvent) { if (Globals.prefs.getBoolean(JabRefPreferences.AUTO_ASSIGN_GROUP)) { final List entries = Collections.singletonList(addedEntryEvent.getBibEntry()); Globals.stateManager.getSelectedGroup(bibDatabaseContext).forEach( - selectedGroup -> selectedGroup.addEntriesToGroup(entries)); + selectedGroup -> selectedGroup.addEntriesToGroup(entries)); } } } @@ -1239,8 +1229,7 @@ public void listen(EntryRemovedEvent entryRemovedEvent) { /** * Ensures that the search auto completer is up to date when entries are changed AKA Let the auto completer, if any, - * harvest words from the entry - * Actual methods for autocomplete indexing must run in javafx thread + * harvest words from the entry Actual methods for autocomplete indexing must run in javafx thread */ private class SearchAutoCompleteListener { @@ -1256,8 +1245,8 @@ public void listen(EntryChangedEvent entryChangedEvent) { } /** - * Ensures that the results of the current search are updated when a new entry is inserted into the database - * Actual methods for performing search must run in javafx thread + * Ensures that the results of the current search are updated when a new entry is inserted into the database Actual + * methods for performing search must run in javafx thread */ private class SearchListener { @@ -1331,8 +1320,8 @@ public void action() { try { JabRefDesktop.openExternalFileAnyFormat(bibDatabaseContext, - linkedFile.get().getLink(), - ExternalFileTypes.getInstance().fromLinkedFile(linkedFile.get(), true)); + linkedFile.get().getLink(), + ExternalFileTypes.getInstance().fromLinkedFile(linkedFile.get(), true)); output(Localization.lang("External viewer called") + '.'); } catch (IOException e) { diff --git a/src/main/java/org/jabref/gui/GUIGlobals.java b/src/main/java/org/jabref/gui/GUIGlobals.java index 12d55f69bbe..909465a1e43 100644 --- a/src/main/java/org/jabref/gui/GUIGlobals.java +++ b/src/main/java/org/jabref/gui/GUIGlobals.java @@ -1,11 +1,10 @@ package org.jabref.gui; -import java.awt.Color; -import java.awt.Font; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.gui.icon.IconTheme; -import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.gui.util.CustomLocalDragboard; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -45,20 +44,15 @@ public static void updateEntryEditorColors() { * on Un*x is unavailable. */ public static void init() { - if (Globals.prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS)) { - EmacsKeyBindings.load(); - } - // Set up entry editor colors, first time: GUIGlobals.updateEntryEditorColors(); IconTheme.loadFonts(); - GUIGlobals.currentFont = new Font(Globals.prefs.get(JabRefPreferences.FONT_FAMILY), - Globals.prefs.getInt(JabRefPreferences.FONT_STYLE), Globals.prefs.getInt(JabRefPreferences.FONT_SIZE)); + GUIGlobals.currentFont = new Font(Globals.prefs.getFontFamily(), Globals.prefs.getDouble(JabRefPreferences.FONT_SIZE)); } - public static void setFont(int size) { - currentFont = new Font(currentFont.getFamily(), currentFont.getStyle(), size); + public static void setFont(double size) { + currentFont = new Font(currentFont.getFamily(), size); // update preferences Globals.prefs.putInt(JabRefPreferences.FONT_SIZE, size); } diff --git a/src/main/java/org/jabref/gui/JabRefDialog.java b/src/main/java/org/jabref/gui/JabRefDialog.java deleted file mode 100644 index 3221956a393..00000000000 --- a/src/main/java/org/jabref/gui/JabRefDialog.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.jabref.gui; - -import java.awt.Frame; - -import javax.swing.JDialog; - -import org.jabref.Globals; - -public class JabRefDialog extends JDialog { - - public JabRefDialog(boolean modal, Class clazz) { - this("JabRef", modal, clazz); - } - - public JabRefDialog(Class clazz) { - this(true, clazz); - } - - public JabRefDialog(String title, Class clazz) { - this(title, true, clazz); - } - - public JabRefDialog(String title, boolean modal, Class clazz) { - super((Frame) null, title, modal); - - trackDialogOpening(clazz); - } - - public JabRefDialog(java.awt.Dialog owner, String title, Class clazz) { - this(owner, title, true, clazz); - } - - public JabRefDialog(java.awt.Dialog owner, String title, boolean modal, Class clazz) { - super(owner, title, modal); - - trackDialogOpening(clazz); - } - - private void trackDialogOpening(Class clazz) { - Globals.getTelemetryClient().ifPresent(client -> client.trackPageView(clazz.getName())); - } - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - - if (visible) { - // FIXME: Ugly hack to ensure that new dialogs are not hidden behind the main window - setAlwaysOnTop(true); - requestFocus(); - setAlwaysOnTop(false); - } - } -} diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 4ce6c1c1ffc..de52c9fbc11 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -14,9 +14,6 @@ import java.util.TimerTask; import java.util.stream.Collectors; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -294,9 +291,7 @@ private void initShowTrackingNotification() { @Override public void run() { - SwingUtilities.invokeLater(() -> { DefaultTaskExecutor.runInJavaFXThread(JabRefFrame.this::showTrackingNotification); - }); } }, 60000); // run in one minute } @@ -402,6 +397,8 @@ private void tearDownJabRef(List filenames) { prefs.flush(); // dispose all windows, even if they are not displayed anymore + // TODO: javafx variant only avaiable in java 9 and updwards + // https://docs.oracle.com/javase/9/docs/api/javafx/stage/Window.html#getWindows-- for (Window window : Window.getWindows()) { window.dispose(); } @@ -1063,18 +1060,9 @@ public void setProgressBarVisible(final boolean visible) { /** * Sets the indeterminate status of the progress bar. *

- * If not called on the event dispatch thread, this method uses SwingUtilities.invokeLater() to do the actual - * operation on the EDT. */ public void setProgressBarIndeterminate(final boolean value) { - // TODO: Reimplement - /* - if (SwingUtilities.isEventDispatchThread()) { - progressBar.setIndeterminate(value); - } else { - SwingUtilities.invokeLater(() -> progressBar.setIndeterminate(value)); - } - */ + progressBar.setProgress(ProgressBar.INDETERMINATE_PROGRESS); } /** @@ -1107,10 +1095,6 @@ private boolean isExistURLorDOI(List selectEntryList) { return false; } - public void showMessage(String message) { - JOptionPane.showMessageDialog(null, message); - } - /** * Ask if the user really wants to close the given database * @@ -1297,7 +1281,7 @@ private void increaseTableFontSize() { } private void decreaseTableFontSize() { - int currentSize = GUIGlobals.currentFont.getSize(); + double currentSize = GUIGlobals.currentFont.getSize(); if (currentSize < 2) { return; } diff --git a/src/main/java/org/jabref/gui/customentrytypes/FieldSetComponent.java b/src/main/java/org/jabref/gui/customentrytypes/FieldSetComponent.java deleted file mode 100644 index be7dc8efc6f..00000000000 --- a/src/main/java/org/jabref/gui/customentrytypes/FieldSetComponent.java +++ /dev/null @@ -1,351 +0,0 @@ -package org.jabref.gui.customentrytypes; - -import java.awt.Component; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import javax.swing.Box; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; -import javax.swing.JViewport; -import javax.swing.ListSelectionModel; -import javax.swing.ScrollPaneConstants; -import javax.swing.event.ListDataListener; -import javax.swing.event.ListSelectionListener; - -import org.jabref.Globals; -import org.jabref.gui.icon.IconTheme; -import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; -import org.jabref.logic.l10n.Localization; -import org.jabref.preferences.JabRefPreferences; - -class FieldSetComponent extends JPanel { - - protected final JList list; - protected DefaultListModel listModel; - protected final JButton remove; - protected final GridBagLayout gbl = new GridBagLayout(); - protected final GridBagConstraints con = new GridBagConstraints(); - protected final boolean forceLowerCase; - protected boolean changesMade; - private final Set additionListeners = new HashSet<>(); - private final JScrollPane sp; - private JComboBox sel; - private JTextField input; - private final JButton add; - private JButton up; - private JButton down; - private final Set modelListeners = new HashSet<>(); - - - /** - * Creates a new instance of FieldSetComponent, with preset selection - * values. These are put into a JComboBox. - */ - public FieldSetComponent(String title, List fields, List preset, boolean arrows, boolean forceLowerCase) { - this(title, fields, preset, Localization.lang("Add"), - Localization.lang("Remove"), arrows, forceLowerCase); - } - - /** - * Creates a new instance of FieldSetComponent without preset selection - * values. Replaces the JComboBox with a JTextField. - */ - FieldSetComponent(String title, List fields, boolean arrows, boolean forceLowerCase) { - this(title, fields, null, Localization.lang("Add"), - Localization.lang("Remove"), arrows, forceLowerCase); - } - - private FieldSetComponent(String title, List fields, List preset, String addText, String removeText, - boolean arrows, boolean forceLowerCase) { - this.forceLowerCase = forceLowerCase; - add = new JButton(addText); - remove = new JButton(removeText); - listModel = new DefaultListModel<>(); - JLabel title1 = null; - if (title != null) { - title1 = new JLabel(title); - } - - for (String field : fields) { - listModel.addElement(field); - } - list = new JList<>(listModel); - list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - // Set up GUI: - add.addActionListener(e -> { - // Selection has been made, or add button pressed: - if ((sel != null) && (sel.getSelectedItem() != null)) { - String s = sel.getSelectedItem().toString(); - addField(s); - } else if ((input != null) && !"".equals(input.getText())) { - addField(input.getText()); - } - }); - remove.addActionListener(e -> removeSelected()); // Remove button pressed - - setLayout(gbl); - con.insets = new Insets(1, 1, 1, 1); - con.fill = GridBagConstraints.BOTH; - con.weightx = 1; - con.gridwidth = GridBagConstraints.REMAINDER; - if (title1 != null) { - gbl.setConstraints(title1, con); - add(title1); - } - - con.weighty = 1; - sp = new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - gbl.setConstraints(sp, con); - add(sp); - con.weighty = 0; - con.gridwidth = 1; - if (arrows) { - con.weightx = 0; - up = new JButton(IconTheme.JabRefIcons.UP.getSmallIcon()); - down = new JButton(IconTheme.JabRefIcons.DOWN.getSmallIcon()); - up.addActionListener(e -> move(-1)); - down.addActionListener(e -> move(1)); - up.setToolTipText(Localization.lang("Move up")); - down.setToolTipText(Localization.lang("Move down")); - gbl.setConstraints(up, con); - add(up); - gbl.setConstraints(down, con); - add(down); - con.weightx = 0; - } - - Component strut = Box.createHorizontalStrut(5); - gbl.setConstraints(strut, con); - add(strut); - - con.weightx = 1; - con.gridwidth = GridBagConstraints.REMAINDER; - - //Component b = Box.createHorizontalGlue(); - //gbl.setConstraints(b, con); - //add(b); - - //if (!arrows) - con.gridwidth = GridBagConstraints.REMAINDER; - gbl.setConstraints(remove, con); - add(remove); - - con.gridwidth = 3; - con.weightx = 1; - if (preset == null) { - input = new JTextField(20); - input.addActionListener(e -> addField(input.getText())); - gbl.setConstraints(input, con); - add(input); - } else { - sel = new JComboBox<>(preset.toArray(new String[preset.size()])); - sel.setEditable(true); - gbl.setConstraints(sel, con); - add(sel); - } - con.gridwidth = GridBagConstraints.REMAINDER; - con.weighty = 0; - con.weightx = 0.5; - con.gridwidth = 1; - gbl.setConstraints(add, con); - add(add); - - FieldListFocusListener fieldListFocusListener = new FieldListFocusListener<>(list); - list.addFocusListener(fieldListFocusListener); - } - - public void setListSelectionMode(int mode) { - list.setSelectionMode(mode); - } - - public void selectField(String fieldName) { - int idx = listModel.indexOf(fieldName); - if (idx >= 0) { - list.setSelectedIndex(idx); - } - - // Make sure it is visible: - JViewport viewport = sp.getViewport(); - Rectangle rectangle = list.getCellBounds(idx, idx); - if (rectangle != null) { - viewport.scrollRectToVisible(rectangle); - } - - } - - public String getFirstSelected() { - return list.getSelectedValue(); - } - - @Override - public void setEnabled(boolean en) { - if (input != null) { - input.setEnabled(en); - } - if (sel != null) { - sel.setEnabled(en); - } - if (up != null) { - up.setEnabled(en); - down.setEnabled(en); - } - add.setEnabled(en); - remove.setEnabled(en); - } - - /** - * Return the current list. - */ - public Set getFields() { - Set res = new LinkedHashSet<>(listModel.getSize()); - Enumeration elements = listModel.elements(); - while (elements.hasMoreElements()) { - res.add(elements.nextElement()); - } - return res; - } - - /** - * This method is called when a new field should be added to the list. Performs validation of the - * field. - */ - protected void addField(String str) { - String s = str.trim(); - if (forceLowerCase) { - s = s.toLowerCase(Locale.ROOT); - } - if ("".equals(s) || listModel.contains(s)) { - return; - } - - String testString = BibtexKeyGenerator.cleanKey(s, - Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); - if (!testString.equals(s) || (s.indexOf('&') >= 0)) { - // Report error and exit. - JOptionPane.showMessageDialog(this, Localization.lang("Field names are not allowed to contain white space or the following " - + "characters") + ": # { } ~ , ^ &", - Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); - - return; - } - addFieldUncritically(s); - } - - /** - * This method adds a new field to the list, without any regard to validation. This method can be - * useful for classes that overrides addField(s) to provide different validation. - */ - protected void addFieldUncritically(String s) { - listModel.addElement(s); - changesMade = true; - for (ActionListener additionListener : additionListeners) { - additionListener.actionPerformed(new ActionEvent(this, 0, s)); - } - - } - - protected void removeSelected() { - int[] selected = list.getSelectedIndices(); - if (selected.length > 0) { - changesMade = true; - } - for (int i = 0; i < selected.length; i++) { - listModel.removeElementAt(selected[selected.length - 1 - i]); - } - - } - - public void setFields(Set fields) { - DefaultListModel newListModel = new DefaultListModel<>(); - for (String field : fields) { - newListModel.addElement(field); - } - this.listModel = newListModel; - for (ListDataListener modelListener : modelListeners) { - newListModel.addListDataListener(modelListener); - } - list.setModel(newListModel); - } - - /** - * Add a ListSelectionListener to the JList component displayed as part of this component. - */ - public void addListSelectionListener(ListSelectionListener l) { - list.addListSelectionListener(l); - } - - /** - * Adds an ActionListener that will receive events each time a field is added. The ActionEvent - * will specify this component as source, and the added field as action command. - */ - public void addAdditionActionListener(ActionListener l) { - additionListeners.add(l); - } - - public void addListDataListener(ListDataListener l) { - listModel.addListDataListener(l); - modelListeners.add(l); - } - - /** - * If a field is selected in the list, move it dy positions. - */ - private void move(int dy) { - int oldIdx = list.getSelectedIndex(); - if (oldIdx < 0) { - return; - } - String o = listModel.get(oldIdx); - // Compute the new index: - int newInd = Math.max(0, Math.min(listModel.size() - 1, oldIdx + dy)); - listModel.remove(oldIdx); - listModel.add(newInd, o); - list.setSelectedIndex(newInd); - } - - /** - * FocusListener to select the first entry in the list of fields when they are focused - */ - protected class FieldListFocusListener implements FocusListener { - - private final JList list; - - public FieldListFocusListener(JList list) { - this.list = list; - } - - @Override - public void focusGained(FocusEvent e) { - if (list.getSelectedValue() == null) { - list.setSelectedIndex(0); - } - } - - @Override - public void focusLost(FocusEvent e) { - //focus should remain at the same position so nothing to do here - } - } - -} diff --git a/src/main/java/org/jabref/gui/externalfiles/TransferableFileLinkSelection.java b/src/main/java/org/jabref/gui/externalfiles/TransferableFileLinkSelection.java deleted file mode 100644 index 798189cb1c6..00000000000 --- a/src/main/java/org/jabref/gui/externalfiles/TransferableFileLinkSelection.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.jabref.gui.externalfiles; - -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.jabref.Globals; -import org.jabref.gui.BasePanel; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.LinkedFile; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - */ -public class TransferableFileLinkSelection implements Transferable { - - private static final Logger LOGGER = LoggerFactory.getLogger(TransferableFileLinkSelection.class); - - private final List fileList = new ArrayList<>(); - - public TransferableFileLinkSelection(BasePanel panel, List selection) { - BibEntry entry = selection.get(0); - List files = entry.getFiles(); - if (!files.isEmpty()) { - // Find the default directory for this field type, if any: - LinkedFile firstFile = files.get(0); - firstFile.findIn(panel.getBibDatabaseContext(), Globals.prefs.getFilePreferences()) - .ifPresent(fileList::add); - } - } - - @Override - public DataFlavor[] getTransferDataFlavors() { - return new DataFlavor[] {DataFlavor.javaFileListFlavor};//, DataFlavor.stringFlavor}; - } - - @Override - public boolean isDataFlavorSupported(DataFlavor dataFlavor) { - LOGGER.debug("Query: " + dataFlavor.getHumanPresentableName() + " , " - + - dataFlavor.getDefaultRepresentationClass() + " , " + dataFlavor.getMimeType()); - return dataFlavor.equals(DataFlavor.javaFileListFlavor) - || dataFlavor.equals(DataFlavor.stringFlavor); - } - - @Override - public Object getTransferData(DataFlavor dataFlavor) throws UnsupportedFlavorException, IOException { - //if (dataFlavor.equals(DataFlavor.javaFileListFlavor)) - return fileList; - //else - // return "test"; - } - /* - private StringSelection ss; - - public TransferableFileLinkSelection(BasePanel panel, BibEntry[] selection) { - String s = selection[0].getField(GUIGlobals.FILE_FIELD); - FileListTableModel tm = new FileListTableModel(); - if (s != null) - tm.setContent(s); - if (tm.getRowCount() > 0) { - // Find the default directory for this field type, if any: - String dir = panel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD); - // Include the standard "file" directory: - String fileDir = panel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD); - // Include the directory of the BIB file: - String[] dirs; - if (panel.metaData().getDatabaseFile() != null) { - String databaseDir = panel.metaData().getDatabaseFile().getParent(); - dirs = new String[] { dir, fileDir, databaseDir }; - } - else - dirs = new String[] { dir, fileDir }; - System.out.println(tm.getEntry(0).getLink()); - for (int i = 0; i < dirs.length; i++) { - String dir1 = dirs[i]; - System.out.println("dir:"+dir1); - } - File expLink = Util.expandFilename(tm.getEntry(0).getLink(), dirs); - try { - System.out.println(expLink.toURI().toURL().toString()); - ss = new StringSelection(expLink.toURI().toURL().toString()); - - } catch (MalformedURLException ex) { - ss = new StringSelection(""); - } - } - else - ss = new StringSelection(""); - - } - - public Transferable getTransferable() { - return ss; - } */ -} diff --git a/src/main/java/org/jabref/gui/externalfiletype/CustomExternalFileType.java b/src/main/java/org/jabref/gui/externalfiletype/CustomExternalFileType.java index 371060b64ca..5a4887c6fd3 100644 --- a/src/main/java/org/jabref/gui/externalfiletype/CustomExternalFileType.java +++ b/src/main/java/org/jabref/gui/externalfiletype/CustomExternalFileType.java @@ -2,8 +2,6 @@ import java.util.Objects; -import javax.swing.JLabel; - import org.jabref.gui.icon.IconTheme; import org.jabref.gui.icon.JabRefIcon; @@ -14,7 +12,6 @@ */ public class CustomExternalFileType implements ExternalFileType { - private final JLabel label = new JLabel(); private String name; private String extension; private String openWith; @@ -24,9 +21,7 @@ public class CustomExternalFileType implements ExternalFileType { public CustomExternalFileType(String name, String extension, String mimeType, String openWith, String iconName, JabRefIcon icon) { - label.setText(null); this.name = name; - label.setToolTipText(this.name); this.extension = extension; this.mimeType = mimeType; this.openWith = openWith; @@ -90,7 +85,6 @@ public String getName() { public void setName(String name) { this.name = name; - label.setToolTipText(this.name); } @Override @@ -129,16 +123,6 @@ public void setOpenWith(String openWith) { this.openWith = openWith; } - /** - * Obtain a JLabel instance set with this file type's icon. The same JLabel - * is returned from each call of this method. - * - * @return the label. - */ - public JLabel getIconLabel() { - return label; - } - /** * Get the string associated with this file type's icon. * @@ -165,7 +149,6 @@ public JabRefIcon getIcon() { public void setIcon(JabRefIcon icon) { Objects.requireNonNull(icon); this.icon = icon; - label.setIcon(this.icon.getSmallIcon()); } @Override diff --git a/src/main/java/org/jabref/gui/externalfiletype/ExternalFileMenuItem.java b/src/main/java/org/jabref/gui/externalfiletype/ExternalFileMenuItem.java index ffb071384e7..e69de29bb2d 100644 --- a/src/main/java/org/jabref/gui/externalfiletype/ExternalFileMenuItem.java +++ b/src/main/java/org/jabref/gui/externalfiletype/ExternalFileMenuItem.java @@ -1,92 +0,0 @@ -package org.jabref.gui.externalfiletype; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import javax.swing.Icon; -import javax.swing.JMenuItem; - -import org.jabref.Globals; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.desktop.JabRefDesktop; -import org.jabref.gui.util.DefaultTaskExecutor; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.util.FileHelper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The menu item used in the popup menu for opening external resources associated - * with an entry. Shows the resource name and icon given, and adds an action listener - * to process the request if the user clicks this menu item. - */ -public class ExternalFileMenuItem extends JMenuItem implements ActionListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(ExternalFileMenuItem.class); - - private final String link; - private final BibDatabaseContext databaseContext; - private Optional fileType; - private final JabRefFrame frame; - - public ExternalFileMenuItem(JabRefFrame frame, String name, String link, Icon icon, - BibDatabaseContext databaseContext, Optional fileType) { - super(name, icon); - this.frame = frame; - this.link = link; - this.databaseContext = databaseContext; - this.fileType = fileType; - addActionListener(this); - } - - @Override - public void actionPerformed(ActionEvent e) { - boolean success = openLink(); - if (!success) { - List searchedDirs = databaseContext.getFileDirectoriesAsPaths(Globals.prefs.getFilePreferences()); - frame.getDialogService().notify(Localization.lang("Unable to open %0", link) + " " + Arrays.toString(searchedDirs.toArray())); - } - } - - private boolean openLink() { - frame.getDialogService().notify(Localization.lang("External viewer called") + "."); - try { - Optional type = fileType; - if (!this.fileType.isPresent()) { - // We don't already know the file type, so we try to deduce it from the extension: - Optional extension = FileHelper.getFileExtension(link); - // Now we know the extension, check if it is one we know about: - type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(extension.orElse(null)); - fileType = type; - } - - return JabRefDesktop.openExternalFileAnyFormat(databaseContext, link, type); - - } catch (IOException ex) { - // See if we should show an error message concerning the application to open the - // link with. We check if the file type is set, and if the file type has a non-empty - // application link. If that link is referred by the error message, we can assume - // that the problem is in the open-with-application setting: - if ((fileType.isPresent()) && (!fileType.get().getOpenWithApplication().isEmpty()) - && ex.getMessage().contains(fileType.get().getOpenWithApplication())) { - - DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showErrorDialogAndWait(Localization.lang("Could not open link"), - Localization.lang("Unable to open link. " + "The application '%0' associated with the file type '%1' could not be called.", - fileType.get().getOpenWithApplication(), - fileType.get().getName()))); - - return false; - } - - LOGGER.warn("Unable to open link", ex); - } - return false; - } -} diff --git a/src/main/java/org/jabref/gui/filelist/FileListTableModel.java b/src/main/java/org/jabref/gui/filelist/FileListTableModel.java deleted file mode 100644 index 94a8f008e92..00000000000 --- a/src/main/java/org/jabref/gui/filelist/FileListTableModel.java +++ /dev/null @@ -1,187 +0,0 @@ -package org.jabref.gui.filelist; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.StringJoiner; - -import javax.swing.SwingUtilities; -import javax.swing.event.TableModelEvent; -import javax.swing.table.AbstractTableModel; - -import org.jabref.gui.externalfiletype.ExternalFileType; -import org.jabref.gui.externalfiletype.ExternalFileTypes; -import org.jabref.model.entry.FileFieldParser; -import org.jabref.model.entry.FileFieldWriter; -import org.jabref.model.entry.LinkedFile; - -/** - * Data structure to contain a list of file links, parseable from a coded string. - * Doubles as a table model for the file list editor. - * - * @deprecated use {@link org.jabref.model.entry.LinkedFile} instead - */ -@Deprecated -public class FileListTableModel extends AbstractTableModel { - - private final List list = new ArrayList<>(); - - @Override - public int getRowCount() { - synchronized (list) { - return list.size(); - } - } - - @Override - public int getColumnCount() { - return 3; - } - - @Override - public Class getColumnClass(int columnIndex) { - return String.class; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - synchronized (list) { - FileListEntry entry = list.get(rowIndex); - switch (columnIndex) { - case 0: - return entry.getDescription(); - case 1: - return entry.getLink(); - default: - return entry.getType().isPresent() ? entry.getType().get().getName() : ""; - } - } - } - - public FileListEntry getEntry(int index) { - synchronized (list) { - return list.get(index); - } - } - - public void setEntry(int index, FileListEntry entry) { - synchronized (list) { - list.set(index, entry); - fireTableRowsUpdated(index, index); - } - } - - public void removeEntry(int index) { - synchronized (list) { - list.remove(index); - fireTableRowsDeleted(index, index); - } - - } - - /** - * Add an entry to the table model, and fire a change event. The change event - * is fired on the event dispatch thread. - * @param index The row index to insert the entry at. - * @param entry The entry to insert. - */ - public void addEntry(final int index, final FileListEntry entry) { - synchronized (list) { - list.add(index, entry); - if (SwingUtilities.isEventDispatchThread()) { - fireTableRowsInserted(index, index); - } else { - SwingUtilities.invokeLater(() -> fireTableRowsInserted(index, index)); - } - } - - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - // Do nothing - } - - /** - * Set up the table contents based on the flat string representation of the file list - * @param value The string representation - */ - public void setContent(String value) { - setContent(value, false, true); - } - - public void setContentDontGuessTypes(String value) { - setContent(value, false, false); - } - - private FileListEntry setContent(String val, boolean firstOnly, boolean deduceUnknownTypes) { - String value = val; - if (value == null) { - value = ""; - } - - List fields = FileFieldParser.parse(value); - List files = new ArrayList<>(); - - for (LinkedFile entry : fields) { - - if (entry.isEmpty()) { - continue; - } - - if (firstOnly) { - return decodeEntry(entry, deduceUnknownTypes); - } else { - files.add(decodeEntry(entry, deduceUnknownTypes)); - } - } - - synchronized (list) { - list.clear(); - list.addAll(files); - } - fireTableChanged(new TableModelEvent(this)); - return null; - } - - private FileListEntry decodeEntry(LinkedFile entry, boolean deduceUnknownType) { - Optional type = ExternalFileTypes.getInstance().fromLinkedFile(entry, deduceUnknownType); - - return new FileListEntry(entry.getDescription(), entry.getLink(), type); - } - - /** - * Transform the file list shown in the table into a flat string representable - * as a BibTeX field: - * @return String representation. - */ - public String getStringRepresentation() { - synchronized (list) { - String[][] array = new String[list.size()][]; - int i = 0; - for (FileListEntry entry : list) { - array[i] = entry.getStringArrayRepresentation(); - i++; - } - return FileFieldWriter.encodeStringArray(array); - } - } - - /** - * Transform the file list shown in the table into a HTML string representation - * suitable for displaying the contents in a tooltip. - * @return Tooltip representation. - */ - public String getToolTipHTMLRepresentation() { - StringJoiner sb = new StringJoiner("
", "", ""); - - synchronized (list) { - for (FileListEntry entry : list) { - sb.add(String.format("%s (%s)", entry.getDescription(), entry.getLink())); - } - } - - return sb.toString(); - } - -} diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeNodeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupTreeNodeViewModel.java index 1ef43c63806..6e6270490da 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeNodeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeNodeViewModel.java @@ -1,17 +1,9 @@ package org.jabref.gui.groups; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; import java.util.function.Consumer; -import javax.swing.JTree; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.UndoManager; @@ -29,25 +21,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GroupTreeNodeViewModel implements Transferable, TreeNode { +public class GroupTreeNodeViewModel { - private static final DataFlavor FLAVOR; private static final Logger LOGGER = LoggerFactory.getLogger(GroupTreeNodeViewModel.class); - private static final DataFlavor[] FLAVORS; - - static { - DataFlavor df = null; - try { - df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType - + ";class=" + GroupTreeNode.class.getCanonicalName()); - } catch (ClassNotFoundException e) { - LOGGER.error("Creating DataFlavor failed. This should not happen.", e); - } - FLAVOR = df; - FLAVORS = new DataFlavor[] {GroupTreeNodeViewModel.FLAVOR}; - } - private final GroupTreeNode node; public GroupTreeNodeViewModel(GroupTreeNode node) { @@ -62,90 +39,10 @@ public String toString() { return sb.toString(); } - @Override - public DataFlavor[] getTransferDataFlavors() { - return GroupTreeNodeViewModel.FLAVORS; - } - - @Override - public boolean isDataFlavorSupported(DataFlavor someFlavor) { - return someFlavor.equals(GroupTreeNodeViewModel.FLAVOR); - } - - @Override - public Object getTransferData(DataFlavor someFlavor) - throws UnsupportedFlavorException, IOException { - if (!isDataFlavorSupported(someFlavor)) { - throw new UnsupportedFlavorException(someFlavor); - } - return this; - } - - @Override - public TreeNode getChildAt(int childIndex) { - return node.getChildAt(childIndex).map(GroupTreeNodeViewModel::new).orElse(null); - } - - @Override - public int getChildCount() { - return node.getNumberOfChildren(); - } - - @Override - public TreeNode getParent() { - return node.getParent().map(GroupTreeNodeViewModel::new).orElse(null); - } - - @Override - public int getIndex(TreeNode child) { - if (!(child instanceof GroupTreeNodeViewModel)) { - return -1; - } - - GroupTreeNodeViewModel childViewModel = (GroupTreeNodeViewModel) child; - return node.getIndexOfChild(childViewModel.getNode()).orElse(-1); - } - - @Override - public boolean getAllowsChildren() { - return true; - } - - @Override - public boolean isLeaf() { - return node.isLeaf(); - } - - @Override - public Enumeration children() { - Iterable children = node.getChildren(); - return new Enumeration() { - - @Override - public boolean hasMoreElements() { - return children.iterator().hasNext(); - } - - @Override - public GroupTreeNodeViewModel nextElement() { - return new GroupTreeNodeViewModel(children.iterator().next()); - } - }; - } - public GroupTreeNode getNode() { return node; } - /** Expand this node and all its children. */ - public void expandSubtree(JTree tree) { - tree.expandPath(this.getTreePath()); - - for (GroupTreeNodeViewModel child : getChildren()) { - child.expandSubtree(tree); - } - } - public List getChildren() { List children = new ArrayList<>(); for (GroupTreeNode child : node.getChildren()) { @@ -174,11 +71,6 @@ public String getDescription() { return "" + shortDescription + ""; } - public TreePath getTreePath() { - List pathToNode = node.getPathFromRoot(); - return new TreePath(pathToNode.stream().map(GroupTreeNodeViewModel::new).toArray()); - } - public boolean canAddEntries(List entries) { return (getNode().getGroup() instanceof GroupEntryChanger) && !getNode().getGroup().containsAll(entries); } @@ -189,8 +81,8 @@ public boolean canRemoveEntries(List entries) { public void sortChildrenByName(boolean recursive) { getNode().sortChildren( - (node1, node2) -> node1.getGroup().getName().compareToIgnoreCase(node2.getGroup().getName()), - recursive); + (node1, node2) -> node1.getGroup().getName().compareToIgnoreCase(node2.getGroup().getName()), + recursive); } @Override @@ -221,23 +113,23 @@ public boolean canBeEdited() { public boolean canMoveUp() { return (getNode().getPreviousSibling() != null) - && !(getNode().getGroup() instanceof AllEntriesGroup); + && !(getNode().getGroup() instanceof AllEntriesGroup); } public boolean canMoveDown() { return (getNode().getNextSibling() != null) - && !(getNode().getGroup() instanceof AllEntriesGroup); + && !(getNode().getGroup() instanceof AllEntriesGroup); } public boolean canMoveLeft() { return !(getNode().getGroup() instanceof AllEntriesGroup) - // TODO: Null! - && !(getNode().getParent().get().getGroup() instanceof AllEntriesGroup); + // TODO: Null! + && !(getNode().getParent().get().getGroup() instanceof AllEntriesGroup); } public boolean canMoveRight() { return (getNode().getPreviousSibling() != null) - && !(getNode().getGroup() instanceof AllEntriesGroup); + && !(getNode().getGroup() instanceof AllEntriesGroup); } public void changeEntriesTo(List entries, UndoManager undoManager) { @@ -295,7 +187,7 @@ public void addNewGroup(AbstractGroup newGroup, CountingUndoManager undoManager) this.getNode().addChild(newNode); UndoableAddOrRemoveGroup undo = new UndoableAddOrRemoveGroup(this, - new GroupTreeNodeViewModel(newNode), UndoableAddOrRemoveGroup.ADD_NODE); + new GroupTreeNodeViewModel(newNode), UndoableAddOrRemoveGroup.ADD_NODE); undoManager.addEdit(undo); } diff --git a/src/main/java/org/jabref/gui/groups/UndoableAddOrRemoveGroup.java b/src/main/java/org/jabref/gui/groups/UndoableAddOrRemoveGroup.java index 7e0e40f9f49..83f1faaf65e 100644 --- a/src/main/java/org/jabref/gui/groups/UndoableAddOrRemoveGroup.java +++ b/src/main/java/org/jabref/gui/groups/UndoableAddOrRemoveGroup.java @@ -50,7 +50,7 @@ public UndoableAddOrRemoveGroup(GroupTreeNodeViewModel groupsRoot, GroupTreeNodeViewModel editedNode, int editType) { m_groupsRootHandle = groupsRoot; m_editType = editType; - m_subtreeRootChildCount = editedNode.getChildCount(); + m_subtreeRootChildCount = editedNode.getChildren().size(); // storing a backup of the whole subtree is not required when children // are kept m_subtreeBackup = editType != UndoableAddOrRemoveGroup.REMOVE_NODE_KEEP_CHILDREN ? editedNode.getNode() diff --git a/src/main/java/org/jabref/gui/groups/WarnAssignmentSideEffects.java b/src/main/java/org/jabref/gui/groups/WarnAssignmentSideEffects.java deleted file mode 100644 index d66d0ee7fa2..00000000000 --- a/src/main/java/org/jabref/gui/groups/WarnAssignmentSideEffects.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.jabref.gui.groups; - -import java.awt.Component; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.swing.JOptionPane; - -import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.field.Field; -import org.jabref.model.entry.field.InternalField; -import org.jabref.model.entry.field.StandardField; -import org.jabref.model.groups.AbstractGroup; -import org.jabref.model.groups.KeywordGroup; - -public class WarnAssignmentSideEffects { - - private WarnAssignmentSideEffects() { - } - - /** - * Warns the user of undesired side effects of an explicit assignment/removal of entries to/from this group. - * Currently there are four types of groups: AllEntriesGroup, SearchGroup - do not support explicit assignment. - * ExplicitGroup and KeywordGroup - this modifies entries upon assignment/removal. - * Modifications are acceptable unless they affect a field (such as "author") besides the "keywords" or "groups' field. - * - * @param parent The Component used as a parent when displaying a confirmation dialog. - * @return true if the assignment has no undesired side effects, or the user chose to perform it anyway. false - * otherwise (this indicates that the user has aborted the assignment). - */ - public static boolean warnAssignmentSideEffects(List groups, Component parent) { - List affectedFields = new ArrayList<>(); - for (AbstractGroup group : groups) { - if (group instanceof KeywordGroup) { - KeywordGroup keywordGroup = (KeywordGroup) group; - Field field = keywordGroup.getSearchField(); - if (StandardField.KEYWORDS.equals(field) || InternalField.GROUPS.equals(field)) { - continue; // this is not undesired - } - - affectedFields.add(field); - } - } - if (affectedFields.isEmpty()) { - return true; // no side effects - } - - // show a warning, then return - StringBuilder message = new StringBuilder( - Localization.lang("This action will modify the following field(s) in at least one entry each:")) - .append('\n'); - for (Field affectedField : affectedFields) { - message.append(affectedField.getDisplayName()).append('\n'); - } - message.append(Localization.lang("This could cause undesired changes to your entries.")).append('\n') - .append("It is recommended that you change the grouping field in your group definition to \"keywords\" or a non-standard name.") - .append("\n\n").append(Localization.lang("Do you still want to continue?")); - int choice = JOptionPane.showConfirmDialog(parent, message, Localization.lang("Warning"), - JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - return choice != JOptionPane.NO_OPTION; - - // if (groups instanceof KeywordGroup) { - // KeywordGroup kg = (KeywordGroup) groups; - // String field = kg.getSearchField().toLowerCase(Locale.ROOT); - // if (field.equals("keywords")) - // return true; // this is not undesired - // for (int i = 0; i < GUIGlobals.ALL_FIELDS.length; ++i) { - // if (field.equals(GUIGlobals.ALL_FIELDS[i])) { - // // show a warning, then return - // String message = Globals ... - // .lang( - // "This action will modify the \"%0\" field " - // + "of your entries.\nThis could cause undesired changes to " - // + "your entries, so it is\nrecommended that you change the grouping - // field " - // + "in your group\ndefinition to \"keywords\" or a non-standard name." - // + "\n\nDo you still want to continue?", - // field); - // int choice = JOptionPane.showConfirmDialog(parent, message, - // Globals.lang("Warning"), JOptionPane.YES_NO_OPTION, - // JOptionPane.WARNING_MESSAGE); - // return choice != JOptionPane.NO_OPTION; - // } - // } - // } - // return true; // found no side effects - } - - public static boolean warnAssignmentSideEffects(AbstractGroup group, Component parent) { - return warnAssignmentSideEffects(Collections.singletonList(group), parent); - } - -} diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index 39e0ff48d0b..83338444164 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -1,13 +1,5 @@ package org.jabref.gui.icon; -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -import java.awt.FontFormatException; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -20,15 +12,12 @@ import java.util.Map; import java.util.Objects; -import javax.swing.Icon; -import javax.swing.ImageIcon; - import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ToggleButton; import javafx.scene.image.Image; +import javafx.scene.paint.Color; -import org.jabref.gui.util.ColorUtil; import org.jabref.logic.groups.DefaultGroupsFactory; import org.jabref.preferences.JabRefPreferences; @@ -45,19 +34,12 @@ public class IconTheme { public static final Color DEFAULT_COLOR = JabRefPreferences.getInstance().getColor(JabRefPreferences.ICON_ENABLED_COLOR); public static final Color DEFAULT_DISABLED_COLOR = JabRefPreferences.getInstance().getColor(JabRefPreferences.ICON_DISABLED_COLOR); public static final javafx.scene.paint.Color SELECTED_COLOR = javafx.scene.paint.Color.web("#50618F"); - public static Font FONT; private static final String DEFAULT_ICON_PATH = "/images/external/red.png"; private static final Logger LOGGER = LoggerFactory.getLogger(IconTheme.class); private static final Map KEY_TO_ICON = readIconThemeFile( - IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); + IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); public static void loadFonts() { - try (InputStream stream = getMaterialDesignIconsStream()) { - FONT = Font.createFont(Font.TRUETYPE_FONT, stream); - } catch (FontFormatException | IOException e) { - LOGGER.error("Error loading font", e); - } - try (InputStream stream = getMaterialDesignIconsStream()) { javafx.scene.text.Font.loadFont(stream, 7); } catch (IOException e) { @@ -72,15 +54,15 @@ public static void loadFonts() { } private static InputStream getMaterialDesignIconsStream() { - return FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf"); + return IconTheme.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf"); } private static InputStream getJabRefMaterialDesignIconsStream() throws IOException { - return FontBasedIcon.class.getResource("/fonts/JabRefMaterialDesign.ttf").openStream(); + return IconTheme.class.getResource("/fonts/JabRefMaterialDesign.ttf").openStream(); } - public static javafx.scene.paint.Color getDefaultColor() { - return ColorUtil.toFX(DEFAULT_COLOR); + public static Color getDefaultColor() { + return DEFAULT_COLOR; } public static Image getJabRefImageFX() { @@ -109,7 +91,7 @@ public static URL getIconUrl(String name) { String key = Objects.requireNonNull(name, "icon name"); if (!KEY_TO_ICON.containsKey(key)) { LOGGER.warn("Could not find icon url by name " + name + ", so falling back on default icon " - + DEFAULT_ICON_PATH); + + DEFAULT_ICON_PATH); } String path = KEY_TO_ICON.getOrDefault(key, DEFAULT_ICON_PATH); return Objects.requireNonNull(IconTheme.class.getResource(path), "Path must not be null for key " + key); @@ -133,7 +115,7 @@ private static Map readIconThemeFile(URL url, String prefix) { Map result = new HashMap<>(); try (BufferedReader in = new BufferedReader( - new InputStreamReader(url.openStream(), StandardCharsets.ISO_8859_1))) { + new InputStreamReader(url.openStream(), StandardCharsets.ISO_8859_1))) { String line; while ((line = in.readLine()) != null) { if (!line.contains("=")) { @@ -151,19 +133,6 @@ private static Map readIconThemeFile(URL url, String prefix) { return result; } - public static List getLogoSet() { - List jabrefLogos = new ArrayList<>(); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon16")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon20")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon32")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon40")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon48")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon64")).getImage()); - jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon128")).getImage()); - - return jabrefLogos; - } - public static List getLogoSetFX() { List jabrefLogos = new ArrayList<>(); jabrefLogos.add(new Image(getIconUrl("jabrefIcon16").toString())); @@ -221,7 +190,7 @@ public enum JabRefIcons implements JabRefIcon { PRIORITY(MaterialDesignIcon.FLAG), PRIORITY_HIGH(Color.RED, MaterialDesignIcon.FLAG), PRIORITY_MEDIUM(Color.ORANGE, MaterialDesignIcon.FLAG), - PRIORITY_LOW(new Color(111, 204, 117), MaterialDesignIcon.FLAG), + PRIORITY_LOW(Color.rgb(111, 204, 117), MaterialDesignIcon.FLAG), PRINTED(MaterialDesignIcon.PRINTER), RANKING(MaterialDesignIcon.STAR), RANK1(MaterialDesignIcon.STAR, MaterialDesignIcon.STAR_OUTLINE, MaterialDesignIcon.STAR_OUTLINE, MaterialDesignIcon.STAR_OUTLINE, MaterialDesignIcon.STAR_OUTLINE), @@ -240,15 +209,15 @@ public enum JabRefIcons implements JabRefIcon { ATTACH_FILE(MaterialDesignIcon.PAPERCLIP) /*css: paperclip*/, AUTO_FILE_LINK(MaterialDesignIcon.FILE_FIND) /*css: file-find */, QUALITY_ASSURED(MaterialDesignIcon.CERTIFICATE), /*css: certificate */ - QUALITY(MaterialDesignIcon.CERTIFICATE),/*css: certificate */ + QUALITY(MaterialDesignIcon.CERTIFICATE), /*css: certificate */ OPEN(MaterialDesignIcon.FOLDER_OUTLINE) /*css: folder */, ADD_ROW(MaterialDesignIcon.SERVER_PLUS) /* css: server-plus*/, REMOVE_ROW(MaterialDesignIcon.SERVER_MINUS) /*css: server-minus */, PICTURE(MaterialDesignIcon.FILE_IMAGE) /*css: file-image */, - READ_STATUS_READ(new Color(111, 204, 117), MaterialDesignIcon.EYE), /*css: eye */ + READ_STATUS_READ(Color.rgb(111, 204, 117, 1), MaterialDesignIcon.EYE), /*css: eye */ READ_STATUS_SKIMMED(Color.ORANGE, MaterialDesignIcon.EYE), /*css: eye */ - READ_STATUS(MaterialDesignIcon.EYE),/*css: eye */ - RELEVANCE(MaterialDesignIcon.STAR_CIRCLE),/*css: star-circle */ + READ_STATUS(MaterialDesignIcon.EYE), /*css: eye */ + RELEVANCE(MaterialDesignIcon.STAR_CIRCLE), /*css: star-circle */ MERGE_ENTRIES(MaterialDesignIcon.COMPARE), /* css: compare */ CONNECT_OPEN_OFFICE(MaterialDesignIcon.OPEN_IN_APP) /*css: open-in-app */, PLAIN_TEXT_IMPORT_TODO(MaterialDesignIcon.CHECKBOX_BLANK_CIRCLE_OUTLINE) /* css: checkbox-blank-circle-outline*/, @@ -334,31 +303,11 @@ public enum JabRefIcons implements JabRefIcon { icon = new InternalMaterialDesignIcon(color, icons); } - @Override - public Icon getIcon() { - return icon.getIcon(); - } - - @Override - public Icon getSmallIcon() { - return icon.getSmallIcon(); - } - @Override public Node getGraphicNode() { return icon.getGraphicNode(); } - @Override - public JabRefIcon disabled() { - return icon.disabled(); - } - - @Override - public JabRefIcon withColor(javafx.scene.paint.Color color) { - return icon.withColor(color); - } - @Override public String unicode() { return icon.unicode(); @@ -382,65 +331,17 @@ public ToggleButton asToggleButton() { button.getStyleClass().add("icon-button"); return button; } - } - - public static class FontBasedIcon implements Icon { - - private final String iconCode; - private final Color iconColor; - private final int size; - - public FontBasedIcon(String code, Color iconColor) { - this.iconCode = code; - this.iconColor = iconColor; - this.size = 24; - } - - public FontBasedIcon(String code, Color iconColor, int size) { - this.iconCode = code; - this.iconColor = iconColor; - this.size = size; - } @Override - public void paintIcon(Component c, Graphics g, int x, int y) { - Graphics2D g2 = (Graphics2D) g.create(); - - RenderingHints rh = new RenderingHints( - RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - g2.setRenderingHints(rh); - - g2.setFont(FONT.deriveFont(Font.PLAIN, size)); - g2.setColor(iconColor); - FontMetrics fm = g2.getFontMetrics(); - - g2.translate(x, y + fm.getAscent()); - g2.drawString(iconCode, 0, 0); - - g2.dispose(); - } + public JabRefIcon withColor(Color color) { + return icon.withColor(color); - @Override - public int getIconWidth() { - return size; } @Override - public int getIconHeight() { - return size; - } - - public FontBasedIcon createDisabledIcon() { - return new FontBasedIcon(this.iconCode, IconTheme.DEFAULT_DISABLED_COLOR, this.size); - } - - public FontBasedIcon createSmallIcon() { - return new FontBasedIcon(this.iconCode, this.iconColor, 16); - } - - public FontBasedIcon createWithNewColor(Color newColor) { - return new FontBasedIcon(this.iconCode, newColor, this.size); + public JabRefIcon disabled() { + return icon.disabled(); } } + } diff --git a/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java b/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java index 84a02938c6e..cfc0c420e91 100644 --- a/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java +++ b/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java @@ -5,8 +5,6 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.swing.Icon; - import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.text.Text; @@ -16,14 +14,11 @@ import de.jensd.fx.glyphs.GlyphIcons; public class InternalMaterialDesignIcon implements JabRefIcon { + private final List icons; private Optional color; private final String unicode; - public InternalMaterialDesignIcon(java.awt.Color color, GlyphIcons... icons) { - this(ColorUtil.toFX(color), Arrays.asList(icons)); - } - public InternalMaterialDesignIcon(Color color, GlyphIcons... icons) { this(color, Arrays.asList(icons)); } @@ -43,16 +38,6 @@ public InternalMaterialDesignIcon(List icons) { this.color = Optional.empty(); } - @Override - public Icon getIcon() { - return new IconTheme.FontBasedIcon(this.unicode, ColorUtil.toAWT(this.color.orElse(IconTheme.getDefaultColor()))); - } - - @Override - public Icon getSmallIcon() { - return new IconTheme.FontBasedIcon(this.unicode, ColorUtil.toAWT(this.color.orElse(IconTheme.getDefaultColor()))); - } - @Override public Node getGraphicNode() { GlyphIcons icon = icons.get(0); @@ -67,7 +52,7 @@ public Node getGraphicNode() { @Override public JabRefIcon disabled() { - return new InternalMaterialDesignIcon(ColorUtil.toFX(IconTheme.DEFAULT_DISABLED_COLOR), icons); + return new InternalMaterialDesignIcon(IconTheme.DEFAULT_DISABLED_COLOR, icons); } @Override diff --git a/src/main/java/org/jabref/gui/icon/JabRefIcon.java b/src/main/java/org/jabref/gui/icon/JabRefIcon.java index f95b47b42f2..f11d4493d6a 100644 --- a/src/main/java/org/jabref/gui/icon/JabRefIcon.java +++ b/src/main/java/org/jabref/gui/icon/JabRefIcon.java @@ -1,22 +1,18 @@ package org.jabref.gui.icon; -import javax.swing.Icon; - import javafx.scene.Node; import javafx.scene.paint.Color; import de.jensd.fx.glyphs.GlyphIcons; public interface JabRefIcon extends GlyphIcons { - Icon getIcon(); - - Icon getSmallIcon(); Node getGraphicNode(); - JabRefIcon disabled(); + @Override + String name(); JabRefIcon withColor(Color color); - String name(); + JabRefIcon disabled(); } diff --git a/src/main/java/org/jabref/gui/keyboard/EmacsKeyBindings.java b/src/main/java/org/jabref/gui/keyboard/EmacsKeyBindings.java deleted file mode 100644 index 20ee319c711..00000000000 --- a/src/main/java/org/jabref/gui/keyboard/EmacsKeyBindings.java +++ /dev/null @@ -1,790 +0,0 @@ -package org.jabref.gui.keyboard; - -import java.awt.event.ActionEvent; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; - -import javax.swing.Action; -import javax.swing.JEditorPane; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.JTextPane; -import javax.swing.KeyStroke; -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultEditorKit; -import javax.swing.text.Document; -import javax.swing.text.JTextComponent; -import javax.swing.text.Keymap; -import javax.swing.text.TextAction; -import javax.swing.text.Utilities; - -import org.jabref.preferences.JabRefPreferences; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Generic class which activates Emacs keybindings for java input {@link - * JTextComponent}s. - * - * The inner class actions can also be used independently. - */ -public class EmacsKeyBindings { - private static final Logger LOGGER = LoggerFactory.getLogger(EmacsKeyBindings.class); - - private static final String KILL_LINE_ACTION = "emacs-kill-line"; - - private static final String KILL_RING_SAVE_ACTION = "emacs-kill-ring-save"; - - private static final String KILL_REGION_ACTION = "emacs-kill-region"; - - private static final String BACKWARD_KILL_WORD_ACTION = "emacs-backward-kill-word"; - - private static final String CAPITALIZE_WORD_ACTION = "emacs-capitalize-word"; - - private static final String DOWNCASE_WORD_ACTION = "emacs-downcase-word"; - - private static final String KILL_WORD_ACTION = "emacs-kill-word"; - - private static final String SET_MARK_COMMAND_ACTION = "emacs-set-mark-command"; - - private static final String YANK_ACTION = "emacs-yank"; - - private static final String YANK_POP_ACTION = "emacs-yank-pop"; - - private static final String UPCASE_WORD_ACTION = "emacs-upcase-word"; - - private static final JTextComponent.KeyBinding[] EMACS_KEY_BINDINGS_BASE = { - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_E, - InputEvent.CTRL_MASK), - DefaultEditorKit.endLineAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_D, - InputEvent.CTRL_MASK), - DefaultEditorKit.deleteNextCharAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_N, - InputEvent.CTRL_MASK), - DefaultEditorKit.downAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_P, - InputEvent.CTRL_MASK), - DefaultEditorKit.upAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_B, - InputEvent.ALT_MASK), - DefaultEditorKit.previousWordAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LESS, - InputEvent.ALT_MASK), - DefaultEditorKit.beginAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LESS, - InputEvent.ALT_MASK - + InputEvent.SHIFT_MASK), - DefaultEditorKit.endAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_F, - InputEvent.ALT_MASK), - DefaultEditorKit.nextWordAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_B, - InputEvent.CTRL_MASK), - DefaultEditorKit.backwardAction), - // CTRL+V and ALT+V are disabled as CTRL+V is also "paste" - // new JTextComponent. - // KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_V, - // InputEvent.CTRL_MASK), - // DefaultEditorKit.pageDownAction), - // new JTextComponent. - // KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_V, - // InputEvent.ALT_MASK), - // DefaultEditorKit.pageUpAction), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_D, - InputEvent.ALT_MASK), - EmacsKeyBindings.KILL_WORD_ACTION), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, - InputEvent.ALT_MASK), - EmacsKeyBindings.BACKWARD_KILL_WORD_ACTION), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, - InputEvent.CTRL_MASK), - EmacsKeyBindings.SET_MARK_COMMAND_ACTION), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, - InputEvent.ALT_MASK), - EmacsKeyBindings.KILL_RING_SAVE_ACTION), - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_W, - InputEvent.CTRL_MASK), - EmacsKeyBindings.KILL_REGION_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_K, - InputEvent.CTRL_MASK), - EmacsKeyBindings.KILL_LINE_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_Y, - InputEvent.CTRL_MASK), - EmacsKeyBindings.YANK_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_Y, - InputEvent.ALT_MASK), - EmacsKeyBindings.YANK_POP_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_C, - InputEvent.ALT_MASK), - EmacsKeyBindings.CAPITALIZE_WORD_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_L, - InputEvent.ALT_MASK), - EmacsKeyBindings.DOWNCASE_WORD_ACTION), - - new JTextComponent. - KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_U, - InputEvent.ALT_MASK), - EmacsKeyBindings.UPCASE_WORD_ACTION), - }; - - private static final JTextComponent.KeyBinding EMACS_KEY_BINDING_C_A = new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_A, - InputEvent.CTRL_MASK), - DefaultEditorKit.beginLineAction); - - private static final JTextComponent.KeyBinding EMACS_KEY_BINDING_C_F = new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_F, - InputEvent.CTRL_MASK), - DefaultEditorKit.forwardAction); - - private static final TextAction[] EMACS_ACTIONS = { - new KillWordAction(EmacsKeyBindings.KILL_WORD_ACTION), - new BackwardKillWordAction(EmacsKeyBindings.BACKWARD_KILL_WORD_ACTION), - new SetMarkCommandAction(EmacsKeyBindings.SET_MARK_COMMAND_ACTION), - new KillRingSaveAction(EmacsKeyBindings.KILL_RING_SAVE_ACTION), - new KillRegionAction(EmacsKeyBindings.KILL_REGION_ACTION), - new KillLineAction(EmacsKeyBindings.KILL_LINE_ACTION), - new YankAction(EmacsKeyBindings.YANK_ACTION), - new YankPopAction(EmacsKeyBindings.YANK_POP_ACTION), - new CapitalizeWordAction(EmacsKeyBindings.CAPITALIZE_WORD_ACTION), - new DowncaseWordAction(EmacsKeyBindings.DOWNCASE_WORD_ACTION), - new UpcaseWordAction(EmacsKeyBindings.UPCASE_WORD_ACTION) - }; - - // components to modify - private static final JTextComponent[] JTCS = new JTextComponent[]{ - new JTextArea(), - new JTextPane(), - new JTextField(), - new JEditorPane(), - }; - - private EmacsKeyBindings() { - } - - /** - * Loads the emacs keybindings for all common JTextComponents. - * - * The shared keymap instances of the concrete subclasses of - * {@link JTextComponent} are fed with the keybindings. - * - * The original keybindings are stored in a backup array. - */ - public static void load() { - EmacsKeyBindings.createBackup(); - EmacsKeyBindings.loadEmacsKeyBindings(); - } - - private static void createBackup() { - Keymap oldBackup = JTextComponent.getKeymap(EmacsKeyBindings.JTCS[0].getClass().getName()); - if (oldBackup != null) { - // if there is already a backup, do not create a new backup - return; - } - - for (JTextComponent jtc : EmacsKeyBindings.JTCS) { - Keymap orig = jtc.getKeymap(); - Keymap backup = JTextComponent.addKeymap - (jtc.getClass().getName(), null); - Action[] bound = orig.getBoundActions(); - for (Action aBound : bound) { - KeyStroke[] strokes = orig.getKeyStrokesForAction(aBound); - for (KeyStroke stroke : strokes) { - backup.addActionForKeyStroke(stroke, aBound); - } - } - backup.setDefaultAction(orig.getDefaultAction()); - } - } - - /** - * Restores the original keybindings for the concrete subclasses of - * {@link JTextComponent}. - */ - public static void unload() { - for (int i = 0; i < EmacsKeyBindings.JTCS.length; i++) { - Keymap backup = JTextComponent.getKeymap - (EmacsKeyBindings.JTCS[i].getClass().getName()); - - if (backup != null) { - Keymap current = EmacsKeyBindings.JTCS[i].getKeymap(); - current.removeBindings(); - - Action[] bound = backup.getBoundActions(); - for (Action aBound : bound) { - KeyStroke[] strokes = - backup.getKeyStrokesForAction(bound[i]); - for (KeyStroke stroke : strokes) { - current.addActionForKeyStroke(stroke, aBound); - } - } - current.setDefaultAction(backup.getDefaultAction()); - } - } - } - - /** - * Activates Emacs keybindings for all text components extending {@link - * JTextComponent}. - */ - private static void loadEmacsKeyBindings() { - EmacsKeyBindings.LOGGER.debug("Loading emacs keybindings"); - - for (JTextComponent jtc : EmacsKeyBindings.JTCS) { - Action[] origActions = jtc.getActions(); - Action[] actions = new Action[origActions.length + EmacsKeyBindings.EMACS_ACTIONS.length]; - System.arraycopy(origActions, 0, actions, 0, origActions.length); - System.arraycopy(EmacsKeyBindings.EMACS_ACTIONS, 0, actions, origActions.length, EmacsKeyBindings.EMACS_ACTIONS.length); - - Keymap k = jtc.getKeymap(); - - JTextComponent.KeyBinding[] keybindings; - boolean rebindCA = JabRefPreferences.getInstance().getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA); - boolean rebindCF = JabRefPreferences.getInstance().getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF); - if (rebindCA || rebindCF) { - // if we additionally rebind C-a or C-f, we have to add the shortcuts to EmacsKeyBindings.EMACS_KEY_BINDINGS_BASE - - // determine size of new array and position of the new key bindings in the array - int size = EmacsKeyBindings.EMACS_KEY_BINDINGS_BASE.length; - int posCA = -1; - int posCF = -1; - if (rebindCA) { - posCA = size; - size++; - } - if (rebindCF) { - posCF = size; - size++; - } - - // generate new array - keybindings = new JTextComponent.KeyBinding[size]; - System.arraycopy(EmacsKeyBindings.EMACS_KEY_BINDINGS_BASE, 0, keybindings, 0, EmacsKeyBindings.EMACS_KEY_BINDINGS_BASE.length); - if (rebindCA) { - keybindings[posCA] = EmacsKeyBindings.EMACS_KEY_BINDING_C_A; - } - if (rebindCF) { - keybindings[posCF] = EmacsKeyBindings.EMACS_KEY_BINDING_C_F; - } - } else { - keybindings = EmacsKeyBindings.EMACS_KEY_BINDINGS_BASE; - } - JTextComponent.loadKeymap(k, keybindings, actions); - } - } - - - /** - * This action kills the next word. - * - * It removes the next word on the right side of the cursor from the active - * text component and adds it to the clipboard. - */ - @SuppressWarnings("serial") - public static class KillWordAction extends TextAction { - - public KillWordAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent jtc = getTextComponent(e); - if (jtc != null) { - try { - int offs = jtc.getCaretPosition(); - jtc.setSelectionStart(offs); - offs = EmacsKeyBindings.getWordEnd(jtc, offs); - jtc.setSelectionEnd(offs); - String selectedText = jtc.getSelectedText(); - if (selectedText != null) { - KillRing.getInstance().add(selectedText); - } - jtc.cut(); - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - /** - * This action kills the previous word. - * - * It removes the previous word on the left side of the cursor from the - * active text component and adds it to the clipboard. - */ - @SuppressWarnings("serial") - public static class BackwardKillWordAction extends TextAction { - - public BackwardKillWordAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent jtc = getTextComponent(e); - if (jtc != null) { - try { - int offs = jtc.getCaretPosition(); - jtc.setSelectionEnd(offs); - offs = Utilities.getPreviousWord(jtc, offs); - jtc.setSelectionStart(offs); - String selectedText = jtc.getSelectedText(); - if (selectedText != null) { - KillRing.getInstance().add(selectedText); - } - jtc.cut(); - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - /** - * This action copies the marked region and stores it in the killring. - */ - @SuppressWarnings("serial") - public static class KillRingSaveAction extends TextAction { - - public KillRingSaveAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent jtc = getTextComponent(e); - EmacsKeyBindings.doCopyOrCut(jtc, true); - } - } - - /** - * This action Kills the marked region and stores it in the killring. - */ - @SuppressWarnings("serial") - public static class KillRegionAction extends TextAction { - - public KillRegionAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent jtc = getTextComponent(e); - EmacsKeyBindings.doCopyOrCut(jtc, false); - } - } - - private static void doCopyOrCut(JTextComponent jtc, boolean copy) { - if (jtc != null) { - int caretPosition = jtc.getCaretPosition(); - String text = jtc.getSelectedText(); - if (text != null) { - // user has manually marked a text without using CTRL+W - // we obey that selection and copy it. - } else if (SetMarkCommandAction.isMarked(jtc)) { - int beginPos = caretPosition; - int endPos = SetMarkCommandAction.getCaretPosition(); - if (beginPos > endPos) { - int tmp = endPos; - endPos = beginPos; - beginPos = tmp; - } - jtc.select(beginPos, endPos); - SetMarkCommandAction.reset(); - } - text = jtc.getSelectedText(); - if (text == null) { - jtc.getToolkit().beep(); - } else { - if (copy) { - jtc.copy(); - // clear the selection - jtc.select(caretPosition, caretPosition); - } else { - int newCaretPos = jtc.getSelectionStart(); - jtc.cut(); - // put the cursor to the beginning of the text to cut - jtc.setCaretPosition(newCaretPos); - } - KillRing.getInstance().add(text); - } - } - } - - - /** - * This actin kills text up to the end of the current line and stores it in - * the killring. - */ - @SuppressWarnings("serial") - public static class KillLineAction extends TextAction { - - public KillLineAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - JTextComponent jtc = getTextComponent(e); - if (jtc != null) { - try { - int start = jtc.getCaretPosition(); - int end = Utilities.getRowEnd(jtc, start); - if ((start == end) && jtc.isEditable()) { - Document doc = jtc.getDocument(); - doc.remove(end, 1); - } else { - jtc.setSelectionStart(start); - jtc.setSelectionEnd(end); - String selectedText = jtc.getSelectedText(); - if (selectedText != null) { - KillRing.getInstance().add(selectedText); - } - - jtc.cut(); - // jtc.replaceSelection(""); - } - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - /** - * This action matchers a beginning mark for a selection. - */ - @SuppressWarnings("serial") - public static class SetMarkCommandAction extends TextAction { - - private static int position = -1; - private static JTextComponent jtc; - - - public SetMarkCommandAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent e) { - SetMarkCommandAction.jtc = getTextComponent(e); - if (SetMarkCommandAction.jtc != null) { - SetMarkCommandAction.position = SetMarkCommandAction.jtc.getCaretPosition(); - } - } - - public static boolean isMarked(JTextComponent jt) { - return (SetMarkCommandAction.jtc == jt) && (SetMarkCommandAction.position != -1); - } - - public static void reset() { - SetMarkCommandAction.jtc = null; - SetMarkCommandAction.position = -1; - } - - public static int getCaretPosition() { - return SetMarkCommandAction.position; - } - } - - /** - * This action pastes text from the killring. - */ - @SuppressWarnings("serial") - public static class YankAction extends TextAction { - - public static int start = -1; - public static int end = -1; - - - public YankAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent event) { - JTextComponent jtc = getTextComponent(event); - - if (jtc != null) { - try { - YankAction.start = jtc.getCaretPosition(); - jtc.paste(); - YankAction.end = jtc.getCaretPosition(); - KillRing.getInstance().add(jtc.getText(YankAction.start, YankAction.end)); - KillRing.getInstance().setCurrentTextComponent(jtc); - } catch (BadLocationException e) { - LOGGER.info("Bad location when yanking", e); - } - } - } - } - - /** - * This action pastes an element from the killring cycling through it. - */ - @SuppressWarnings("serial") - public static class YankPopAction extends TextAction { - - public YankPopAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent event) { - JTextComponent jtc = getTextComponent(event); - boolean jtcNotNull = jtc != null; - boolean jtcIsCurrentTextComponent = KillRing.getInstance().getCurrentTextComponent() == jtc; - boolean caretPositionIsEndOfLastYank = jtcNotNull && (jtc.getCaretPosition() == YankAction.end); - boolean killRingNotEmpty = !KillRing.getInstance().isEmpty(); - if (jtcNotNull && jtcIsCurrentTextComponent && caretPositionIsEndOfLastYank && killRingNotEmpty) { - jtc.setSelectionStart(YankAction.start); - jtc.setSelectionEnd(YankAction.end); - String toYank = KillRing.getInstance().next(); - if (toYank == null) { - jtc.getToolkit().beep(); - } else { - jtc.replaceSelection(toYank); - YankAction.end = jtc.getCaretPosition(); - } - } - } - } - - public static class KillRing { - - /** - * Manages all killed (cut) text pieces in a ring which is accessible - * through {@link YankPopAction}. - *

- * Also provides an unmodifiable copy of all cut pieces. - */ - private static final KillRing INSTANCE = new KillRing(); - private JTextComponent jtc; - private final LinkedList ring = new LinkedList<>(); - - private Iterator iter = ring.iterator(); - - public static KillRing getInstance() { - return KillRing.INSTANCE; - } - - public void setCurrentTextComponent(JTextComponent jtc) { - this.jtc = jtc; - } - - public JTextComponent getCurrentTextComponent() { - return jtc; - } - - /** - * Adds text to the front of the kill ring. - *

- * Deviating from the Emacs implementation we make sure the - * exact same text is not somewhere else in the ring. - */ - public void add(String text) { - if (text.isEmpty()) { - return; - } - - ring.remove(text); - ring.addFirst(text); - while (ring.size() > 60) { - ring.removeLast(); - } - iter = ring.iterator(); - // skip first entry, the one we just added - iter.next(); - } - - /** - * Returns an unmodifiable version of the ring list which contains - * the killed texts. - * - * @return the content of the kill ring - */ - public List getRing() { - return Collections.unmodifiableList(ring); - } - - public boolean isEmpty() { - return ring.isEmpty(); - } - - /** - * Returns the next text element which is to be yank-popped. - * - * @return null if the ring is empty - */ - public String next() { - if (ring.isEmpty()) { - return null; - } else if (iter.hasNext()) { - return iter.next(); - } else { - iter = ring.iterator(); - // guaranteed to not throw an exception, since ring is not empty - return iter.next(); - } - } - } - - /** - * This action capitalizes the next word on the right side of the caret. - */ - @SuppressWarnings("serial") - public static class CapitalizeWordAction extends TextAction { - - public CapitalizeWordAction(String nm) { - super(nm); - } - - /** - * At first the same code as in {@link - * EmacsKeyBindings.DowncaseWordAction} is performed, to ensure the - * word is in lower case, then the first letter is capialized. - */ - @Override - public void actionPerformed(ActionEvent event) { - JTextComponent jtc = getTextComponent(event); - - if (jtc != null) { - try { - /* downcase code */ - int start = jtc.getCaretPosition(); - int end = EmacsKeyBindings.getWordEnd(jtc, start); - jtc.setSelectionStart(start); - jtc.setSelectionEnd(end); - String word = jtc.getText(start, end - start); - jtc.replaceSelection(word.toLowerCase(Locale.ROOT)); - - /* actual capitalize code */ - int offs = Utilities.getWordStart(jtc, start); - // get first letter - String c = jtc.getText(offs, 1); - // we're at the end of the previous word - if (" ".equals(c)) { - /* ugly java workaround to get the beginning of the - word. */ - offs = Utilities.getWordStart(jtc, ++offs); - c = jtc.getText(offs, 1); - } - if (Character.isLetter(c.charAt(0))) { - jtc.setSelectionStart(offs); - jtc.setSelectionEnd(offs + 1); - jtc.replaceSelection(c.toUpperCase(Locale.ROOT)); - } - end = Utilities.getWordEnd(jtc, offs); - jtc.setCaretPosition(end); - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - /** - * This action renders all characters of the next word to lowercase. - */ - @SuppressWarnings("serial") - public static class DowncaseWordAction extends TextAction { - - public DowncaseWordAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent event) { - JTextComponent jtc = getTextComponent(event); - - if (jtc != null) { - try { - int start = jtc.getCaretPosition(); - int end = EmacsKeyBindings.getWordEnd(jtc, start); - jtc.setSelectionStart(start); - jtc.setSelectionEnd(end); - String word = jtc.getText(start, end - start); - jtc.replaceSelection(word.toLowerCase(Locale.ROOT)); - jtc.setCaretPosition(end); - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - /** - * This action renders all characters of the next word to upppercase. - */ - @SuppressWarnings("serial") - public static class UpcaseWordAction extends TextAction { - - public UpcaseWordAction(String nm) { - super(nm); - } - - @Override - public void actionPerformed(ActionEvent event) { - JTextComponent jtc = getTextComponent(event); - - if (jtc != null) { - try { - int start = jtc.getCaretPosition(); - int end = EmacsKeyBindings.getWordEnd(jtc, start); - jtc.setSelectionStart(start); - jtc.setSelectionEnd(end); - String word = jtc.getText(start, end - start); - jtc.replaceSelection(word.toUpperCase(Locale.ROOT)); - jtc.setCaretPosition(end); - } catch (BadLocationException ble) { - jtc.getToolkit().beep(); - } - } - } - } - - private static int getWordEnd(JTextComponent jtc, int start) - throws BadLocationException { - try { - return Utilities.getNextWord(jtc, start); - } catch (BadLocationException ble) { - int end = jtc.getText().length(); - if (start < end) { - return end; - } else { - throw ble; - } - } - } -} diff --git a/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java b/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java index 0e8100e834e..309abf06ac8 100644 --- a/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java +++ b/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java @@ -1,9 +1,5 @@ package org.jabref.gui.keyboard; -import java.awt.AWTError; -import java.awt.HeadlessException; -import java.awt.Toolkit; -import java.awt.event.InputEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -14,8 +10,6 @@ import java.util.TreeMap; import java.util.stream.Collectors; -import javax.swing.KeyStroke; - import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyEvent; @@ -32,7 +26,7 @@ public class KeyBindingRepository { * sorted by localization */ private final SortedMap bindings; - private int shortcutMask = -1; + private final int shortcutMask = -1; public KeyBindingRepository() { this(Collections.emptyList(), Collections.emptyList()); @@ -126,32 +120,6 @@ public Optional mapToKeyBinding(KeyEvent keyEvent) { return Optional.empty(); } - public Optional mapToKeyBinding(java.awt.event.KeyEvent keyEvent) { - Optional keyCode = Arrays.stream(KeyCode.values()).filter(k -> k.impl_getCode() == keyEvent.getKeyCode()).findFirst(); - if (keyCode.isPresent()) { - KeyEvent event = new KeyEvent(keyEvent.getSource(), null, KeyEvent.KEY_PRESSED, "", "", keyCode.get(), keyEvent.isShiftDown(), keyEvent.isControlDown(), keyEvent.isAltDown(), keyEvent.isMetaDown()); - return mapToKeyBinding(event); - - } - - return Optional.empty(); - - } - - /** - * Returns the KeyStroke for this binding, as defined by the defaults, or in the Preferences. - */ - public KeyStroke getKey(KeyBinding bindName) { - String s = get(bindName.getConstant()); - s = s.replace("+", " "); //swing needs the keys without pluses but whitespace between the modifiers - - if (OS.OS_X) { - return getKeyForMac(KeyStroke.getKeyStroke(s)); - } else { - return KeyStroke.getKeyStroke(s); - } - } - public KeyCombination getKeyCombination(KeyBinding bindName) { String binding = get(bindName.getConstant()); if (OS.OS_X) { @@ -173,39 +141,6 @@ public boolean checkKeyCombinationEquality(KeyBinding binding, KeyEvent keyEvent return checkKeyCombinationEquality(keyCombination, keyEvent); } - /** - * Returns the KeyStroke for this binding, as defined by the defaults, or in the Preferences, but adapted for Mac - * users, with the Command key preferred instead of Control. - * TODO: Move to OS.java? Or replace with portable Java key codes, i.e. KeyEvent - */ - private KeyStroke getKeyForMac(KeyStroke ks) { - if (ks == null) { - return null; - } - int keyCode = ks.getKeyCode(); - if ((ks.getModifiers() & InputEvent.CTRL_MASK) == 0) { - return ks; - } else { - int modifiers = 0; - if ((ks.getModifiers() & InputEvent.SHIFT_MASK) != 0) { - modifiers = modifiers | InputEvent.SHIFT_MASK; - } - if ((ks.getModifiers() & InputEvent.ALT_MASK) != 0) { - modifiers = modifiers | InputEvent.ALT_MASK; - } - - if (shortcutMask == -1) { - try { - shortcutMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - } catch (AWTError | HeadlessException e) { - LOGGER.warn("Problem geting shortcut mask", e); - } - } - - return KeyStroke.getKeyStroke(keyCode, shortcutMask + modifiers); - } - } - public List getBindNames() { return bindings.keySet().stream().map(KeyBinding::getConstant).collect(Collectors.toList()); } diff --git a/src/main/java/org/jabref/gui/maintable/ListSynchronizer.java b/src/main/java/org/jabref/gui/maintable/ListSynchronizer.java deleted file mode 100644 index 6049ce243cb..00000000000 --- a/src/main/java/org/jabref/gui/maintable/ListSynchronizer.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.jabref.gui.maintable; - -import org.jabref.model.database.event.EntryAddedEvent; -import org.jabref.model.database.event.EntryRemovedEvent; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.event.EntryChangedEvent; - -import ca.odell.glazedlists.EventList; -import com.google.common.eventbus.Subscribe; - -public class ListSynchronizer { - - private final EventList list; - - public ListSynchronizer(EventList list) { - this.list = list; - } - - @Subscribe - public void listen(EntryAddedEvent entryAddedEvent) { - lock(); - try { - list.add(entryAddedEvent.getBibEntry()); - } finally { - unlock(); - } - } - - @Subscribe - public void listen(EntryRemovedEvent entryRemovedEvent) { - lock(); - try { - list.remove(entryRemovedEvent.getBibEntry()); - } finally { - unlock(); - } - } - - @Subscribe - public void listen(EntryChangedEvent entryChangedEvent) { - lock(); - try { - // cannot use list#indexOf b/c it won't distinguish between duplicates - for (int i = 0; i < list.size(); i++) { - if (list.get(i) == entryChangedEvent.getBibEntry()) { - list.set(i, entryChangedEvent.getBibEntry()); - break; - } - } - } finally { - unlock(); - } - } - - private void lock() { - list.getReadWriteLock().writeLock().lock(); - } - - private void unlock() { - list.getReadWriteLock().writeLock().unlock(); - } -} diff --git a/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java index aa3770d25f8..b3da27b7eb7 100644 --- a/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preferences/EntryEditorPrefsTab.java @@ -16,7 +16,6 @@ import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.entryeditor.FileDragDropPreferenceType; -import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -244,28 +243,7 @@ public void storeSettings() { prefs.putBoolean(JabRefPreferences.ACCEPT_RECOMMENDATIONS, acceptRecommendations.isSelected()); prefs.putBoolean(JabRefPreferences.SHOW_LATEX_CITATIONS, latexCitations.isSelected()); prefs.putBoolean(JabRefPreferences.VALIDATE_IN_ENTRY_EDITOR, validation.isSelected()); - boolean emacsModeChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS) != emacsMode.isSelected(); - boolean emacsRebindCtrlAChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA) != emacsRebindCtrlA.isSelected(); - boolean emacsRebindCtrlFChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF) != emacsRebindCtrlF.isSelected(); - if (emacsModeChanged || emacsRebindCtrlAChanged || emacsRebindCtrlFChanged) { - prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS, emacsMode.isSelected()); - prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA, emacsRebindCtrlA.isSelected()); - prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF, emacsRebindCtrlF.isSelected()); - // immediately apply the change - if (emacsModeChanged) { - if (emacsMode.isSelected()) { - EmacsKeyBindings.load(); - } else { - EmacsKeyBindings.unload(); - } - } else { - // only rebinding of CTRL+a or CTRL+f changed - assert emacsMode.isSelected(); - // we simply reload the emacs mode to activate the CTRL+a/CTRL+f change - EmacsKeyBindings.unload(); - EmacsKeyBindings.load(); - } - } + autoCompletePreferences.setShouldAutoComplete(autoComplete.isSelected()); autoCompletePreferences.setCompleteNames(autoCompFields.getText()); if (autoCompBoth.isSelected()) { diff --git a/src/main/java/org/jabref/gui/renderer/GeneralRenderer.java b/src/main/java/org/jabref/gui/renderer/GeneralRenderer.java deleted file mode 100644 index e0077dac5c3..00000000000 --- a/src/main/java/org/jabref/gui/renderer/GeneralRenderer.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.jabref.gui.renderer; - -import java.awt.Color; -import java.awt.Component; - -import javax.swing.Icon; -import javax.swing.JLabel; -import javax.swing.JTable; -import javax.swing.table.DefaultTableCellRenderer; - -/** - * Renderer for table cells, which supports both Icons, JLabels and plain text. - */ -public class GeneralRenderer extends DefaultTableCellRenderer { - - private final Color rendererBackground; - private Color selBackground; - - public GeneralRenderer(Color c) { - super(); - this.rendererBackground = c; - setBackground(c); - } - - /** - * Renderer with specified foreground and background colors, and default selected - * background color. - * @param c Foreground color - * @param fg Background color - */ - public GeneralRenderer(Color c, Color fg) { - this(c); - setForeground(fg); - } - - /** - * Renderer with specified foreground, background and selected background colors - * @param c Foreground color - * @param fg Unselected background color - * @param sel Selected background color - */ - public GeneralRenderer(Color c, Color fg, Color sel) { - this(c, fg); - this.selBackground = sel; - } - - @Override - public Component getTableCellRendererComponent(JTable table, Object o, boolean isSelected, - boolean hasFocus, int row, int column) { - if (selBackground == null) { - return super.getTableCellRendererComponent(table, o, isSelected, hasFocus, row, column); - } else { - Component c = super.getTableCellRendererComponent(table, o, isSelected, hasFocus, row, column); - if (isSelected) { - c.setBackground(selBackground); - } else { - c.setBackground(rendererBackground); - } - return c; - } - } - - @Override - public void firePropertyChange(String propertyName, Object old, Object newV) { - // disable super.firePropertyChange - } - - /* For enabling the renderer to handle icons. */ - @Override - protected void setValue(Object value) { - if (value instanceof Icon) { - setIcon((Icon) value); - setText(null); - } else if (value instanceof JLabel) { - JLabel lab = (JLabel) value; - setIcon(lab.getIcon()); - setToolTipText(lab.getToolTipText()); - if (lab.getIcon() != null) { - setText(null); - } - } else { - // this is plain text - setIcon(null); - setToolTipText(null); - if (value == null) { - setText(null); - } else { - setText(value.toString()); - } - } - } - -} diff --git a/src/main/java/org/jabref/gui/search/HitOrMissComparator.java b/src/main/java/org/jabref/gui/search/HitOrMissComparator.java deleted file mode 100644 index b018cacf5bd..00000000000 --- a/src/main/java/org/jabref/gui/search/HitOrMissComparator.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.jabref.gui.search; - -import java.util.Comparator; -import java.util.Objects; - -import org.jabref.model.entry.BibEntry; - -import ca.odell.glazedlists.matchers.Matcher; - -/** - * This Comparator compares two objects based on whether none, one of them, or both - * match a given Matcher. It is used to "float" group and search hits in the main table. - */ -public class HitOrMissComparator implements Comparator { - - private final Matcher hitOrMiss; - - public HitOrMissComparator(Matcher hitOrMiss) { - this.hitOrMiss = Objects.requireNonNull(hitOrMiss); - } - - @Override - public int compare(BibEntry o1, BibEntry o2) { - if (hitOrMiss == null) { - return 0; - } - - return Boolean.compare(hitOrMiss.matches(o2), hitOrMiss.matches(o1)); - } -} diff --git a/src/main/java/org/jabref/gui/search/matchers/EverythingMatcher.java b/src/main/java/org/jabref/gui/search/matchers/EverythingMatcher.java deleted file mode 100644 index 4e355b14c19..00000000000 --- a/src/main/java/org/jabref/gui/search/matchers/EverythingMatcher.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.jabref.gui.search.matchers; - -import org.jabref.model.entry.BibEntry; - -import ca.odell.glazedlists.matchers.Matcher; - -/** - * Matcher that accepts all entries. Used for filtering when so search is - * active. - */ -public class EverythingMatcher implements Matcher { - - public static final Matcher INSTANCE = new EverythingMatcher(); - - @Override - public boolean matches(BibEntry object) { - return true; - } -} diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldDropDown.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldDropDown.java deleted file mode 100644 index db6a2acb42c..00000000000 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldDropDown.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.jabref.gui.specialfields; - -import java.awt.Dimension; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; - -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.actions.Actions; -import org.jabref.logic.util.OS; -import org.jabref.model.entry.field.SpecialField; -import org.jabref.model.entry.field.SpecialFieldValue; - -public class SpecialFieldDropDown { - - private SpecialFieldDropDown() { - } - - public static JButton generateSpecialFieldButtonWithDropDown(SpecialField field, JabRefFrame frame) { - Dimension buttonDim = new Dimension(23, 23); - SpecialFieldViewModel viewModel = new SpecialFieldViewModel(field, frame.getUndoManager()); - JButton button = new JButton(viewModel.getRepresentingIcon()); - button.setToolTipText(viewModel.getLocalization()); - button.setPreferredSize(buttonDim); - if (!OS.OS_X) { - button.setMargin(new Insets(1, 0, 2, 0)); - } - button.setBorder(null); - button.setBorderPainted(false); - button.setRolloverEnabled(true); - button.setOpaque(false); - button.setBounds(0, 0, buttonDim.width, buttonDim.height); - button.setSize(buttonDim); - button.setMinimumSize(buttonDim); - button.setMaximumSize(buttonDim); - button.addActionListener(new MenuButtonActionListener(field, frame, button, buttonDim)); - return button; - } - - private static class MenuButtonActionListener implements ActionListener { - - private JPopupMenu popup; - private final Dimension dim; - private final JabRefFrame frame; - private final SpecialField field; - private final JButton button; - - - public MenuButtonActionListener(SpecialField field, JabRefFrame frame, JButton button, Dimension dim) { - this.field = field; - this.dim = dim; - this.frame = frame; - this.button = button; - } - - @Override - public void actionPerformed(ActionEvent e) { - if (popup == null) { - popup = new JPopupMenu(); - for (SpecialFieldValue val : field.getValues()) { - SpecialFieldValueViewModel viewModel = new SpecialFieldValueViewModel(val); - JMenuItem item = new JMenuItem(viewModel.getSpecialFieldValueIcon()); - item.setText(viewModel.getMenuString()); - item.setToolTipText(viewModel.getToolTipText()); - item.addActionListener(new PopupitemActionListener(frame.getCurrentBasePanel(), new SpecialFieldValueViewModel(val).getCommand())); - item.setMargin(new Insets(0, 0, 0, 0)); - popup.add(item); - } - } - popup.show(button, 0, dim.height); - } - - private class PopupitemActionListener implements ActionListener { - - private final BasePanel panel; - private final Actions actionName; - - public PopupitemActionListener(BasePanel panel, Actions actionName) { - this.panel = panel; - this.actionName = actionName; - } - - @Override - public void actionPerformed(ActionEvent e) { - panel.runCommand(actionName); - popup.setVisible(false); - } - - } - - } - -} diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java deleted file mode 100644 index b393e1002a9..00000000000 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldUpdateListener.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.jabref.gui.specialfields; - -import javax.swing.SwingUtilities; - -import org.jabref.Globals; -import org.jabref.JabRefGUI; -import org.jabref.logic.specialfields.SpecialFieldsUtils; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.event.FieldChangedEvent; -import org.jabref.model.entry.field.Field; -import org.jabref.model.entry.field.SpecialField; -import org.jabref.model.entry.field.StandardField; - -import com.google.common.eventbus.Subscribe; - -/** - * Listener triggering - * * an update of keywords if special field has been updated - * * an update of special fields if keywords have been updated - */ -public class SpecialFieldUpdateListener { - - private static SpecialFieldUpdateListener INSTANCE; - - @Subscribe - public void listen(FieldChangedEvent fieldChangedEvent) { - // only sync if keyword sync is enabled - if (!Globals.prefs.isKeywordSyncEnabled()) { - return; - } - - final BibEntry entry = fieldChangedEvent.getBibEntry(); - final Field field = fieldChangedEvent.getField(); - // Source editor cycles through all entries - // if we immediately updated the fields, the entry editor would detect a subsequent change as a user change - // and re-fire this event - // e.g., "keyword = {prio1}, priority = {prio2}" and a change at keyword to prio3 would not succeed. - SwingUtilities.invokeLater(() -> { - if (StandardField.KEYWORDS.equals(field)) { - SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, Globals.prefs.getKeywordDelimiter()); - } else if (field instanceof SpecialField) { - SpecialFieldsUtils.syncKeywordsFromSpecialFields(entry, Globals.prefs.getKeywordDelimiter()); - } - SwingUtilities.invokeLater(() -> JabRefGUI.getMainFrame().getCurrentBasePanel().updateEntryEditorIfShowing()); - }); - } - - public static SpecialFieldUpdateListener getInstance() { - if (SpecialFieldUpdateListener.INSTANCE == null) { - SpecialFieldUpdateListener.INSTANCE = new SpecialFieldUpdateListener(); - } - return SpecialFieldUpdateListener.INSTANCE; - } - -} diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldValueViewModel.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldValueViewModel.java index 82a5af8bd14..1a56592791f 100644 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldValueViewModel.java +++ b/src/main/java/org/jabref/gui/specialfields/SpecialFieldValueViewModel.java @@ -3,9 +3,6 @@ import java.util.Objects; import java.util.Optional; -import javax.swing.Icon; -import javax.swing.JLabel; - import org.jabref.gui.actions.Action; import org.jabref.gui.actions.Actions; import org.jabref.gui.actions.StandardActions; @@ -26,20 +23,10 @@ public SpecialFieldValue getValue() { return value; } - public Icon getSpecialFieldValueIcon() { - return getIcon().map(JabRefIcon::getSmallIcon).orElse(null); - } - public Optional getIcon() { return getAction().getIcon(); } - public JLabel createSpecialFieldValueLabel() { - JLabel label = new JLabel(getSpecialFieldValueIcon()); - label.setToolTipText(getToolTipText()); - return label; - } - public String getMenuString() { return getAction().getText(); } diff --git a/src/main/java/org/jabref/gui/specialfields/SpecialFieldViewModel.java b/src/main/java/org/jabref/gui/specialfields/SpecialFieldViewModel.java index 60d5010ba40..455e1708c71 100644 --- a/src/main/java/org/jabref/gui/specialfields/SpecialFieldViewModel.java +++ b/src/main/java/org/jabref/gui/specialfields/SpecialFieldViewModel.java @@ -4,7 +4,6 @@ import java.util.Objects; import java.util.stream.Collectors; -import javax.swing.Icon; import javax.swing.undo.UndoManager; import org.jabref.Globals; @@ -41,10 +40,6 @@ public SpecialFieldAction getSpecialFieldAction(SpecialFieldValue value, JabRefF getLocalization()); } - public Icon getRepresentingIcon() { - return getAction().getIcon().map(JabRefIcon::getSmallIcon).orElse(null); - } - public JabRefIcon getIcon() { return getAction().getIcon().orElse(null); } diff --git a/src/main/java/org/jabref/gui/texparser/ParseTexResult.fxml b/src/main/java/org/jabref/gui/texparser/ParseTexResult.fxml index ff8ee769fcf..68cae58e98e 100644 --- a/src/main/java/org/jabref/gui/texparser/ParseTexResult.fxml +++ b/src/main/java/org/jabref/gui/texparser/ParseTexResult.fxml @@ -6,7 +6,6 @@ - diff --git a/src/main/java/org/jabref/gui/util/ColorUtil.java b/src/main/java/org/jabref/gui/util/ColorUtil.java index 90284d24250..4fbaafac6f4 100644 --- a/src/main/java/org/jabref/gui/util/ColorUtil.java +++ b/src/main/java/org/jabref/gui/util/ColorUtil.java @@ -3,30 +3,15 @@ import javafx.scene.paint.Color; public class ColorUtil { - public static java.awt.Color toAWT(Color color) { - return new java.awt.Color((float) color.getRed(), - (float) color.getGreen(), - (float) color.getBlue(), - (float) color.getOpacity()); - } - - public static Color toFX(java.awt.Color awtColor) { - int r = awtColor.getRed(); - int g = awtColor.getGreen(); - int b = awtColor.getBlue(); - int a = awtColor.getAlpha(); - double opacity = a / 255.0; - return Color.rgb(r, g, b, opacity); - } public static String toRGBCode(Color color) { return String.format("#%02X%02X%02X", - (int) (color.getRed() * 255), - (int) (color.getGreen() * 255), - (int) (color.getBlue() * 255)); + (int) (color.getRed() * 255), + (int) (color.getGreen() * 255), + (int) (color.getBlue() * 255)); } - public static String toHex(java.awt.Color color) { - return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue()); + public static String toHex(Color validFieldBackgroundColor) { + return String.format("#%02x%02x%02x", (int) validFieldBackgroundColor.getRed(), (int) validFieldBackgroundColor.getGreen(), (int) validFieldBackgroundColor.getBlue()); } } diff --git a/src/main/java/org/jabref/gui/util/WindowLocation.java b/src/main/java/org/jabref/gui/util/WindowLocation.java deleted file mode 100644 index 2655fc9857c..00000000000 --- a/src/main/java/org/jabref/gui/util/WindowLocation.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.jabref.gui.util; - -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Window; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; - -import javax.swing.JFrame; - -import org.jabref.Globals; - -/** - * Restores and saves the position of non-modal windows inside the JabRef preferences. - * - * Includes multi-monitor support. - * If a windows is placed on another monitor than the main one, it tries to restore that position afterwards. - * If the stored position in a multi-monitor setup is not available anymore, it places the window on an equivalent position on the main monitor. - */ -public class WindowLocation { - private final String posXKey; - private final String posYKey; - private final String sizeXKey; - private final String sizeYKey; - private final Window window; - - public WindowLocation(Window window, String posXKey, String posYKey, String sizeXKey, String sizeYKey) { - this.window = window; - this.posXKey = posXKey; - this.posYKey = posYKey; - this.sizeXKey = sizeXKey; - this.sizeYKey = sizeYKey; - - // set up a ComponentListener that saves the last size and position of the dialog - window.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - storeCurrentWindowLocation(); - } - - @Override - public void componentMoved(ComponentEvent e) { - storeCurrentWindowLocation(); - } - }); - } - - public void displayWindowAtStoredLocation() { - WindowPosition storedPosition = getStoredLocation(); - - // preference values are wrong/not in multi-monitor setup anymore - if (!isDisplayable(storedPosition)) { - // adapt position to be inside available boundaries - storedPosition = adaptPosition(storedPosition); - } - - setWindowLocation(storedPosition); - } - - public void storeCurrentWindowLocation() { - // maximizing is handled explicitely - if (window instanceof Frame) { - Frame frame = (Frame) window; - if (frame.getExtendedState() == Frame.MAXIMIZED_BOTH) { - return; - } - } - Point location = window.getLocation(); - Dimension dimensions = window.getSize(); - - Globals.prefs.putInt(posXKey, location.x); - Globals.prefs.putInt(posYKey, location.y); - Globals.prefs.putInt(sizeXKey, dimensions.width); - Globals.prefs.putInt(sizeYKey, dimensions.height); - } - - private WindowPosition getStoredLocation() { - int sizeX = Globals.prefs.getInt(sizeXKey); - int sizeY = Globals.prefs.getInt(sizeYKey); - int posX = Globals.prefs.getInt(posXKey); - int posY = Globals.prefs.getInt(posYKey); - - return new WindowPosition(posX, posY, sizeX, sizeY); - } - - private void setWindowLocation(WindowPosition storedPosition) { - window.setLocation(storedPosition.posX, storedPosition.posY); - window.setSize(storedPosition.sizeX, storedPosition.sizeY); - } - - private boolean isDisplayable(WindowPosition position) { - JFrame frame = new JFrame(); - frame.setBounds(position.posX, position.posY, position.sizeX, position.sizeY); - - return getVirtualBounds().contains(frame.getBounds()); - } - - private Rectangle getVirtualBounds() { - Rectangle bounds = new Rectangle(0, 0, 0, 0); - GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); - - for (GraphicsDevice device : devices) { - bounds.add(device.getDefaultConfiguration().getBounds()); - } - return bounds; - } - - private WindowPosition adaptPosition(WindowPosition position) { - if (isDisplayable(position)) { - return position; - } - - // current algorithm: - // 1. try to move to main screen - // 2. use default sizes on main monitor - GraphicsDevice mainScreen = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - int mainScreenHeight = mainScreen.getDisplayMode().getHeight(); - int mainScreenWidth = mainScreen.getDisplayMode().getWidth(); - - int newPosX = position.posX; - int newPosY = position.posY; - int newSizeX = position.sizeX; - int newSizeY = position.sizeY; - - if ((position.posX + position.sizeX) > mainScreenWidth) { - if (position.sizeX <= mainScreenWidth) { - newPosX = mainScreenWidth - position.sizeX; - } else { - newPosX = Globals.prefs.getIntDefault(posXKey); - newSizeX = Globals.prefs.getIntDefault(sizeXKey); - } - } - - if ((position.posY + position.sizeY) > mainScreenHeight) { - if (position.sizeY <= mainScreenHeight) { - newPosY = mainScreenHeight - position.sizeY; - } else { - newPosY = Globals.prefs.getIntDefault(posYKey); - newSizeY = Globals.prefs.getIntDefault(sizeYKey); - } - } - - return new WindowPosition(newPosX, newPosY, newSizeX, newSizeY); - } - - static class WindowPosition { - public final int posX; - public final int posY; - public final int sizeX; - public final int sizeY; - - public WindowPosition(int posX, int posY, int sizeX, int sizeY) { - this.posX = posX; - this.posY = posY; - this.sizeX = sizeX; - this.sizeY = sizeY; - } - } -} diff --git a/src/main/java/org/jabref/gui/util/component/OverlayPanel.java b/src/main/java/org/jabref/gui/util/component/OverlayPanel.java deleted file mode 100644 index 08cabd6825f..00000000000 --- a/src/main/java/org/jabref/gui/util/component/OverlayPanel.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.jabref.gui.util.component; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; - -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.OverlayLayout; -import javax.swing.ScrollPaneConstants; - -/** - * Supports an underlying text for JComponent - */ -public class OverlayPanel extends JPanel { - - private final JLabel label; - - - public OverlayPanel(JComponent overlay, String text) { - OverlayLayout layout = new OverlayLayout(this); - this.setLayout(layout); - - label = new JLabel(text); - label.setFont(new Font(label.getFont().getName(), Font.ITALIC, 18)); - label.setForeground(new Color(224, 220, 220)); - label.setLocation(0, 0); - - JScrollPane scroller = new JScrollPane(overlay); - scroller.setLocation(0, 0); - scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - - add(label); - add(scroller); - } - - @Override - public void paint(Graphics g) { - int len = label.getWidth(); - - Dimension dim = this.getSize(); - if ((dim.height > 25) && (dim.width > (len + 10))) { - int x = (dim.width - len) / 2; - int y = dim.height / 2; - - label.setLocation(x, y); - } - - super.paint(g); - } - -} diff --git a/src/main/java/org/jabref/logic/l10n/Localization.java b/src/main/java/org/jabref/logic/l10n/Localization.java index cd260d8cf57..168dc0082be 100644 --- a/src/main/java/org/jabref/logic/l10n/Localization.java +++ b/src/main/java/org/jabref/logic/l10n/Localization.java @@ -79,7 +79,6 @@ public static void setLanguage(Language language) { } locale = langLocale; Locale.setDefault(locale); - javax.swing.JComponent.setDefaultLocale(locale); try { createResourceBundles(locale); diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 4022e0e9766..ecf4c79ac3c 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -1,7 +1,5 @@ package org.jabref.preferences; -import java.awt.Color; -import java.awt.Font; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -36,6 +34,7 @@ import java.util.stream.Stream; import javafx.scene.control.TableColumn.SortType; +import javafx.scene.paint.Color; import org.jabref.Globals; import org.jabref.JabRefException; @@ -225,6 +224,7 @@ public class JabRefPreferences implements PreferencesService { public static final String OVERRIDE_DEFAULT_FONT_SIZE = "overrideDefaultFontSize"; public static final String MAIN_FONT_SIZE = "mainFontSize"; public static final String FONT_STYLE = "fontStyle"; + public static final String RECENT_DATABASES = "recentDatabases"; public static final String RENAME_ON_MOVE_FILE_TO_FILE_DIR = "renameOnMoveFileToFileDir"; public static final String MEMORY_STICK_MODE = "memoryStickMode"; @@ -600,7 +600,7 @@ private JabRefPreferences() { defaults.put(SHOW_ADVANCED_HINTS, Boolean.TRUE); defaults.put(RENAME_ON_MOVE_FILE_TO_FILE_DIR, Boolean.TRUE); - defaults.put(FONT_STYLE, Font.PLAIN); + defaults.put(FONT_STYLE, 0); //for backwards compatibility, is equal to java.awt.Font.PLAIN defaults.put(FONT_SIZE, 12); // Main table color settings: defaults.put(VALID_FIELD_BACKGROUND_COLOR, "255:255:255"); @@ -1128,13 +1128,13 @@ public List getStringList(String key) { public Color getColor(String key) { String value = get(key); int[] rgb = getRgb(value); - return new Color(rgb[0], rgb[1], rgb[2]); + return Color.rgb(rgb[0], rgb[1], rgb[2]); } public Color getDefaultColor(String key) { String value = (String) defaults.get(key); int[] rgb = getRgb(value); - return new Color(rgb[0], rgb[1], rgb[2]); + return Color.rgb(rgb[0], rgb[1], rgb[2]); } /** @@ -1981,6 +1981,10 @@ public Optional getFontSize() { } } + public String getFontFamily() { + return get(FONT_FAMILY); + } + public String setLastPreferencesExportPath() { return get(PREFS_EXPORT_PATH); } diff --git a/src/main/resources/csl-locales b/src/main/resources/csl-locales index 29ed2ff4328..e89e6b08b5c 160000 --- a/src/main/resources/csl-locales +++ b/src/main/resources/csl-locales @@ -1 +1 @@ -Subproject commit 29ed2ff43284f726f9f583981650a86ffb9b236f +Subproject commit e89e6b08b5c621a414fc7114f2129efac5f8c7d5 diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index 6ed87f55fd7..7c8f108ce4f 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit 6ed87f55fd75fcecbf8f6b8a96d5edd0c935702e +Subproject commit 7c8f108ce4f855e405486dff83a89ffe2ccda671 diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index c39fa9f646d..7a7a1bd3881 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -554,12 +554,8 @@ Modified\ string=Modified string Modify=Modify -Move\ down=Move down - move\ group=move group -Move\ up=Move up - Moved\ group\ "%0".=Moved group "%0". No\ recommendations\ received\ from\ Mr.\ DLib\ for\ this\ entry.=No recommendations received from Mr. DLib for this entry. @@ -947,8 +943,6 @@ Try\ different\ encoding=Try different encoding Unabbreviate\ journal\ names\ of\ the\ selected\ entries=Unabbreviate journal names of the selected entries Unabbreviated\ %0\ journal\ names.=Unabbreviated %0 journal names. -Unable\ to\ open\ %0=Unable to open %0 -Unable\ to\ open\ link.\ The\ application\ '%0'\ associated\ with\ the\ file\ type\ '%1'\ could\ not\ be\ called.=Unable to open link. The application '%0' associated with the file type '%1' could not be called. unable\ to\ write\ to=unable to write to Undo=Undo @@ -1518,8 +1512,6 @@ Ill-formed\ entrytype\ comment\ in\ BIB\ file=Ill-formed entrytype comment in BI Move\ linked\ files\ to\ default\ file\ directory\ %0=Move linked files to default file directory %0 Do\ you\ still\ want\ to\ continue?=Do you still want to continue? -This\ action\ will\ modify\ the\ following\ field(s)\ in\ at\ least\ one\ entry\ each\:=This action will modify the following field(s) in at least one entry each: -This\ could\ cause\ undesired\ changes\ to\ your\ entries.=This could cause undesired changes to your entries. Run\ field\ formatter\:=Run field formatter: Table\ font\ size\ is\ %0=Table font size is %0 Internal\ style=Internal style diff --git a/src/test/java/org/jabref/architecture/MainArchitectureTestsWithArchUnit.java b/src/test/java/org/jabref/architecture/MainArchitectureTestsWithArchUnit.java index ab22b7dd5aa..56f7a70888c 100644 --- a/src/test/java/org/jabref/architecture/MainArchitectureTestsWithArchUnit.java +++ b/src/test/java/org/jabref/architecture/MainArchitectureTestsWithArchUnit.java @@ -2,6 +2,7 @@ import com.tngtech.archunit.core.domain.JavaClasses; import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchIgnore; import com.tngtech.archunit.junit.ArchTest; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; @@ -15,4 +16,36 @@ public static void doNotUseApacheCommonsLang3(JavaClasses classes) { .should().accessClassesThat().resideInAPackage("org.apache.commons.lang3") .check(classes); } + + @ArchTest + public static void doNotUseSwing(JavaClasses classes) { + // This checks for all all Swing packages, but not the UndoManager + noClasses().should().accessClassesThat().resideInAnyPackage("javax.swing", + "javax.swing.border..", + "javax.swing.colorchooser..", + "javax.swing.event..", + "javax.swing.filechooser..", + "javax.swing.plaf..", + "javax.swing.table..", + "javax.swing.text..", + "javax.swing.tree.." + ).check(classes); + } + + @ArchTest + public static void doNotUseJGoodies(JavaClasses classes) { + noClasses().should().accessClassesThat().resideInAPackage("com.jgoodies..").check(classes); + } + + @ArchTest + public static void doNotUseGlazedLists(JavaClasses classes) { + noClasses().should().accessClassesThat().resideInAPackage("ca.odell.glazedlists..").check(classes); + } + + //"Currently disabled as there is no alternative for the rest of classes who need awt" + @ArchIgnore + @ArchTest + public static void doNotUseJavaAWT(JavaClasses classes) { + noClasses().should().accessClassesThat().resideInAPackage("java.awt..").check(classes); + } } diff --git a/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java b/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java index c9c34e25e0e..1bdc248771a 100644 --- a/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java +++ b/src/test/java/org/jabref/gui/keyboard/KeyBindingsDialogViewModelTest.java @@ -1,10 +1,5 @@ package org.jabref.gui.keyboard; -import java.awt.event.InputEvent; -import java.util.Optional; - -import javax.swing.JFrame; - import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyEvent; @@ -41,7 +36,7 @@ public void setUp() { public void testInvalidKeyBindingIsNotSaved() { setKeyBindingViewModel(KeyBinding.COPY); KeyEvent shortcutKeyEvent = new KeyEvent(KeyEvent.KEY_RELEASED, "Q", "Q", KeyCode.Q, false, false, false, - false); + false); assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.COPY, shortcutKeyEvent)); model.setNewBindingForCurrent(shortcutKeyEvent); KeyCombination combination = KeyCombination.keyCombination(keyBindingRepository.get(KeyBinding.COPY).get()); @@ -54,20 +49,20 @@ public void testInvalidKeyBindingIsNotSaved() { public void testSpecialKeysValidKeyBindingIsSaved() { setKeyBindingViewModel(KeyBinding.IMPORT_INTO_NEW_DATABASE); KeyEvent shortcutKeyEvent = new KeyEvent(KeyEvent.KEY_RELEASED, "F1", "F1", KeyCode.F1, false, false, false, - false); + false); assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.IMPORT_INTO_NEW_DATABASE, - shortcutKeyEvent)); + shortcutKeyEvent)); model.setNewBindingForCurrent(shortcutKeyEvent); KeyCombination combination = KeyCombination - .keyCombination(keyBindingRepository.get(KeyBinding.IMPORT_INTO_NEW_DATABASE).get()); + .keyCombination(keyBindingRepository.get(KeyBinding.IMPORT_INTO_NEW_DATABASE).get()); assertTrue(KeyBindingRepository.checkKeyCombinationEquality(combination, shortcutKeyEvent)); model.saveKeyBindings(); assertTrue(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.IMPORT_INTO_NEW_DATABASE, - shortcutKeyEvent)); + shortcutKeyEvent)); } @Test @@ -112,7 +107,7 @@ public void testSaveNewKeyBindingsToPreferences() { public void testSaveNewSpecialKeysKeyBindingsToPreferences() { setKeyBindingViewModel(KeyBinding.ABBREVIATE); KeyEvent shortcutKeyEvent = new KeyEvent(KeyEvent.KEY_PRESSED, "F1", "F1", KeyCode.F1, true, false, false, - false); + false); assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.ABBREVIATE, shortcutKeyEvent)); model.setNewBindingForCurrent(shortcutKeyEvent); @@ -177,16 +172,6 @@ public void testSetSingleKeyBindingToDefault() { assertFalse(keyBindingRepository.checkKeyCombinationEquality(KeyBinding.ABBREVIATE, shortcutKeyEvent)); } - @Test - public void testConversionAwtKeyEventJavafxKeyEvent() { - assumeFalse(OS.OS_X); - - java.awt.event.KeyEvent evt = new java.awt.event.KeyEvent(mock(JFrame.class), 0, 0, InputEvent.CTRL_MASK, java.awt.event.KeyEvent.VK_S, java.awt.event.KeyEvent.CHAR_UNDEFINED); - - Optional keyBinding = keyBindingRepository.mapToKeyBinding(evt); - assertEquals(Optional.of(KeyBinding.SAVE_DATABASE), keyBinding); - } - private KeyBindingViewModel setKeyBindingViewModel(KeyBinding binding) { KeyBindingViewModel bindViewModel = new KeyBindingViewModel(keyBindingRepository, binding, binding.getDefaultKeyBinding()); model.selectedKeyBindingProperty().set(bindViewModel); diff --git a/src/test/java/org/jabref/logic/l10n/LocalizationTest.java b/src/test/java/org/jabref/logic/l10n/LocalizationTest.java index 377ef0b0911..bd60ee446f6 100644 --- a/src/test/java/org/jabref/logic/l10n/LocalizationTest.java +++ b/src/test/java/org/jabref/logic/l10n/LocalizationTest.java @@ -20,7 +20,6 @@ void storeDefaultLocale() { @AfterEach void restoreDefaultLocale() { Locale.setDefault(locale); - javax.swing.JComponent.setDefaultLocale(locale); Localization.setLanguage(Language.ENGLISH); }