From 31e6797d8a1d0827180b0b54ea4a8b5fef936a59 Mon Sep 17 00:00:00 2001 From: Li Yiming Date: Wed, 18 Jul 2018 03:43:07 +0800 Subject: [PATCH 1/7] Fixed: #4166 add move & rename file (#4217) * Fixed: #4166 add move & rename file * Updated: CHANGELOG.md --- CHANGELOG.md | 1 + .../jabref/gui/fieldeditors/LinkedFileViewModel.java | 5 +++++ .../org/jabref/gui/fieldeditors/LinkedFilesEditor.java | 6 +++++- src/main/resources/l10n/JabRef_en.properties | 2 ++ src/main/resources/l10n/JabRef_zh.properties | 10 ++++++---- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61cf25bc5be..c1cfb3cef5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## [Unreleased] ### Changed +- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) - Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) - We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) - The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index e1480c08688..f0639545af8 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -281,6 +281,11 @@ public void moveToDefaultDirectory() { } } + public void moveToDefaultDirectoryAndRename() { + moveToDefaultDirectory(); + rename(); + } + public boolean delete(FileDirectoryPreferences prefs) { Optional file = linkedFile.findIn(databaseContext, prefs); diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java index 2758f5583cd..153caee75a1 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java @@ -259,6 +259,10 @@ private ContextMenu createContextMenuForFile(LinkedFileViewModel linkedFile) { moveFile.setOnAction(event -> linkedFile.moveToDefaultDirectory()); moveFile.setDisable(linkedFile.getFile().isOnlineLink()); + MenuItem renameAndMoveFile = new MenuItem(Localization.lang("Move file to file directory and rename file")); + renameAndMoveFile.setOnAction(event -> linkedFile.moveToDefaultDirectoryAndRename()); + renameAndMoveFile.setDisable(linkedFile.getFile().isOnlineLink()); + MenuItem deleteFile = new MenuItem(Localization.lang("Permanently delete local file")); deleteFile.setOnAction(event -> viewModel.deleteFile(linkedFile)); deleteFile.setDisable(linkedFile.getFile().isOnlineLink()); @@ -273,7 +277,7 @@ private ContextMenu createContextMenuForFile(LinkedFileViewModel linkedFile) { if (linkedFile.getFile().isOnlineLink()) { menu.getItems().add(download); } - menu.getItems().addAll(renameFile, moveFile, deleteLink, deleteFile); + menu.getItems().addAll(renameFile, moveFile, renameAndMoveFile, deleteLink, deleteFile); return menu; } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index e521d6e9272..10a193f6020 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -1185,6 +1185,8 @@ Query\ '%0'\ with\ fetcher\ '%1'\ did\ not\ return\ any\ results.=Query '%0' wit Move\ file=Move file Rename\ file=Rename file +Move\ file\ to\ file\ directory\ and\ rename\ file=Move file to file directory and rename file + Move\ file\ failed=Move file failed Could\ not\ move\ file\ '%0'.=Could not move file '%0'. Could\ not\ find\ file\ '%0'.=Could not find file '%0'. diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 9d3de79901d..0cefa1dd0a5 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -196,7 +196,7 @@ Copied\ keys=已复制 BibTeX 键 Copy=复制 Copy\ BibTeX\ key=复制 BibTeX 键 -Copy\ file\ to\ file\ directory=拷贝文件到文件目录。 +Copy\ file\ to\ file\ directory=拷贝文件到文件目录 Copy\ to\ clipboard=复制到剪贴板 @@ -1181,8 +1181,10 @@ Could\ not\ find\ fetcher\ '%0'=无法找到抓取器 '%0' Running\ query\ '%0'\ with\ fetcher\ '%1'.=使用抓取器'%1'执行请求'%0' Query\ '%0'\ with\ fetcher\ '%1'\ did\ not\ return\ any\ results.=使用抓取器'%1'请求'%0'未返回任何结果。 -Move\ file=移动 文件 -Rename\ file=重命名 文件 +Move\ file=移动文件 +Rename\ file=重命名文件 + +Move\ file\ to\ file\ directory\ and\ rename\ file=移动文件到文件目录重命名文件 Move\ file\ failed=移动文件失败 Could\ not\ move\ file\ '%0'.=无法移动文件 '%0' @@ -1262,7 +1264,7 @@ Enforce\ legal\ characters\ in\ BibTeX\ keys=强制在 BibTeX 键值中使用合 Save\ without\ backup?=保存但不备份? Unable\ to\ create\ backup=无法创建备份 -Move\ file\ to\ file\ directory=移动文件到文件目录。 +Move\ file\ to\ file\ directory=移动文件到文件目录 Rename\ file\ to=将文件更名为 All\ Entries\ (this\ group\ cannot\ be\ edited\ or\ removed)=所有记录(此分组无法被编辑或者删除) static\ group=静态分组 From d50bb417a154720d56c7e9724701c361356d0bb0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 18 Jul 2018 14:30:32 +0200 Subject: [PATCH 2/7] Fix that swing dialogs are hidden behind main window (#4205) * Remove unnecessary look and feel migration * Remove unused look and feel references * Fix that swing dialogs are hidden behind main window * Remove passing null values for owner frame * Add fixme --- src/main/java/org/jabref/gui/BasePanel.java | 2 +- .../jabref/gui/DuplicateResolverDialog.java | 3 +- .../java/org/jabref/gui/EntryTypeDialog.java | 2 +- .../jabref/gui/FindUnlinkedFilesDialog.java | 5 +-- .../org/jabref/gui/GenFieldsCustomizer.java | 3 +- .../java/org/jabref/gui/JabRefDialog.java | 43 ++++++++----------- src/main/java/org/jabref/gui/MergeDialog.java | 3 +- .../org/jabref/gui/ReplaceStringDialog.java | 3 +- .../java/org/jabref/gui/StringDialog.java | 2 +- .../gui/actions/DatabasePropertiesAction.java | 2 +- .../gui/actions/FindUnlinkedFilesAction.java | 2 +- .../jabref/gui/actions/WriteXMPAction.java | 8 ++-- .../jabref/gui/auximport/FromAuxDialog.java | 3 +- .../BibtexKeyPatternDialog.java | 3 +- .../gui/collab/ChangeDisplayDialog.java | 8 ++-- .../org/jabref/gui/collab/ChangeScanner.java | 2 +- .../ContentSelectorDialog.java | 6 +-- .../EntryTypeCustomizationDialog.java | 3 +- .../DatabasePropertiesDialog.java | 5 +-- .../gui/exporter/CustomExportDialog.java | 3 +- .../exporter/ExportCustomizationDialog.java | 3 +- .../org/jabref/gui/groups/GroupDialog.java | 3 +- .../org/jabref/gui/help/NewVersionDialog.java | 7 +-- .../importer/ImportCustomizationDialog.java | 3 +- .../gui/importer/ImportInspectionDialog.java | 2 +- .../gui/mergeentries/MergeEntriesDialog.java | 3 +- .../mergeentries/MergeFetchedEntryDialog.java | 3 +- .../gui/plaintextimport/TextInputDialog.java | 2 +- .../gui/preftabs/PreferencesDialog.java | 2 +- .../gui/preftabs/PreferencesFilterDialog.java | 5 +-- .../NewProtectedTermsFileDialog.java | 3 +- .../shared/ConnectToSharedDatabaseDialog.java | 3 +- .../org/jabref/gui/worker/VersionWorker.java | 2 +- 33 files changed, 60 insertions(+), 92 deletions(-) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index c7820865c80..54938361525 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -455,7 +455,7 @@ private void setupActions() { actions.put(Actions.PREVIOUS_PREVIEW_STYLE, this::previousPreviewStyle); actions.put(Actions.MANAGE_SELECTORS, () -> { - ContentSelectorDialog csd = new ContentSelectorDialog(null, frame, BasePanel.this, false, null); + ContentSelectorDialog csd = new ContentSelectorDialog(frame, BasePanel.this, false, null); csd.setVisible(true); }); diff --git a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java b/src/main/java/org/jabref/gui/DuplicateResolverDialog.java index 2151be6eaa3..c7d939cbd87 100644 --- a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java +++ b/src/main/java/org/jabref/gui/DuplicateResolverDialog.java @@ -6,7 +6,6 @@ import javax.swing.Box; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JPanel; import org.jabref.gui.help.HelpAction; @@ -46,7 +45,7 @@ public enum DuplicateResolverResult { private MergeEntries me; public DuplicateResolverDialog(JabRefFrame frame, BibEntry one, BibEntry two, DuplicateResolverType type) { - super((JFrame) null, Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class); + super(Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class); this.frame = frame; init(one, two, type); } diff --git a/src/main/java/org/jabref/gui/EntryTypeDialog.java b/src/main/java/org/jabref/gui/EntryTypeDialog.java index e91ebcb00b8..b4cdc9a0abc 100644 --- a/src/main/java/org/jabref/gui/EntryTypeDialog.java +++ b/src/main/java/org/jabref/gui/EntryTypeDialog.java @@ -66,7 +66,7 @@ public class EntryTypeDialog extends JabRefDialog implements ActionListener { public EntryTypeDialog(JabRefFrame frame) { // modal dialog - super(null, true, EntryTypeDialog.class); + super(true, EntryTypeDialog.class); this.frame = frame; diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index 7d2a77b38bf..e41f30dc616 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -3,7 +3,6 @@ import java.awt.Component; import java.awt.Container; import java.awt.Dimension; -import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -158,8 +157,8 @@ public class FindUnlinkedFilesDialog extends JabRefDialog { private boolean checkBoxWhyIsThereNoGetSelectedStupidSwing; - public FindUnlinkedFilesDialog(Frame owner, JabRefFrame frame) { - super(owner, Localization.lang("Find unlinked files"), true, FindUnlinkedFilesDialog.class); + public FindUnlinkedFilesDialog(JabRefFrame frame) { + super(Localization.lang("Find unlinked files"), true, FindUnlinkedFilesDialog.class); this.frame = frame; restoreSizeOfDialog(); diff --git a/src/main/java/org/jabref/gui/GenFieldsCustomizer.java b/src/main/java/org/jabref/gui/GenFieldsCustomizer.java index 6bff3e65d56..f913bbe5cc8 100644 --- a/src/main/java/org/jabref/gui/GenFieldsCustomizer.java +++ b/src/main/java/org/jabref/gui/GenFieldsCustomizer.java @@ -16,7 +16,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -51,7 +50,7 @@ public class GenFieldsCustomizer extends JabRefDialog { private final JButton revert = new JButton(); public GenFieldsCustomizer(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Set general fields"), false, GenFieldsCustomizer.class); + super(Localization.lang("Set general fields"), false, GenFieldsCustomizer.class); helpBut = new HelpAction(HelpFile.GENERAL_FIELDS).getHelpButton(); jbInit(); setSize(new Dimension(650, 300)); diff --git a/src/main/java/org/jabref/gui/JabRefDialog.java b/src/main/java/org/jabref/gui/JabRefDialog.java index 3a70de1a368..3221956a393 100644 --- a/src/main/java/org/jabref/gui/JabRefDialog.java +++ b/src/main/java/org/jabref/gui/JabRefDialog.java @@ -1,7 +1,6 @@ package org.jabref.gui; import java.awt.Frame; -import java.awt.Window; import javax.swing.JDialog; @@ -9,30 +8,20 @@ public class JabRefDialog extends JDialog { - public JabRefDialog(Frame owner, boolean modal, Class clazz) { - super(owner, modal); - - trackDialogOpening(clazz); + public JabRefDialog(boolean modal, Class clazz) { + this("JabRef", modal, clazz); } public JabRefDialog(Class clazz) { - super(); - - trackDialogOpening(clazz); + this(true, clazz); } - public JabRefDialog(Frame owner, Class clazz) { - super(owner); - - trackDialogOpening(clazz); + public JabRefDialog(String title, Class clazz) { + this(title, true, clazz); } - public JabRefDialog(Frame owner, String title, Class clazz) { - this(owner, title, true, clazz); - } - - public JabRefDialog(Frame owner, String title, boolean modal, Class clazz) { - super(owner, title, modal); + public JabRefDialog(String title, boolean modal, Class clazz) { + super((Frame) null, title, modal); trackDialogOpening(clazz); } @@ -47,13 +36,19 @@ public JabRefDialog(java.awt.Dialog owner, String titl trackDialogOpening(clazz); } - public JabRefDialog(Window owner, String title, Class clazz) { - super(owner, title); - - 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/MergeDialog.java b/src/main/java/org/jabref/gui/MergeDialog.java index 8129da56e1b..09ddfb6677d 100644 --- a/src/main/java/org/jabref/gui/MergeDialog.java +++ b/src/main/java/org/jabref/gui/MergeDialog.java @@ -13,7 +13,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import org.jabref.Globals; @@ -41,7 +40,7 @@ public class MergeDialog extends JabRefDialog { private boolean okPressed; public MergeDialog(JabRefFrame frame, String title, boolean modal) { - super((JFrame) null, title, modal, MergeDialog.class); + super(title, modal, MergeDialog.class); jbInit(); pack(); } diff --git a/src/main/java/org/jabref/gui/ReplaceStringDialog.java b/src/main/java/org/jabref/gui/ReplaceStringDialog.java index 10fd5ccc1cf..4c493260c00 100644 --- a/src/main/java/org/jabref/gui/ReplaceStringDialog.java +++ b/src/main/java/org/jabref/gui/ReplaceStringDialog.java @@ -16,7 +16,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -48,7 +47,7 @@ class ReplaceStringDialog extends JabRefDialog { public ReplaceStringDialog(JabRefFrame parent) { - super((JFrame) null, Localization.lang("Replace string"), true, ReplaceStringDialog.class); + super(Localization.lang("Replace string"), true, ReplaceStringDialog.class); ButtonGroup bg = new ButtonGroup(); bg.add(allFi); diff --git a/src/main/java/org/jabref/gui/StringDialog.java b/src/main/java/org/jabref/gui/StringDialog.java index 796a557dbec..1169b1f7dce 100644 --- a/src/main/java/org/jabref/gui/StringDialog.java +++ b/src/main/java/org/jabref/gui/StringDialog.java @@ -66,7 +66,7 @@ class StringDialog extends JabRefDialog { public StringDialog(JabRefFrame frame, BasePanel panel, BibDatabase base) { - super(null, StringDialog.class); + super(StringDialog.class); this.panel = panel; this.base = base; diff --git a/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java b/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java index d7b3ffe35bf..564b6c5cc2f 100644 --- a/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java +++ b/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java @@ -13,7 +13,7 @@ public DatabasePropertiesAction(JabRefFrame frame) { @Override public void execute() { - DatabasePropertiesDialog propertiesDialog = new DatabasePropertiesDialog(null, frame.getCurrentBasePanel()); + DatabasePropertiesDialog propertiesDialog = new DatabasePropertiesDialog(frame.getCurrentBasePanel()); propertiesDialog.updateEnableStatus(); propertiesDialog.setVisible(true); } diff --git a/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java b/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java index 9e3f32dc8f2..d1a193857eb 100644 --- a/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java +++ b/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java @@ -13,7 +13,7 @@ public FindUnlinkedFilesAction(JabRefFrame jabRefFrame) { @Override public void execute() { - FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(null, jabRefFrame); + FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(jabRefFrame); dlg.setVisible(true); } diff --git a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java index 74ebc86949c..e2d549e2c4e 100644 --- a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java +++ b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java @@ -17,7 +17,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; @@ -95,7 +94,7 @@ public void init() { errors = entriesChanged = skipped = 0; if (optionsDialog == null) { - optionsDialog = new OptionsDialog(null); + optionsDialog = new OptionsDialog(); } optionsDialog.open(); @@ -182,9 +181,8 @@ class OptionsDialog extends JabRefDialog { private final JTextArea progressArea; - - public OptionsDialog(JFrame parent) { - super(parent, Localization.lang("Writing XMP-metadata for selected entries..."), false, WriteXMPAction.OptionsDialog.class); + public OptionsDialog() { + super(Localization.lang("Writing XMP-metadata for selected entries..."), false, WriteXMPAction.OptionsDialog.class); okButton.setEnabled(false); okButton.addActionListener(e -> dispose()); diff --git a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java index 265ba9fc994..8cc7b0e144e 100644 --- a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java +++ b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java @@ -13,7 +13,6 @@ import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; @@ -69,7 +68,7 @@ public class FromAuxDialog extends JabRefDialog { private final JabRefFrame parentFrame; public FromAuxDialog(JabRefFrame frame, String title, boolean modal, TabPane viewedDBs) { - super((JFrame) null, title, modal, FromAuxDialog.class); + super(title, modal, FromAuxDialog.class); parentTabbedPane = viewedDBs; parentFrame = frame; diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java index 3897f74042b..9b04361a327 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java @@ -10,7 +10,6 @@ import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; @@ -31,7 +30,7 @@ public class BibtexKeyPatternDialog extends JabRefDialog { private final BibtexKeyPatternPanel bibtexKeyPatternPanel; public BibtexKeyPatternDialog(BasePanel panel) { - super((JFrame) null, Localization.lang("BibTeX key patterns"), true, BibtexKeyPatternDialog.class); + super(Localization.lang("BibTeX key patterns"), true, BibtexKeyPatternDialog.class); this.bibtexKeyPatternPanel = new BibtexKeyPatternPanel(panel); this.panel = panel; this.metaData = panel.getBibDatabaseContext().getMetaData(); diff --git a/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java b/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java index 1bf8978f1f0..ff67d3e19bb 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java +++ b/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java @@ -9,7 +9,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -35,10 +34,9 @@ class ChangeDisplayDialog extends JabRefDialog implements TreeSelectionListener private JComponent infoShown; private boolean okPressed; - - public ChangeDisplayDialog(JFrame owner, final BasePanel panel, - BibDatabase secondary, final DefaultMutableTreeNode root) { - super(owner, Localization.lang("External changes"), true, ChangeDisplayDialog.class); + public ChangeDisplayDialog(final BasePanel panel, + BibDatabase secondary, final DefaultMutableTreeNode root) { + super(Localization.lang("External changes"), true, ChangeDisplayDialog.class); BibDatabase localSecondary; // Just to be sure, put in an empty secondary base if none is given: diff --git a/src/main/java/org/jabref/gui/collab/ChangeScanner.java b/src/main/java/org/jabref/gui/collab/ChangeScanner.java index b7f6ab06d70..553d17cb3a2 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeScanner.java +++ b/src/main/java/org/jabref/gui/collab/ChangeScanner.java @@ -81,7 +81,7 @@ private static BibEntry bestFit(BibEntry targetEntry, List entries) { public void displayResult(final DisplayResultCallback fup) { if (changes.getChildCount() > 0) { SwingUtilities.invokeLater(() -> { - ChangeDisplayDialog changeDialog = new ChangeDisplayDialog(null, panel, databaseInTemp.getDatabase(), changes); + ChangeDisplayDialog changeDialog = new ChangeDisplayDialog(panel, databaseInTemp.getDatabase(), changes); changeDialog.setVisible(true); fup.scanResultsResolved(changeDialog.isOkPressed()); if (changeDialog.isOkPressed()) { diff --git a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java index 1a180891503..a188c1fca8a 100644 --- a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java +++ b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java @@ -3,7 +3,6 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; @@ -82,14 +81,13 @@ public class ContentSelectorDialog extends JabRefDialog { /** * - * @param owner the parent Window (Dialog or Frame) * @param frame the JabRef Frame * @param panel the currently selected BasePanel * @param modal should this dialog be modal? * @param fieldName the field this selector is initialized for. May be null. */ - public ContentSelectorDialog(Window owner, JabRefFrame frame, BasePanel panel, boolean modal, String fieldName) { - super(owner, Localization.lang("Manage content selectors"), ContentSelectorDialog.class); + public ContentSelectorDialog(JabRefFrame frame, BasePanel panel, boolean modal, String fieldName) { + super(Localization.lang("Manage content selectors"), ContentSelectorDialog.class); this.setModal(modal); this.metaData = panel.getBibDatabaseContext().getMetaData(); this.frame = frame; diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java index a9dc764366c..0361f3013a1 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java @@ -25,7 +25,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListSelectionModel; @@ -75,7 +74,7 @@ public class EntryTypeCustomizationDialog extends JabRefDialog implements ListSe * Creates a new instance of EntryTypeCustomizationDialog */ public EntryTypeCustomizationDialog(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Customize entry types"), false, EntryTypeCustomizationDialog.class); + super(Localization.lang("Customize entry types"), false, EntryTypeCustomizationDialog.class); this.frame = frame; initGui(); diff --git a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java index 8667f8cf49e..24cdaae3aee 100644 --- a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java +++ b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java @@ -16,7 +16,6 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JTextField; @@ -69,8 +68,8 @@ public class DatabasePropertiesDialog extends JabRefDialog { private FieldFormatterCleanupsPanel fieldFormatterCleanupsPanel; - public DatabasePropertiesDialog(JFrame parent, BasePanel panel) { - super(parent, Localization.lang("Library properties"), true, DatabasePropertiesDialog.class); + public DatabasePropertiesDialog(BasePanel panel) { + super(Localization.lang("Library properties"), true, DatabasePropertiesDialog.class); encoding = new JComboBox<>(); encoding.setModel(new DefaultComboBoxModel<>(Encodings.ENCODINGS)); ok = new JButton(Localization.lang("OK")); diff --git a/src/main/java/org/jabref/gui/exporter/CustomExportDialog.java b/src/main/java/org/jabref/gui/exporter/CustomExportDialog.java index 8667a3a1611..21552963b45 100644 --- a/src/main/java/org/jabref/gui/exporter/CustomExportDialog.java +++ b/src/main/java/org/jabref/gui/exporter/CustomExportDialog.java @@ -15,7 +15,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; @@ -57,7 +56,7 @@ public CustomExportDialog(final JabRefFrame parent, final String exporterName, f } public CustomExportDialog(final JabRefFrame parent) { - super((JFrame) null, Localization.lang("Edit custom export"), true, CustomExportDialog.class); + super(Localization.lang("Edit custom export"), true, CustomExportDialog.class); frame = parent; ActionListener okListener = e -> { Path layoutFileDir = Paths.get(layoutFile.getText()).getParent(); diff --git a/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java b/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java index a06b75d29f3..4348c4c1956 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java @@ -13,7 +13,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -44,7 +43,7 @@ public class ExportCustomizationDialog extends JabRefDialog { public ExportCustomizationDialog(final JabRefFrame frame) { - super((JFrame) null, Localization.lang("Manage custom exports"), false, ExportCustomizationDialog.class); + super(Localization.lang("Manage custom exports"), false, ExportCustomizationDialog.class); DefaultEventTableModel> tableModel = new DefaultEventTableModel<>( Globals.prefs.customExports.getSortedList(), new ExportTableFormat()); JTable table = new JTable(tableModel); diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index 4abd8d6ac83..043ee954af1 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -20,7 +20,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -149,7 +148,7 @@ public Dimension getPreferredSize() { * created. */ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) { - super((JFrame) null, Localization.lang("Edit group"), true, GroupDialog.class); + super(Localization.lang("Edit group"), true, GroupDialog.class); // set default values (overwritten if editedGroup != null) keywordGroupSearchField.setText(jabrefFrame.prefs().get(JabRefPreferences.GROUPS_DEFAULT_FIELD)); diff --git a/src/main/java/org/jabref/gui/help/NewVersionDialog.java b/src/main/java/org/jabref/gui/help/NewVersionDialog.java index 9c64e2a64a7..51bff518ca6 100644 --- a/src/main/java/org/jabref/gui/help/NewVersionDialog.java +++ b/src/main/java/org/jabref/gui/help/NewVersionDialog.java @@ -7,7 +7,6 @@ import java.awt.event.MouseEvent; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.event.MouseInputAdapter; @@ -21,8 +20,8 @@ public class NewVersionDialog extends JabRefDialog { - public NewVersionDialog(JFrame frame, Version currentVersion, Version latestVersion) { - super(frame, NewVersionDialog.class); + public NewVersionDialog(Version currentVersion, Version latestVersion) { + super(NewVersionDialog.class); setTitle(Localization.lang("New version available")); JLabel lblTitle = new JLabel(Localization.lang("A new version of JabRef has been released.")); @@ -87,8 +86,6 @@ public void mouseClicked(MouseEvent e) { add(panel); pack(); - setLocationRelativeTo(frame); - setModalityType(ModalityType.APPLICATION_MODAL); setVisible(true); } diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java b/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java index 80031214d9a..3cbfa285a47 100644 --- a/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java @@ -16,7 +16,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -60,7 +59,7 @@ public class ImportCustomizationDialog extends JabRefDialog { private final JTable customImporterTable; public ImportCustomizationDialog(final JabRefFrame frame) { - super((JFrame) null, Localization.lang("Manage custom imports"), false, ImportCustomizationDialog.class); + super(Localization.lang("Manage custom imports"), false, ImportCustomizationDialog.class); DialogService dialogService = frame.getDialogService(); diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 3366019169c..8b53cfd793b 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -193,7 +193,7 @@ public class ImportInspectionDialog extends JabRefDialog implements ImportInspec * @param panel */ public ImportInspectionDialog(JabRefFrame frame, BasePanel panel, String undoName, boolean newDatabase) { - super(null, ImportInspectionDialog.class); + super(ImportInspectionDialog.class); this.frame = frame; this.panel = panel; this.bibDatabaseContext = (panel == null) ? null : panel.getBibDatabaseContext(); diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java index e88a3c139b7..39a9e6f789b 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java @@ -3,7 +3,6 @@ import java.util.List; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JSeparator; import org.jabref.gui.BasePanel; @@ -33,7 +32,7 @@ public class MergeEntriesDialog extends JabRefDialog { private final DialogService dialogService; public MergeEntriesDialog(BasePanel panel, DialogService dialogService) { - super((JFrame) null, MERGE_ENTRIES, true, MergeEntriesDialog.class); + super(MERGE_ENTRIES, true, MergeEntriesDialog.class); this.dialogService = dialogService; this.panel = panel; diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java index 1b54098bec5..516f59f98b9 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java @@ -8,7 +8,6 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JSeparator; import org.jabref.gui.BasePanel; @@ -44,7 +43,7 @@ public class MergeFetchedEntryDialog extends JabRefDialog { public MergeFetchedEntryDialog(BasePanel panel, BibEntry originalEntry, BibEntry fetchedEntry, String type) { - super((JFrame) null, Localization.lang("Merge entry with %0 information", type), true, MergeFetchedEntryDialog.class); + super(Localization.lang("Merge entry with %0 information", type), true, MergeFetchedEntryDialog.class); this.panel = panel; this.originalEntry = originalEntry; diff --git a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java index c5b9468ff0a..f2aee0e94fa 100644 --- a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java @@ -134,7 +134,7 @@ public class TextInputDialog extends JabRefDialog { public TextInputDialog(JabRefFrame frame, BibEntry bibEntry) { - super(null, true, TextInputDialog.class); + super(true, TextInputDialog.class); this.frame = Objects.requireNonNull(frame); diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java index 44ee6297960..61b497f8c8d 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java @@ -188,7 +188,7 @@ private JComponent constructSwingContent() { }); showPreferences.addActionListener( - e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs), null).setVisible(true)); + e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).setVisible(true)); resetPreferences.addActionListener(e -> { boolean resetPreferencesClicked = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogAndWait(Localization.lang("Reset preferences"), diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java index 050a2cb619f..fb3bbdc6b86 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java @@ -7,7 +7,6 @@ import java.util.Objects; import javax.swing.JCheckBox; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -27,8 +26,8 @@ class PreferencesFilterDialog extends JabRefDialog { private final JCheckBox showOnlyDeviatingPreferenceOptions; private final JLabel count; - public PreferencesFilterDialog(JabRefPreferencesFilter preferencesFilter, JFrame frame) { - super(frame, true, PreferencesFilterDialog.class); // is modal + public PreferencesFilterDialog(JabRefPreferencesFilter preferencesFilter) { + super(true, PreferencesFilterDialog.class); this.preferencesFilter = Objects.requireNonNull(preferencesFilter); diff --git a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java index d2a286f7071..b0bd76d7276 100644 --- a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java +++ b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java @@ -12,7 +12,6 @@ import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JTextField; import org.jabref.Globals; @@ -49,7 +48,7 @@ public NewProtectedTermsFileDialog(JDialog parent, ProtectedTermsLoader loader, } public NewProtectedTermsFileDialog(DialogService dialogService, ProtectedTermsLoader loader) { - super((JFrame) null, Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); + super(Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); this.loader = loader; this.dialogService = dialogService; setupDialog(); diff --git a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java index 86d7a6429b4..9dd594d2418 100644 --- a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java +++ b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java @@ -24,7 +24,6 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; @@ -102,7 +101,7 @@ public class ConnectToSharedDatabaseDialog extends JabRefDialog { * @param frame the JabRef Frame */ public ConnectToSharedDatabaseDialog(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Connect to shared database"), ConnectToSharedDatabaseDialog.class); + super(Localization.lang("Connect to shared database"), ConnectToSharedDatabaseDialog.class); this.frame = frame; initLayout(); updateEnableState(); diff --git a/src/main/java/org/jabref/gui/worker/VersionWorker.java b/src/main/java/org/jabref/gui/worker/VersionWorker.java index 21d47599359..a761066d18c 100644 --- a/src/main/java/org/jabref/gui/worker/VersionWorker.java +++ b/src/main/java/org/jabref/gui/worker/VersionWorker.java @@ -112,7 +112,7 @@ private void showUpdateInfo(List availableVersions) { } else { // notify the user about a newer version - new NewVersionDialog(null, installedVersion, newerVersion.get()); + new NewVersionDialog(installedVersion, newerVersion.get()); } } From 9ae2b404efeb09c83ac31050f9b084bc7177f2f1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 19 Jul 2018 18:14:07 +0200 Subject: [PATCH 3/7] Make it easier to rename and move files (#4200) * Make it easier to rename and move files Removes confirmation dialogs when renaming or moving files. It is hard to accidentally invoke this action (you have to right click on the file > move/rename) and it is not irreversible. Thus, in my opinion, no confirmation dialog is needed. * Fix checkstyle --- CHANGELOG.md | 2 +- .../gui/fieldeditors/LinkedFileViewModel.java | 32 ++++--------------- .../jabref/logic/util/io/FileBasedLock.java | 2 +- src/main/resources/l10n/JabRef_en.properties | 1 - 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1cfb3cef5d..1a8805404d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. - +- We streamlined the process to rename and move files by removing the confirmation dialogs. diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index f0639545af8..ee0a04e5b4f 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -201,34 +201,19 @@ public void rename() { // Cannot rename remote links return; } - Optional fileDir = databaseContext.getFirstExistingFileDir(fileDirectoryPreferences); - if (!fileDir.isPresent()) { - dialogService.showErrorDialogAndWait(Localization.lang("Rename file"), Localization.lang("File directory is not set or does not exist!")); - return; - } Optional file = linkedFile.findIn(databaseContext, fileDirectoryPreferences); if ((file.isPresent()) && Files.exists(file.get())) { RenamePdfCleanup pdfCleanup = new RenamePdfCleanup(false, databaseContext, fileDirPattern, fileDirectoryPreferences, linkedFile); - - String targetFileName = pdfCleanup.getTargetFileName(linkedFile, entry); - - boolean confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("Rename file"), - Localization.lang("Rename file to") + " " + targetFileName, - Localization.lang("Rename file"), - Localization.lang("Cancel")); - - if (confirm) { - Optional fileConflictCheck = pdfCleanup.findExistingFile(linkedFile, entry); - performRenameWithConflictCheck(file, pdfCleanup, targetFileName, fileConflictCheck); - } + performRenameWithConflictCheck(file.get(), pdfCleanup); } else { dialogService.showErrorDialogAndWait(Localization.lang("File not found"), Localization.lang("Could not find file '%0'.", linkedFile.getLink())); } } - private void performRenameWithConflictCheck(Optional file, RenamePdfCleanup pdfCleanup, String targetFileName, Optional fileConflictCheck) { + private void performRenameWithConflictCheck(Path file, RenamePdfCleanup pdfCleanup) { boolean confirm; + Optional fileConflictCheck = pdfCleanup.findExistingFile(linkedFile, entry); if (!fileConflictCheck.isPresent()) { try { pdfCleanup.cleanupWithException(entry); @@ -236,6 +221,7 @@ private void performRenameWithConflictCheck(Optional file, RenamePdfCleanu dialogService.showErrorDialogAndWait(Localization.lang("Rename failed"), Localization.lang("JabRef cannot access the file because it is being used by another process.")); } } else { + String targetFileName = pdfCleanup.getTargetFileName(linkedFile, entry); confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("File exists"), Localization.lang("'%0' exists. Overwrite file?", targetFileName), Localization.lang("Overwrite"), @@ -243,7 +229,7 @@ private void performRenameWithConflictCheck(Optional file, RenamePdfCleanu if (confirm) { try { - FileUtil.renameFileWithException(fileConflictCheck.get(), file.get(), true); + FileUtil.renameFileWithException(fileConflictCheck.get(), file, true); pdfCleanup.cleanupWithException(entry); } catch (IOException e) { dialogService.showErrorDialogAndWait(Localization.lang("Rename failed"), @@ -268,13 +254,9 @@ public void moveToDefaultDirectory() { Optional file = linkedFile.findIn(databaseContext, fileDirectoryPreferences); if ((file.isPresent()) && Files.exists(file.get())) { - // Linked file exists, so move it + // Found the linked file, so move it MoveFilesCleanup moveFiles = new MoveFilesCleanup(databaseContext, fileDirPattern, fileDirectoryPreferences, linkedFile); - - boolean confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("Move file"), Localization.lang("Move file to file directory?") + " " + fileDir.get(), Localization.lang("Move file"), Localization.lang("Cancel")); - if (confirm) { - moveFiles.cleanup(entry); - } + moveFiles.cleanup(entry); } else { // File doesn't exist, so we can't move it. dialogService.showErrorDialogAndWait(Localization.lang("File not found"), Localization.lang("Could not find file '%0'.", linkedFile.getLink())); diff --git a/src/main/java/org/jabref/logic/util/io/FileBasedLock.java b/src/main/java/org/jabref/logic/util/io/FileBasedLock.java index 7de6acb8642..a271879d184 100644 --- a/src/main/java/org/jabref/logic/util/io/FileBasedLock.java +++ b/src/main/java/org/jabref/logic/util/io/FileBasedLock.java @@ -12,7 +12,7 @@ public class FileBasedLock { /** - * The age in ms of a lockfile before JabRef will offer to "steal" the locked file. + * The age in ms of a lock file before JabRef will offer to "steal" the locked file. */ public static final long LOCKFILE_CRITICAL_AGE = 60000; private static final Logger LOGGER = LoggerFactory.getLogger(FileBasedLock.class); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 10a193f6020..55b6f2209de 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -1198,7 +1198,6 @@ Error\ while\ fetching\ from\ %0=Error while fetching from %0 Show\ search\ results\ in\ a\ window=Show search results in a window Show\ global\ search\ results\ in\ a\ window=Show global search results in a window Search\ in\ all\ open\ libraries=Search in all open libraries -Move\ file\ to\ file\ directory?=Move file to file directory? Library\ is\ protected.\ Cannot\ save\ until\ external\ changes\ have\ been\ reviewed.=Library is protected. Cannot save until external changes have been reviewed. Protected\ library=Protected library From f9799d44dbec3aae6acee8b929ed7d69edbccba9 Mon Sep 17 00:00:00 2001 From: Dominik Traczyk Date: Sun, 22 Jul 2018 21:25:16 +0200 Subject: [PATCH 4/7] single line text fields (#4138) * force author, title and year text areas to be single line text field using text formatter * consider 'institution' as a field, that should contain only one line * create EditorTextField and use that control for author, institution, year and title * pass JournalAbbrevRepo instead of Loader and Prefs * code review fixes - move SINGLE_LINE_FIELDS list to InternalBibtexFields class - rename hasSingleLine var to isSingleLine --- .../gui/entryeditor/FieldsEditorTab.java | 5 +- .../gui/fieldeditors/ContextMenuAddable.java | 15 +++++ .../gui/fieldeditors/EditorTextArea.java | 12 ++-- .../gui/fieldeditors/EditorTextField.java | 65 +++++++++++++++++++ .../gui/fieldeditors/EditorValidator.java | 6 +- .../jabref/gui/fieldeditors/FieldEditors.java | 29 ++++++--- .../gui/fieldeditors/JournalEditor.java | 6 +- .../fieldeditors/JournalEditorViewModel.java | 15 ++--- .../gui/fieldeditors/PersonsEditor.java | 27 +++++--- .../jabref/gui/fieldeditors/SimpleEditor.java | 31 ++++++--- .../fieldeditors/contextmenu/ClearField.java | 4 +- .../fieldeditors/contextmenu/EditorMenus.java | 21 +++--- .../contextmenu/ProtectedTermsMenu.java | 6 +- .../model/entry/InternalBibtexFields.java | 8 +++ 14 files changed, 183 insertions(+), 67 deletions(-) create mode 100644 src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java create mode 100644 src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java index a757a7ee4c7..c653ed1b23f 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java @@ -85,9 +85,8 @@ private Region setupPanel(BibEntry entry, boolean compressed, SuggestionProvider boolean isFirstField = true; for (String fieldName : fields) { FieldEditorFX fieldEditor = FieldEditors.getForField(fieldName, Globals.TASK_EXECUTOR, dialogService, - Globals.journalAbbreviationLoader, Globals.prefs.getJournalAbbreviationPreferences(), Globals.prefs, - databaseContext, entry.getType(), - suggestionProviders, undoManager); + Globals.journalAbbreviationLoader.getRepository(Globals.prefs.getJournalAbbreviationPreferences()), + Globals.prefs, databaseContext, entry.getType(), suggestionProviders, undoManager); fieldEditor.bindToEntry(entry); editors.put(fieldName, fieldEditor); diff --git a/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java b/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java new file mode 100644 index 00000000000..9f9bff69e41 --- /dev/null +++ b/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java @@ -0,0 +1,15 @@ +package org.jabref.gui.fieldeditors; + +import java.util.List; +import java.util.function.Supplier; + +import javafx.scene.control.MenuItem; + +public interface ContextMenuAddable { + /** + * Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need + * to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary + * allocations when the main table is just scrolled with the entry editor open. + */ + void addToContextMenu(final Supplier> items); +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java index 6f783e05d06..1783e9f1396 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java @@ -13,13 +13,13 @@ import com.sun.javafx.scene.control.skin.TextAreaSkin; -public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable { +public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable, ContextMenuAddable { public EditorTextArea() { this(""); } - public EditorTextArea(String text) { + public EditorTextArea(final String text) { super(text); setMinHeight(1); @@ -49,12 +49,8 @@ public EditorTextArea(String text) { }); } - /** - * Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need - * to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary - * allocations when the main table is just scrolled with the entry editor open. - */ - public void addToContextMenu(Supplier> items) { + @Override + public void addToContextMenu(final Supplier> items) { TextAreaSkin customContextSkin = new TextAreaSkin(this) { @Override public void populateContextMenu(ContextMenu contextMenu) { diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java new file mode 100644 index 00000000000..26c23006a88 --- /dev/null +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java @@ -0,0 +1,65 @@ +package org.jabref.gui.fieldeditors; + +import java.net.URL; +import java.util.List; +import java.util.ResourceBundle; +import java.util.function.Supplier; + +import javafx.fxml.Initializable; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +import com.sun.javafx.scene.control.skin.TextFieldSkin; + +public class EditorTextField extends javafx.scene.control.TextField implements Initializable, ContextMenuAddable { + + public EditorTextField() { + this(""); + } + + public EditorTextField(final String text) { + super(text); + + setMinHeight(1); + setMinWidth(200); + + // Should behave as a normal text field with respect to TAB behaviour + addEventFilter(KeyEvent.KEY_PRESSED, event -> { + if (event.getCode() == KeyCode.TAB) { + TextFieldSkin skin = (TextFieldSkin) getSkin(); + if (event.isShiftDown()) { + // Shift + Tab > previous text area + skin.getBehavior().traversePrevious(); + } else { + if (event.isControlDown()) { + // Ctrl + Tab > insert tab + skin.getBehavior().callAction("InsertTab"); + } else { + // Tab > next text area + skin.getBehavior().traverseNext(); + } + } + event.consume(); + } + }); + } + + @Override + public void addToContextMenu(final Supplier> items) { + TextFieldSkin customContextSkin = new TextFieldSkin(this) { + @Override + public void populateContextMenu(ContextMenu contextMenu) { + super.populateContextMenu(contextMenu); + contextMenu.getItems().addAll(0, items.get()); + } + }; + setSkin(customContextSkin); + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + // not needed + } +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java b/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java index af3c8791a0d..626626ad468 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java @@ -1,5 +1,7 @@ package org.jabref.gui.fieldeditors; +import javafx.scene.control.TextInputControl; + import org.jabref.gui.util.IconValidationDecorator; import org.jabref.preferences.JabRefPreferences; @@ -14,11 +16,11 @@ public EditorValidator(JabRefPreferences preferences) { this.preferences = preferences; } - public void configureValidation(ValidationStatus status, EditorTextArea area) { + public void configureValidation(final ValidationStatus status, final TextInputControl textInput) { if (preferences.getBoolean(JabRefPreferences.VALIDATE_IN_ENTRY_EDITOR)) { ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer(); validationVisualizer.setDecoration(new IconValidationDecorator()); - validationVisualizer.initVisualization(status, area); + validationVisualizer.initVisualization(status, textInput); } } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index ef0db377b85..cff53232371 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -13,8 +13,7 @@ import org.jabref.gui.autocompleter.SuggestionProviders; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.JournalAbbreviationPreferences; +import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.FieldName; import org.jabref.model.entry.FieldProperty; @@ -29,12 +28,26 @@ public class FieldEditors { private static final Logger LOGGER = LoggerFactory.getLogger(FieldEditors.class); - public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecutor, DialogService dialogService, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, JabRefPreferences preferences, BibDatabaseContext databaseContext, String entryType, SuggestionProviders suggestionProviders, UndoManager undoManager) { + public static FieldEditorFX getForField(final String fieldName, + final TaskExecutor taskExecutor, + final DialogService dialogService, + final JournalAbbreviationRepository journalAbbreviationRepository, + final JabRefPreferences preferences, + final BibDatabaseContext databaseContext, + final String entryType, + final SuggestionProviders suggestionProviders, + final UndoManager undoManager) { final Set fieldExtras = InternalBibtexFields.getFieldProperties(fieldName); - AutoCompleteSuggestionProvider suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData()); + final AutoCompleteSuggestionProvider suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData()); - FieldCheckers fieldCheckers = new FieldCheckers(databaseContext, preferences.getFileDirectoryPreferences(), journalAbbreviationLoader.getRepository(journalAbbreviationPreferences), preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); + final FieldCheckers fieldCheckers = new FieldCheckers( + databaseContext, + preferences.getFileDirectoryPreferences(), + journalAbbreviationRepository, + preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); + + final boolean isSingleLine = InternalBibtexFields.isSingleLineField(fieldName); if (preferences.getTimestampPreferences().getTimestampField().equals(fieldName) || fieldExtras.contains(FieldProperty.DATE)) { if (fieldExtras.contains(FieldProperty.ISO_DATE)) { @@ -45,7 +58,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } else if (fieldExtras.contains(FieldProperty.EXTERNAL)) { return new UrlEditor(fieldName, dialogService, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.JOURNAL_NAME)) { - return new JournalEditor(fieldName, journalAbbreviationLoader, preferences, suggestionProvider, fieldCheckers); + return new JournalEditor(fieldName, journalAbbreviationRepository, preferences, suggestionProvider, fieldCheckers); } else if (fieldExtras.contains(FieldProperty.DOI) || fieldExtras.contains(FieldProperty.EPRINT) || fieldExtras.contains(FieldProperty.ISBN)) { return new IdentifierEditor(fieldName, taskExecutor, dialogService, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.OWNER)) { @@ -71,7 +84,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } else if (fieldExtras.contains(FieldProperty.SINGLE_ENTRY_LINK) || fieldExtras.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) { return new LinkedEntriesEditor(fieldName, databaseContext, suggestionProvider, fieldCheckers); } else if (fieldExtras.contains(FieldProperty.PERSON_NAMES)) { - return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers); + return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers, isSingleLine); } else if (FieldName.KEYWORDS.equals(fieldName)) { return new KeywordsEditor(fieldName, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.MULTILINE_TEXT)) { @@ -81,7 +94,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } // default - return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences); + return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences, isSingleLine); } @SuppressWarnings("unchecked") diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java index af338ef26fa..ad00729bab3 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java @@ -8,7 +8,7 @@ import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding; import org.jabref.gui.fieldeditors.contextmenu.EditorMenus; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; +import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; @@ -19,8 +19,8 @@ public class JournalEditor extends HBox implements FieldEditorFX { @FXML private JournalEditorViewModel viewModel; @FXML private EditorTextArea textArea; - public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JabRefPreferences preferences, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { - this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, preferences.getJournalAbbreviationPreferences(), fieldCheckers); + public JournalEditor(String fieldName, JournalAbbreviationRepository journalAbbreviationRepository, JabRefPreferences preferences, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { + this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationRepository, fieldCheckers); ViewLoader.view(this) .root(this) diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java index e59d1305efc..2cf93f8bbec 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java @@ -4,20 +4,16 @@ import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.JournalAbbreviationPreferences; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.strings.StringUtil; public class JournalEditorViewModel extends AbstractEditorViewModel { - private final JournalAbbreviationLoader journalAbbreviationLoader; - private final JournalAbbreviationPreferences journalAbbreviationPreferences; + private final JournalAbbreviationRepository journalAbbreviationRepository; - public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, FieldCheckers fieldCheckers) { + public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JournalAbbreviationRepository journalAbbreviationRepository, FieldCheckers fieldCheckers) { super(fieldName, suggestionProvider, fieldCheckers); - this.journalAbbreviationLoader = journalAbbreviationLoader; - this.journalAbbreviationPreferences = journalAbbreviationPreferences; + this.journalAbbreviationRepository = journalAbbreviationRepository; } public void toggleAbbreviation() { @@ -25,9 +21,8 @@ public void toggleAbbreviation() { return; } - JournalAbbreviationRepository abbreviationRepository = journalAbbreviationLoader.getRepository(journalAbbreviationPreferences); - if (abbreviationRepository.isKnownName(text.get())) { - Optional nextAbbreviation = abbreviationRepository.getNextAbbreviation(text.get()); + if (journalAbbreviationRepository.isKnownName(text.get())) { + Optional nextAbbreviation = journalAbbreviationRepository.getNextAbbreviation(text.get()); if (nextAbbreviation.isPresent()) { text.set(nextAbbreviation.get()); diff --git a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java index 01f5dccc8b9..f72a5cf23fe 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java @@ -2,6 +2,7 @@ import javafx.fxml.FXML; import javafx.scene.Parent; +import javafx.scene.control.TextInputControl; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -16,20 +17,26 @@ public class PersonsEditor extends HBox implements FieldEditorFX { @FXML private final PersonsEditorViewModel viewModel; - private EditorTextArea textArea; + private TextInputControl textInput; - public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JabRefPreferences preferences, FieldCheckers fieldCheckers) { + public PersonsEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final JabRefPreferences preferences, + final FieldCheckers fieldCheckers, + final boolean isSingleLine) { this.viewModel = new PersonsEditorViewModel(fieldName, suggestionProvider, preferences.getAutoCompletePreferences(), fieldCheckers); - textArea = new EditorTextArea(); - HBox.setHgrow(textArea, Priority.ALWAYS); - textArea.textProperty().bindBidirectional(viewModel.textProperty()); - textArea.addToContextMenu(EditorMenus.getNameMenu(textArea)); - this.getChildren().add(textArea); + textInput = isSingleLine + ? new EditorTextField() + : new EditorTextArea(); + HBox.setHgrow(textInput, Priority.ALWAYS); + textInput.textProperty().bindBidirectional(viewModel.textProperty()); + ((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getNameMenu(textInput)); + this.getChildren().add(textInput); - AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy()); + AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy()); - new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput); } @Override @@ -44,7 +51,7 @@ public Parent getNode() { @Override public void requestFocus() { - textArea.requestFocus(); + textInput.requestFocus(); } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java index 00e0e991183..de42b9e0d73 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java @@ -2,6 +2,7 @@ import javafx.fxml.FXML; import javafx.scene.Parent; +import javafx.scene.control.TextInputControl; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -17,22 +18,36 @@ public class SimpleEditor extends HBox implements FieldEditorFX { @FXML private final SimpleEditorViewModel viewModel; - public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers, JabRefPreferences preferences) { + public SimpleEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final FieldCheckers fieldCheckers, + final JabRefPreferences preferences, + final boolean isSingleLine) { this.viewModel = new SimpleEditorViewModel(fieldName, suggestionProvider, fieldCheckers); - EditorTextArea textArea = new EditorTextArea(); - HBox.setHgrow(textArea, Priority.ALWAYS); - textArea.textProperty().bindBidirectional(viewModel.textProperty()); - textArea.addToContextMenu(EditorMenus.getDefaultMenu(textArea)); - this.getChildren().add(textArea); + TextInputControl textInput = isSingleLine + ? new EditorTextField() + : new EditorTextArea(); + HBox.setHgrow(textInput, Priority.ALWAYS); + textInput.textProperty().bindBidirectional(viewModel.textProperty()); + ((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getDefaultMenu(textInput)); + this.getChildren().add(textInput); - AutoCompletionTextInputBinding autoCompleter = AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionStrategy()); + AutoCompletionTextInputBinding autoCompleter = AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionStrategy()); if (suggestionProvider instanceof ContentSelectorSuggestionProvider) { // If content selector values are present, then we want to show the auto complete suggestions immediately on focus autoCompleter.setShowOnFocus(true); } - new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput); + } + + + public SimpleEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final FieldCheckers fieldCheckers, + final JabRefPreferences preferences) { + this(fieldName, suggestionProvider, fieldCheckers, preferences, false); } @Override diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java index 52ef77f1a8c..22b846f44e2 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java @@ -1,13 +1,13 @@ package org.jabref.gui.fieldeditors.contextmenu; import javafx.scene.control.MenuItem; -import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import org.jabref.logic.l10n.Localization; class ClearField extends MenuItem { - public ClearField(TextArea opener) { + public ClearField(TextInputControl opener) { super(Localization.lang("Clear")); setOnAction(event -> opener.setText("")); } diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java index 12e6382a3b1..179a1cfb9b7 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java @@ -12,6 +12,7 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import javafx.scene.control.Tooltip; import org.jabref.gui.actions.CopyDoiUrlAction; @@ -29,18 +30,18 @@ public class EditorMenus { /** * The default menu that contains functions for changing the case of text and doing several conversions. * - * @param textArea text-area that this menu will be connected to + * @param textInput text-input-control that this menu will be connected to * @return default context menu available for most text fields */ - public static Supplier> getDefaultMenu(TextArea textArea) { + public static Supplier> getDefaultMenu(final TextInputControl textInput) { return () -> { List menuItems = new ArrayList<>(6); - menuItems.add(new CaseChangeMenu(textArea.textProperty())); - menuItems.add(new ConversionMenu(textArea.textProperty())); + menuItems.add(new CaseChangeMenu(textInput.textProperty())); + menuItems.add(new ConversionMenu(textInput.textProperty())); menuItems.add(new SeparatorMenuItem()); - menuItems.add(new ProtectedTermsMenu(textArea)); + menuItems.add(new ProtectedTermsMenu(textInput)); menuItems.add(new SeparatorMenuItem()); - menuItems.add(new ClearField(textArea)); + menuItems.add(new ClearField(textInput)); return menuItems; }; } @@ -48,18 +49,18 @@ public static Supplier> getDefaultMenu(TextArea textArea) { /** * The default context menu with a specific menu for normalizing person names regarding to BibTex rules. * - * @param textArea text-area that this menu will be connected to + * @param textInput text-input-control that this menu will be connected to * @return menu containing items of the default menu and an item for normalizing person names */ - public static Supplier> getNameMenu(TextArea textArea) { + public static Supplier> getNameMenu(final TextInputControl textInput) { return () -> { CustomMenuItem normalizeNames = new CustomMenuItem(new Label(Localization.lang("Normalize to BibTeX name format"))); - normalizeNames.setOnAction(event -> textArea.setText(new NormalizeNamesFormatter().format(textArea.getText()))); + normalizeNames.setOnAction(event -> textInput.setText(new NormalizeNamesFormatter().format(textInput.getText()))); Tooltip toolTip = new Tooltip(Localization.lang("If possible, normalize this list of names to conform to standard BibTeX name formatting")); Tooltip.install(normalizeNames.getContent(), toolTip); List menuItems = new ArrayList<>(6); menuItems.add(normalizeNames); - menuItems.addAll(getDefaultMenu(textArea).get()); + menuItems.addAll(getDefaultMenu(textInput).get()); return menuItems; }; } diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java index 3ede64f1fea..4af7fec8023 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java @@ -8,7 +8,7 @@ import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; -import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import org.jabref.Globals; import org.jabref.JabRefGUI; @@ -23,9 +23,9 @@ class ProtectedTermsMenu extends Menu { private static final Formatter FORMATTER = new ProtectTermsFormatter(Globals.protectedTermsLoader); private final Menu externalFiles; - private final TextArea opener; + private final TextInputControl opener; - public ProtectedTermsMenu(TextArea opener) { + public ProtectedTermsMenu(final TextInputControl opener) { super(Localization.lang("Protect terms")); this.opener = opener; MenuItem protectItem = new MenuItem(Localization.lang("Add {} around selected text")); diff --git a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java index dfc7e097dd7..d33e73abdf8 100644 --- a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java +++ b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java @@ -93,6 +93,10 @@ public class InternalBibtexFields { SpecialField.RELEVANCE.getFieldName() ); + private static final Set SINGLE_LINE_FIELDS = Collections.unmodifiableSet(new HashSet<>( + Arrays.asList(FieldName.TITLE, FieldName.AUTHOR, FieldName.YEAR, FieldName.INSTITUTION) + )); + // singleton instance private static InternalBibtexFields RUNTIME = new InternalBibtexFields(); @@ -475,4 +479,8 @@ public static List getIEEETranBSTctlYesNoFields() { private void add(BibtexSingleField field) { fieldSet.put(field.getName(), field); } + + public static boolean isSingleLineField(final String fieldName) { + return SINGLE_LINE_FIELDS.contains(fieldName.toLowerCase()); + } } From d5d67d70247b95af937c3e818dc7f1ae6dd484ee Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 23 Jul 2018 15:09:55 +0200 Subject: [PATCH 5/7] Fix fetcher tests (#4216) * Fix fetcher tests remove uncessary logging in l10n which makes fetcher test fail ISBN tests still fail both Fix arxiv tests, eprint now has url in front * rework fetcher tests Fix logging configuration Fix eprint field of arxiv Return empty results when 404 or 400 encountered Add logging in that case * fix checkstyle * match both https and http prefixes in arxiv * inline prefs in setup method * fix ebook.de test record, as there is a new version of that book entry * move comment --- .../jabref/logic/importer/fetcher/ArXiv.java | 44 +++++++++++-------- .../importer/fileformat/ModsImporter.java | 2 +- .../jabref/logic/net/ProgressInputStream.java | 6 ++- .../org/jabref/logic/net/URLDownload.java | 16 +++++-- .../entry/identifier/ArXivIdentifier.java | 13 +++++- .../logic/importer/fetcher/ACSTest.java | 2 +- .../logic/importer/fetcher/ArXivTest.java | 5 ++- .../fetcher/AstrophysicsDataSystemTest.java | 3 +- .../logic/importer/fetcher/CrossRefTest.java | 14 +++++- .../importer/fetcher/DBLPFetcherTest.java | 11 +++-- .../importer/fetcher/DOAJFetcherTest.java | 12 ++--- .../logic/importer/fetcher/DiVATest.java | 7 ++- .../fetcher/IsbnViaEbookDeFetcherTest.java | 14 +++--- .../fetcher/LibraryOfCongressTest.java | 24 ++++++++-- .../importer/fetcher/MathSciNetTest.java | 2 +- .../importer/fetcher/OpenAccessDoiTest.java | 5 +-- .../importer/fetcher/RfcFetcherTest.java | 7 +-- .../importer/fetcher/SpringerFetcherTest.java | 7 ++- .../resources/{log4j2.xml => log4j2-test.xml} | 2 +- 19 files changed, 133 insertions(+), 63 deletions(-) rename src/test/resources/{log4j2.xml => log4j2-test.xml} (95%) diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java index 7f7edf703ca..108820515c8 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.xml.parsers.DocumentBuilder; @@ -53,9 +55,12 @@ * dspace-portalmec */ public class ArXiv implements FulltextFetcher, SearchBasedFetcher, IdBasedFetcher, IdFetcher { + private static final Logger LOGGER = LoggerFactory.getLogger(ArXiv.class); private static final String API_URL = "https://export.arxiv.org/api/query"; + private static final String ARXIV_URL_PREFIX_FOR_ID = "(https?://arxiv.org/abs/)"; + private static final Pattern URL_PATTERN = Pattern.compile(ARXIV_URL_PREFIX_FOR_ID); private final ImportFormatPreferences importFormatPreferences; @@ -69,10 +74,10 @@ public Optional findFullText(BibEntry entry) throws IOException { try { Optional pdfUrl = searchForEntries(entry).stream() - .map(ArXivEntry::getPdfUrl) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); + .map(ArXivEntry::getPdfUrl) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); if (pdfUrl.isPresent()) { LOGGER.info("Fulltext PDF found @ arXiv."); @@ -159,7 +164,7 @@ private List searchForEntries(String searchQuery) throws FetcherExce } private List queryApi(String searchQuery, List ids, int start, int maxResults) - throws FetcherException { + throws FetcherException { Document result = callApi(searchQuery, ids, start, maxResults); List entries = XMLUtil.asList(result.getElementsByTagName("entry")); @@ -195,7 +200,7 @@ private Document callApi(String searchQuery, List ids, int star } if (!ids.isEmpty()) { uriBuilder.addParameter("id_list", - ids.stream().map(ArXivIdentifier::getNormalized).collect(Collectors.joining(","))); + ids.stream().map(ArXivIdentifier::getNormalized).collect(Collectors.joining(","))); } uriBuilder.addParameter("start", String.valueOf(start)); uriBuilder.addParameter("max_results", String.valueOf(maxResults)); @@ -252,7 +257,8 @@ public HelpFile getHelpPage() { @Override public List performSearch(String query) throws FetcherException { return searchForEntries(query).stream().map( - (arXivEntry) -> arXivEntry.toBibEntry(importFormatPreferences.getKeywordSeparator())).collect(Collectors.toList()); + (arXivEntry) -> arXivEntry.toBibEntry(importFormatPreferences.getKeywordSeparator())) + .collect(Collectors.toList()); } @Override @@ -266,10 +272,10 @@ public Optional performSearchById(String identifier) throws FetcherExc @Override public Optional findIdentifier(BibEntry entry) throws FetcherException { return searchForEntries(entry).stream() - .map(ArXivEntry::getId) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); + .map(ArXivEntry::getId) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); } @Override @@ -290,7 +296,6 @@ private static class ArXivEntry { private final Optional journalReferenceText; private final Optional primaryCategory; - public ArXivEntry(Node item) { // see https://arxiv.org/help/api/user-manual#_details_of_atom_results_returned @@ -347,7 +352,7 @@ public ArXivEntry(Node item) { // Primary category // Ex: primaryCategory = XMLUtil.getNode(item, "arxiv:primary_category") - .flatMap(node -> XMLUtil.getAttributeContent(node, "term")); + .flatMap(node -> XMLUtil.getAttributeContent(node, "term")); } public static String correctLineBreaks(String s) { @@ -367,14 +372,16 @@ public Optional getPdfUrl() { * Returns the arXiv identifier */ public Optional getIdString() { - // remove leading https://arxiv.org/abs/ from abstract url to get arXiv ID - String prefix = "https://arxiv.org/abs/"; + return urlAbstractPage.map(abstractUrl -> { - if (abstractUrl.startsWith(prefix)) { - return abstractUrl.substring(prefix.length()); + Matcher matcher = URL_PATTERN.matcher(abstractUrl); + if (matcher.find()) { + // remove leading http(s)://arxiv.org/abs/ from abstract url to get arXiv ID + return abstractUrl.substring(matcher.group(1).length()); } else { return abstractUrl; } + }); } @@ -409,8 +416,7 @@ public BibEntry toBibEntry(Character keywordDelimiter) { getDate().ifPresent(date -> bibEntry.setField(FieldName.DATE, date)); primaryCategory.ifPresent(category -> bibEntry.setField(FieldName.EPRINTCLASS, category)); journalReferenceText.ifPresent(journal -> bibEntry.setField(FieldName.JOURNALTITLE, journal)); - getPdfUrl().ifPresent(url -> bibEntry - .setFiles(Collections.singletonList(new LinkedFile(url, "PDF")))); + getPdfUrl().ifPresent(url -> bibEntry.setFiles(Collections.singletonList(new LinkedFile(url, "PDF")))); return bibEntry; } } diff --git a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java index ffc3469a567..19f4f52b636 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java @@ -416,7 +416,7 @@ private void putDate(Map fields, String elementName, DateDefinit private void putIfListIsNotEmpty(Map fields, List list, String key, String separator) { if (!list.isEmpty()) { - fields.put(key, Joiner.on(separator).join(list)); + fields.put(key, list.stream().collect(Collectors.joining(separator))); } } diff --git a/src/main/java/org/jabref/logic/net/ProgressInputStream.java b/src/main/java/org/jabref/logic/net/ProgressInputStream.java index 57d23907ff4..d114cbbe6cb 100644 --- a/src/main/java/org/jabref/logic/net/ProgressInputStream.java +++ b/src/main/java/org/jabref/logic/net/ProgressInputStream.java @@ -12,16 +12,18 @@ * Code based on http://stackoverflow.com/a/1339589/873661, but converted to use JavaFX properties instead of listeners */ public class ProgressInputStream extends FilterInputStream { + private final long maxNumBytes; private final LongProperty totalNumBytesRead; private final LongProperty progress; public ProgressInputStream(InputStream in, long maxNumBytes) { super(in); - this.maxNumBytes = maxNumBytes; this.totalNumBytesRead = new SimpleLongProperty(0); this.progress = new SimpleLongProperty(0); - this.progress.bind(totalNumBytesRead.divide(maxNumBytes)); + + this.maxNumBytes = maxNumBytes <= 0 ? 1 : maxNumBytes; + this.progress.bind(totalNumBytesRead.divide(this.maxNumBytes)); } public long getTotalNumBytesRead() { diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index 8219f0ebe0a..5ae3f915c02 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -2,6 +2,7 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; @@ -96,6 +97,7 @@ public static void bypassSSLVerification() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = {new X509TrustManager() { + @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @@ -249,8 +251,14 @@ public void toFile(Path destination) throws IOException { * Takes the web resource as the source for a monitored input stream. */ public ProgressInputStream asInputStream() throws IOException { - URLConnection urlConnection = this.openConnection(); - long fileSize = urlConnection.getContentLength(); + HttpURLConnection urlConnection = (HttpURLConnection) this.openConnection(); + + if ((urlConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) || (urlConnection.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST)) + { + LOGGER.error("Response message {} returned for url {}", urlConnection.getResponseMessage(), urlConnection.getURL()); + return new ProgressInputStream(new ByteArrayInputStream(new byte[0]), 0); + } + long fileSize = urlConnection.getContentLengthLong(); return new ProgressInputStream(new BufferedInputStream(urlConnection.getInputStream()), fileSize); } @@ -311,8 +319,8 @@ private URLConnection openConnection() throws IOException { int status = ((HttpURLConnection) connection).getResponseCode(); if (status != HttpURLConnection.HTTP_OK) { if ((status == HttpURLConnection.HTTP_MOVED_TEMP) - || (status == HttpURLConnection.HTTP_MOVED_PERM) - || (status == HttpURLConnection.HTTP_SEE_OTHER)) { + || (status == HttpURLConnection.HTTP_MOVED_PERM) + || (status == HttpURLConnection.HTTP_SEE_OTHER)) { // get redirect url from "location" header field String newUrl = connection.getHeaderField("Location"); // open the new connnection again diff --git a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java index ba3e428f9ca..8b9287d3e2b 100644 --- a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java +++ b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java @@ -22,8 +22,12 @@ public static Optional parse(String value) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if ((o == null) || (getClass() != o.getClass())) { + return false; + } ArXivIdentifier that = (ArXivIdentifier) o; @@ -45,6 +49,11 @@ public String getNormalized() { return identifier; } + @Override + public String toString() { + return "ArXivIdentifier [identifier=" + identifier + "]"; + } + @Override public Optional getExternalURI() { try { diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java index 01d1f31bb77..c11b94cb2bb 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java @@ -31,7 +31,7 @@ void findByDOI() throws IOException { entry.setField("doi", "10.1021/bk-2006-STYG.ch014"); assertEquals( - Optional.of(new URL("http://pubs.acs.org/doi/pdf/10.1021/bk-2006-STYG.ch014")), + Optional.of(new URL("https://pubs.acs.org/doi/pdf/10.1021/bk-2006-STYG.ch014")), finder.findFullText(entry) ); } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java index 3a438659b31..4c3fd88b745 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java @@ -191,5 +191,8 @@ public void searchIdentifierForSlicePaper() throws Exception { assertEquals(ArXivIdentifier.parse("1405.2249v1"), finder.findIdentifier(sliceTheoremPaper)); } - + @Test + public void searchEmptyId() throws Exception { + assertEquals(Optional.empty(), finder.performSearchById("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java b/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java index 5afe8a6c208..ee5f4c4e2bd 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java @@ -176,8 +176,7 @@ public void testPerformSearchByIdEmptyDOI() throws Exception { @Test public void testPerformSearchByIdInvalidDoi() throws Exception { - Optional fetchedEntry = fetcher.performSearchById("this.doi.will.fail"); - assertEquals(Optional.empty(), fetchedEntry); + assertEquals(Optional.empty(), fetcher.performSearchById("this.doi.will.fail")); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java b/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java index cb98379e242..6c9406e6e71 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java @@ -1,9 +1,11 @@ package org.jabref.logic.importer.fetcher; +import java.util.Collections; import java.util.Locale; import java.util.Optional; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.testutils.category.FetcherTest; import org.junit.jupiter.api.BeforeEach; @@ -115,7 +117,7 @@ public void findByEntry() throws Exception { @Test public void performSearchByIdFindsPaperWithoutTitle() throws Exception { - BibEntry entry = new BibEntry("article"); + BibEntry entry = new BibEntry(BibtexEntryTypes.ARTICLE); entry.setField("author", "Dominik Wujastyk"); entry.setField("doi", "10.1023/a:1003473214310"); entry.setField("issn", "0019-7246"); @@ -125,4 +127,14 @@ public void performSearchByIdFindsPaperWithoutTitle() throws Exception { assertEquals(Optional.of(entry), fetcher.performSearchById("10.1023/a:1003473214310")); } + + @Test + public void performSearchByEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } + + @Test + public void performSearchByEmptyQuery() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java index 1bbdb7eb249..51e1ba7ad97 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java @@ -28,21 +28,21 @@ public class DBLPFetcherTest { public void setUp() { ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class); when(importFormatPreferences.getFieldContentParserPreferences()) - .thenReturn(mock(FieldContentParserPreferences.class)); + .thenReturn(mock(FieldContentParserPreferences.class)); dblpFetcher = new DBLPFetcher(importFormatPreferences); entry = new BibEntry(); entry.setType(BibtexEntryTypes.ARTICLE.getName()); entry.setCiteKey("DBLP:journals/stt/GeigerHL16"); entry.setField(FieldName.TITLE, - "Process Engine Benchmarking with Betsy in the Context of {ISO/IEC} Quality Standards"); + "Process Engine Benchmarking with Betsy in the Context of {ISO/IEC} Quality Standards"); entry.setField(FieldName.AUTHOR, "Matthias Geiger and Simon Harrer and J{\\\"{o}}rg Lenhard"); entry.setField(FieldName.JOURNAL, "Softwaretechnik-Trends"); entry.setField(FieldName.VOLUME, "36"); entry.setField(FieldName.NUMBER, "2"); entry.setField(FieldName.YEAR, "2016"); entry.setField(FieldName.URL, - "http://pi.informatik.uni-siegen.de/stt/36_2/./03_Technische_Beitraege/ZEUS2016/beitrag_2.pdf"); + "http://pi.informatik.uni-siegen.de/stt/36_2/./03_Technische_Beitraege/ZEUS2016/beitrag_2.pdf"); entry.setField("biburl", "https://dblp.org/rec/bib/journals/stt/GeigerHL16"); entry.setField("bibsource", "dblp computer science bibliography, https://dblp.org"); @@ -64,4 +64,9 @@ public void findSingleEntryUsingComplexOperators() throws FetcherException { assertEquals(Collections.singletonList(entry), result); } + @Test + public void findNothing() throws Exception { + assertEquals(Collections.emptyList(), dblpFetcher.performSearch("")); + } + } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java index 4fc62ebec0f..77a0a20b925 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java @@ -31,7 +31,7 @@ void setUp() { @Test void searchByQueryFindsEntry() throws Exception { - BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE.getName()); + BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE); expected.setField("author", "Wei Wang and Yun He and Tong Li and Jiajun Zhu and Jinzhuo Liu"); expected.setField("doi", "10.1155/2018/5913634"); expected.setField("issn", "1875-919X"); @@ -65,10 +65,12 @@ void testBibJSONConverter() { assertEquals(Optional.of("VLSI Design"), bibEntry.getField("journal")); assertEquals(Optional.of("10.1155/2014/217495"), bibEntry.getField("doi")); assertEquals(Optional.of("Syed Asad Alam and Oscar Gustafsson"), bibEntry.getField("author")); - assertEquals( - Optional.of( - "Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain"), - bibEntry.getField("title")); + assertEquals(Optional.of("Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain"), bibEntry.getField("title")); assertEquals(Optional.of("2014"), bibEntry.getField("year")); } + + @Test + public void searchByEmptyQuery() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java b/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java index 9b7b6d2d86e..fa76e65b9b4 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java @@ -44,7 +44,7 @@ public void testPerformSearchById() throws Exception { entry.setField("institution", "Linköping University, The Institute of Technology"); entry.setCiteKey("Gustafsson260746"); entry.setField("journal", - "IEEE transactions on circuits and systems. 2, Analog and digital signal processing (Print)"); + "IEEE transactions on circuits and systems. 2, Analog and digital signal processing (Print)"); entry.setField("number", "11"); entry.setField("pages", "974--978"); entry.setField("title", "Lower bounds for constant multiplication problems"); @@ -65,4 +65,9 @@ public void testValidIdentifier() { public void testInvalidIdentifier() { assertFalse(fetcher.isValidId("banana")); } + + @Test + public void testEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java index cd88c970e6b..aafc965b53c 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java @@ -66,18 +66,16 @@ public void searchByIdSuccessfulWithLongISBN() throws FetcherException { public void authorsAreCorrectlyFormatted() throws Exception { BibEntry bibEntry = new BibEntry(); bibEntry.setType(BiblatexEntryTypes.BOOK); - bibEntry.setField("bibtexkey", "9783642434730"); + bibEntry.setField("bibtexkey", "9783662565094"); bibEntry.setField("title", "Fundamentals of Business Process Management"); bibEntry.setField("publisher", "Springer Berlin Heidelberg"); - bibEntry.setField("year", "2015"); + bibEntry.setField("year", "2018"); bibEntry.setField("author", "Dumas, Marlon and Rosa, Marcello La and Mendling, Jan and Reijers, Hajo A."); - bibEntry.setField("date", "2015-04-12"); - bibEntry.setField("ean", "9783642434730"); - bibEntry.setField("isbn", "3642434738"); - bibEntry.setField("pagetotal", "428"); - bibEntry.setField("url", "https://www.ebook.de/de/product/23955263/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); + bibEntry.setField("date", "2018-03-23"); + bibEntry.setField("ean", "9783662565094"); + bibEntry.setField("url", "https://www.ebook.de/de/product/33399253/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); - Optional fetchedEntry = fetcher.performSearchById("3642434738"); + Optional fetchedEntry = fetcher.performSearchById("978-3-662-56509-4"); assertEquals(Optional.of(bibEntry), fetchedEntry); } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java b/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java index 59f23a88b72..837e7607f6c 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java @@ -6,16 +6,24 @@ import org.jabref.model.entry.BibEntry; import org.jabref.testutils.category.FetcherTest; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Answers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @FetcherTest public class LibraryOfCongressTest { - private final LibraryOfCongress fetcher = new LibraryOfCongress(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS)); + private LibraryOfCongress fetcher; + + @BeforeEach + public void setUp() { + ImportFormatPreferences prefs = mock(ImportFormatPreferences.class); + when(prefs.getKeywordSeparator()).thenReturn(','); + fetcher = new LibraryOfCongress(prefs); + } @Test public void performSearchById() throws Exception { @@ -24,7 +32,7 @@ public void performSearchById() throws Exception { expected.setField("author", "West, Matthew"); expected.setField("isbn", "0123751063 (pbk.)"); expected.setField("issuance", "monographic"); - expected.setField("keywords", "Database design Data structures (Computer science)"); + expected.setField("keywords", "Database design, Data structures (Computer science)"); expected.setField("language", "eng"); expected.setField("lccn", "2010045158"); expected.setField("note", "Matthew West., Includes index."); @@ -36,4 +44,14 @@ public void performSearchById() throws Exception { assertEquals(Optional.of(expected), fetcher.performSearchById("2010045158")); } + + @Test + public void performSearchByEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } + + @Test + public void performSearchByInvalidId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("xxx")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java index e66d81f0948..5c2f2787854 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java @@ -28,7 +28,7 @@ class MathSciNetTest { void setUp() throws Exception { ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class); when(importFormatPreferences.getFieldContentParserPreferences()).thenReturn( - mock(FieldContentParserPreferences.class)); + mock(FieldContentParserPreferences.class)); fetcher = new MathSciNet(importFormatPreferences); ratiuEntry = new BibEntry(); diff --git a/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java b/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java index 9bb675fb340..0e060cc825a 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java @@ -28,10 +28,7 @@ void setUp() { void findByDOI() throws IOException { entry.setField("doi", "10.1038/nature12373"); - assertEquals( - Optional.of(new URL("https://dash.harvard.edu/bitstream/handle/1/12285462/Nanometer-Scale%20Thermometry.pdf?sequence=1")), - finder.findFullText(entry) - ); + assertEquals(Optional.of(new URL("https://dash.harvard.edu/bitstream/handle/1/12285462/Nanometer-Scale%20Thermometry.pdf?sequence=1")), finder.findFullText(entry)); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java index dbb02f25610..1ed849969ae 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java @@ -1,16 +1,17 @@ package org.jabref.logic.importer.fetcher; +import java.util.Optional; + import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BiblatexEntryTypes; import org.jabref.testutils.category.FetcherTest; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Answers; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @FetcherTest diff --git a/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java index 7123d5c3e50..9c250666750 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java @@ -26,7 +26,7 @@ void setUp() { @Test void searchByQueryFindsEntry() throws Exception { - BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE.getName()); + BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE); expected.setField("author", "Steinmacher, Igor and Gerosa, Marco and Conte, Tayana U. and Redmiles, David F."); expected.setField("date", "2018-06-14"); expected.setField("doi", "10.1007/s10606-018-9335-z"); @@ -66,4 +66,9 @@ void testSpringerJSONToBibtex() { assertEquals(Optional.of("Springer"), bibEntry.getField("publisher")); assertEquals(Optional.of("1992-09-01"), bibEntry.getField("date")); } + + @Test + void searchByEmptyQueryFindsNothing() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2-test.xml similarity index 95% rename from src/test/resources/log4j2.xml rename to src/test/resources/log4j2-test.xml index 8c6a336420a..0422d0bd80d 100644 --- a/src/test/resources/log4j2.xml +++ b/src/test/resources/log4j2-test.xml @@ -4,7 +4,7 @@ - + From dd4f043f1557abc4cef7a139751667355b87b850 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 24 Jul 2018 11:01:54 +0200 Subject: [PATCH 6/7] Update to latest release of richtextfx (#4213) RichTextFX will no longer be maintained https://github.com/FXMisc/RichTextFX/issues/768 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2bdc695491e..e738bf1944b 100644 --- a/build.gradle +++ b/build.gradle @@ -125,7 +125,7 @@ dependencies { compile 'de.saxsys:mvvmfx:1.7.0' compile 'org.fxmisc.easybind:easybind:1.0.3' compile 'org.fxmisc.flowless:flowless:0.6.1' - compile 'org.fxmisc.richtext:richtextfx:0.9.0' + compile 'org.fxmisc.richtext:richtextfx:0.9.1' compile 'com.sibvisions.external.jvxfx:dndtabpane:0.1' compile 'javax.inject:javax.inject:1' From 67474dc29882dfa567b203ff97495d06f016f80d Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 24 Jul 2018 11:36:23 +0200 Subject: [PATCH 7/7] Update dependencies (#4231) * update mockito * update archunit and errorprone * fix typo --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e738bf1944b..2daa628c683 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ plugins { id "de.sebastianboegl.shadow.transformer.log4j" version "2.1.1" id "com.simonharrer.modernizer" version '1.6.0-1' id 'me.champeau.gradle.jmh' version '0.4.7' - id 'net.ltgt.errorprone' version '0.0.14' + id 'net.ltgt.errorprone' version '0.0.15' id 'com.github.ben-manes.versions' version '0.20.0' } @@ -160,13 +160,13 @@ dependencies { testCompile 'org.junit-pioneer:junit-pioneer:0.1.2' testRuntime 'org.apache.logging.log4j:log4j-core:2.11.0' testRuntime 'org.apache.logging.log4j:log4j-jul:2.11.0' - testCompile 'org.mockito:mockito-core:2.19.1' + testCompile 'org.mockito:mockito-core:2.20.0' testCompile 'com.github.tomakehurst:wiremock:2.18.0' testCompile 'org.assertj:assertj-swing-junit:3.8.0' testCompile 'org.reflections:reflections:0.9.11' testCompile 'org.xmlunit:xmlunit-core:2.6.0' testCompile 'org.xmlunit:xmlunit-matchers:2.6.0' - testCompile 'com.tngtech.archunit:archunit-junit:0.8.2' + testCompile 'com.tngtech.archunit:archunit-junit:0.8.3' testCompile "org.testfx:testfx-core:4.0.+" testCompile "org.testfx:testfx-junit5:4.0.+"