From 029d78533edaff6d97846a77e064a60d5d131733 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Jun 2018 22:10:45 +0200 Subject: [PATCH 01/22] Fixes #4104: Reactivate next/previous entry shortcuts in entry editor --- CHANGELOG.md | 1 + src/main/java/org/jabref/gui/BasePanel.java | 28 ++----------------- .../jabref/gui/entryeditor/EntryEditor.java | 8 ++++++ .../org/jabref/gui/keyboard/KeyBinding.java | 4 +-- 4 files changed, 13 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b388a96140..17609efbce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). +- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀ alt + up/down`. ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 31bba397dd6..51634d03df1 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -1249,36 +1249,12 @@ public void clearAndSelect(final BibEntry bibEntry) { mainTable.clearAndSelect(bibEntry); } - /** - * This method selects the entry on the given position, and scrolls it into view in the table. - * If an entryEditor is shown, it is given focus afterwards. - * - * @deprecated use select by entry not by row - */ - @Deprecated - private void clearAndSelect(int pos) { - if ((pos >= 0) && (pos < mainTable.getItems().size())) { - mainTable.getSelectionModel().clearAndSelect(pos); - } - } - public void selectPreviousEntry() { - mainTable.getSelectionModel().clearSelection(); - mainTable.getSelectionModel().selectPrevious(); + mainTable.getSelectionModel().clearAndSelect(mainTable.getSelectionModel().getSelectedIndex() - 1); } public void selectNextEntry() { - mainTable.getSelectionModel().clearSelection(); - mainTable.getSelectionModel().selectNext(); - } - - public void selectFirstEntry() { - clearAndSelect(0); - } - - public void selectLastEntry() { - mainTable.getSelectionModel().clearSelection(); - mainTable.getSelectionModel().selectLast(); + mainTable.getSelectionModel().clearAndSelect(mainTable.getSelectionModel().getSelectedIndex() + 1); } /** diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 61ed4e04c5a..8e7e1ed5d25 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -126,6 +126,14 @@ private void setupKeyBindings() { tabbed.getSelectionModel().selectPrevious(); event.consume(); break; + case ENTRY_EDITOR_NEXT_ENTRY: + panel.selectNextEntry(); + event.consume(); + break; + case ENTRY_EDITOR_PREVIOUS_ENTRY: + panel.selectPreviousEntry(); + event.consume(); + break; case HELP: HelpAction.openHelpPage(HelpFile.ENTRY_EDITOR); event.consume(); diff --git a/src/main/java/org/jabref/gui/keyboard/KeyBinding.java b/src/main/java/org/jabref/gui/keyboard/KeyBinding.java index 989c56cba16..a4275922bdf 100644 --- a/src/main/java/org/jabref/gui/keyboard/KeyBinding.java +++ b/src/main/java/org/jabref/gui/keyboard/KeyBinding.java @@ -27,10 +27,10 @@ public enum KeyBinding { DOWNLOAD_FULL_TEXT("Look up full text documents", Localization.lang("Look up full text documents"), "alt+F7", KeyBindingCategory.QUALITY), EDIT_ENTRY("Edit entry", Localization.lang("Edit entry"), "ctrl+E", KeyBindingCategory.BIBTEX), EDIT_STRINGS("Edit strings", Localization.lang("Edit strings"), "ctrl+T", KeyBindingCategory.BIBTEX), - ENTRY_EDITOR_NEXT_ENTRY("Entry editor, next entry", Localization.lang("Entry editor, next entry"), "ctrl+shift+DOWN", KeyBindingCategory.VIEW), + ENTRY_EDITOR_NEXT_ENTRY("Entry editor, next entry", Localization.lang("Entry editor, next entry"), "alt+DOWN", KeyBindingCategory.VIEW), ENTRY_EDITOR_NEXT_PANEL("Entry editor, next panel", Localization.lang("Entry editor, next panel"), "ctrl+TAB", KeyBindingCategory.VIEW), ENTRY_EDITOR_NEXT_PANEL_2("Entry editor, next panel 2", Localization.lang("Entry editor, next panel 2"), "ctrl+PLUS", KeyBindingCategory.VIEW), - ENTRY_EDITOR_PREVIOUS_ENTRY("Entry editor, previous entry", Localization.lang("Entry editor, previous entry"), "ctrl+shift+UP", KeyBindingCategory.VIEW), + ENTRY_EDITOR_PREVIOUS_ENTRY("Entry editor, previous entry", Localization.lang("Entry editor, previous entry"), "alt+UP", KeyBindingCategory.VIEW), ENTRY_EDITOR_PREVIOUS_PANEL("Entry editor, previous panel", Localization.lang("Entry editor, previous panel"), "ctrl+shift+TAB", KeyBindingCategory.VIEW), FILE_LIST_EDITOR_MOVE_ENTRY_DOWN("File list editor, move entry down", Localization.lang("File list editor, move entry down"), "ctrl+DOWN", KeyBindingCategory.VIEW), FILE_LIST_EDITOR_MOVE_ENTRY_UP("File list editor, move entry up", Localization.lang("File list editor, move entry up"), "ctrl+UP", KeyBindingCategory.VIEW), From 0e4e0fb1f6128cf9f1fe85e973f115ef7420dc82 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 00:27:49 +0200 Subject: [PATCH 02/22] Preserve focus of text fields in entry editor upon switching between entries --- src/main/java/org/jabref/JabRefMain.java | 44 ++++++++++--------- .../jabref/gui/entryeditor/EntryEditor.java | 35 +++++++-------- .../gui/entryeditor/EntryEditorTab.java | 3 +- .../gui/entryeditor/FieldsEditorTab.java | 17 ++++++- .../gui/fieldeditors/FieldEditorFX.java | 13 +++++- .../org/jabref/gui/util/ControlHelper.java | 11 +++++ 6 files changed, 79 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/jabref/JabRefMain.java b/src/main/java/org/jabref/JabRefMain.java index fd4ffda4dde..89ae9fbc82c 100644 --- a/src/main/java/org/jabref/JabRefMain.java +++ b/src/main/java/org/jabref/JabRefMain.java @@ -46,33 +46,37 @@ public static void main(String[] args) { @Override public void start(Stage mainStage) throws Exception { - // Fail on unsupported Java versions - ensureCorrectJavaVersion(); - FallbackExceptionHandler.installExceptionHandler(); + try { + // Fail on unsupported Java versions + ensureCorrectJavaVersion(); + FallbackExceptionHandler.installExceptionHandler(); - // Init preferences - final JabRefPreferences preferences = JabRefPreferences.getInstance(); - Globals.prefs = preferences; - // Perform migrations - PreferencesMigrations.runMigrations(); + // Init preferences + final JabRefPreferences preferences = JabRefPreferences.getInstance(); + Globals.prefs = preferences; + // Perform migrations + PreferencesMigrations.runMigrations(); - configureProxy(preferences.getProxyPreferences()); + configureProxy(preferences.getProxyPreferences()); - Globals.startBackgroundTasks(); + Globals.startBackgroundTasks(); - applyPreferences(preferences); + applyPreferences(preferences); - // Process arguments - ArgumentProcessor argumentProcessor = new ArgumentProcessor(arguments, ArgumentProcessor.Mode.INITIAL_START); + // Process arguments + ArgumentProcessor argumentProcessor = new ArgumentProcessor(arguments, ArgumentProcessor.Mode.INITIAL_START); - // Check for running JabRef - if (!handleMultipleAppInstances(arguments) || argumentProcessor.shouldShutDown()) { - shutdownCurrentInstance(); - return; - } + // Check for running JabRef + if (!handleMultipleAppInstances(arguments) || argumentProcessor.shouldShutDown()) { + shutdownCurrentInstance(); + return; + } - // If not, start GUI - new JabRefGUI(mainStage, argumentProcessor.getParserResults(), argumentProcessor.isBlank()); + // If not, start GUI + new JabRefGUI(mainStage, argumentProcessor.getParserResults(), argumentProcessor.isBlank()); + } catch (Exception ex) { + LOGGER.error("Unexpected exception", ex); + } } @Override diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 8e7e1ed5d25..5dfe3754f91 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -246,36 +246,35 @@ public BibEntry getEntry() { public void setEntry(BibEntry entry) { Objects.requireNonNull(entry); - // remove subscription for old entry if existing + // Remove subscription for old entry if existing if (typeSubscription != null) { typeSubscription.unsubscribe(); } + this.entry = entry; - DefaultTaskExecutor.runInJavaFXThread(() -> { - recalculateVisibleTabs(); - if (preferences.showSourceTabByDefault()) { - tabbed.getSelectionModel().select(sourceTab); - } + recalculateVisibleTabs(); + if (preferences.showSourceTabByDefault()) { + tabbed.getSelectionModel().select(sourceTab); + } - // Notify current tab about new entry - EntryEditorTab selectedTab = (EntryEditorTab) tabbed.getSelectionModel().getSelectedItem(); - selectedTab.notifyAboutFocus(entry); + // Notify current tab about new entry + getSelectedTab().notifyAboutFocus(entry); - setupToolBar(); - }); + setupToolBar(); - // subscribe to type changes for rebuilding the currently visible tab + // Subscribe to type changes for rebuilding the currently visible tab typeSubscription = EasyBind.subscribe(this.entry.typeProperty(), type -> { - DefaultTaskExecutor.runInJavaFXThread(() -> { - typeLabel.setText(new TypedBibEntry(entry, bibDatabaseContext.getMode()).getTypeForDisplay()); - recalculateVisibleTabs(); - EntryEditorTab selectedTab = (EntryEditorTab) tabbed.getSelectionModel().getSelectedItem(); - selectedTab.notifyAboutFocus(entry); - }); + typeLabel.setText(new TypedBibEntry(entry, bibDatabaseContext.getMode()).getTypeForDisplay()); + recalculateVisibleTabs(); + getSelectedTab().notifyAboutFocus(entry); }); } + private EntryEditorTab getSelectedTab() { + return (EntryEditorTab) tabbed.getSelectionModel().getSelectedItem(); + } + private void setupToolBar() { // Update type label TypedBibEntry typedEntry = new TypedBibEntry(entry, bibDatabaseContext.getMode()); diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java index 550fbcaba99..edaa93a2b47 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java @@ -2,7 +2,6 @@ import javafx.scene.control.Tab; -import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.model.entry.BibEntry; public abstract class EntryEditorTab extends Tab { @@ -39,7 +38,7 @@ public void notifyAboutFocus(BibEntry entry) { if (!entry.equals(currentEntry) || !currentEntryType.equals(entry.getType())) { currentEntry = entry; currentEntryType = entry.getType(); - DefaultTaskExecutor.runInJavaFXThread(() -> bindToEntry(entry)); + bindToEntry(entry); } handleFocus(); } diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java index dacc6c23212..f714097c64f 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java @@ -5,11 +5,13 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Stream; import javax.swing.undo.UndoManager; +import javafx.application.Platform; import javafx.geometry.VPos; import javafx.scene.Node; import javafx.scene.Parent; @@ -199,7 +201,7 @@ private String getPrompt(String field) { public void requestFocus(String fieldName) { if (editors.containsKey(fieldName)) { activeField = editors.get(fieldName); - activeField.requestFocus(); + activeField.focus(); } } @@ -212,14 +214,25 @@ public boolean shouldShow(BibEntry entry) { @Override public void handleFocus() { if (activeField != null) { - activeField.requestFocus(); + activeField.focus(); } } @Override protected void bindToEntry(BibEntry entry) { + Optional selectedFieldName = editors.entrySet() + .stream() + .filter(editor -> editor.getValue().childIsFocused()) + .map(Map.Entry::getKey) + .findFirst(); + Region panel = setupPanel(entry, isCompressed, suggestionProviders, undoManager); setContent(panel); + + Platform.runLater(() -> { + // Restore focus to field (run this async so that editor is already initialized correctly) + selectedFieldName.ifPresent(this::requestFocus); + }); } protected abstract Collection determineFieldsToShow(BibEntry entry, EntryType entryType); diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java index 3a2978ad060..fea5b0432d8 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java +++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java @@ -2,6 +2,7 @@ import javafx.scene.Parent; +import org.jabref.gui.util.ControlHelper; import org.jabref.model.entry.BibEntry; public interface FieldEditorFX { @@ -10,8 +11,16 @@ public interface FieldEditorFX { Parent getNode(); - default void requestFocus() { - getNode().requestFocus(); + default void focus() { + getNode().getChildrenUnmodifiable() + .stream() + .findFirst() + .orElse(getNode()) + .requestFocus(); + } + + default boolean childIsFocused() { + return ControlHelper.childIsFocused(getNode()); } /** diff --git a/src/main/java/org/jabref/gui/util/ControlHelper.java b/src/main/java/org/jabref/gui/util/ControlHelper.java index fa4e68b1bd3..db6ae5e9d4c 100644 --- a/src/main/java/org/jabref/gui/util/ControlHelper.java +++ b/src/main/java/org/jabref/gui/util/ControlHelper.java @@ -7,6 +7,7 @@ import javafx.embed.swing.SwingNode; import javafx.event.ActionEvent; import javafx.event.Event; +import javafx.scene.Parent; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; @@ -28,4 +29,14 @@ public static void setSwingContent(DialogPane dialogPane, JComponent content) { dialogPane.setContent(node); } + + public static boolean childIsFocused(Parent node) { + return node.isFocused() || node.getChildrenUnmodifiable().stream().anyMatch(child -> { + if (child instanceof Parent) { + return childIsFocused((Parent) child); + } else { + return child.isFocused(); + } + }); + } } From 46d4de8f423bd24f0e94cf8378774088bd02a0b9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 15:56:39 +0200 Subject: [PATCH 03/22] Replace swing clipboard with JavaFX one --- src/main/java/org/jabref/gui/BasePanel.java | 14 +- .../java/org/jabref/gui/ClipBoardManager.java | 140 ++++++------------ src/main/java/org/jabref/gui/JabRefFrame.java | 5 - .../java/org/jabref/gui/PreviewPanel.java | 4 +- .../actions/CopyBibTeXKeyAndLinkAction.java | 2 +- .../jabref/gui/actions/CopyDoiUrlAction.java | 5 +- .../actions/CopyVersionToClipboardAction.java | 23 --- .../org/jabref/gui/desktop/JabRefDesktop.java | 3 +- .../FileAnnotationTabViewModel.java | 4 +- .../errorconsole/ErrorConsoleViewModel.java | 4 +- .../gui/exporter/ExportToClipboardAction.java | 10 +- .../jabref/gui/exporter/RtfTransferable.java | 53 ------- .../gui/fieldeditors/HtmlTransferable.java | 70 --------- .../gui/fieldeditors/XmlTransferable.java | 50 ------- .../jabref/gui/help/AboutDialogViewModel.java | 2 +- .../org/jabref/gui/maintable/MainTable.java | 7 +- .../gui/plaintextimport/TextInputDialog.java | 3 +- .../jabref/gui/search/SearchResultFrame.java | 11 +- .../CitationStyleToClipboardWorker.java | 114 +++++++------- .../org/jabref/gui/ClipBoardManagerTest.java | 70 --------- .../fieldeditors/HtmlTransferableTest.java | 91 ------------ .../CitationStyleToClipboardWorkerTest.java | 75 +++++----- 22 files changed, 172 insertions(+), 588 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/actions/CopyVersionToClipboardAction.java delete mode 100644 src/main/java/org/jabref/gui/exporter/RtfTransferable.java delete mode 100644 src/main/java/org/jabref/gui/fieldeditors/HtmlTransferable.java delete mode 100644 src/main/java/org/jabref/gui/fieldeditors/XmlTransferable.java delete mode 100644 src/test/java/org/jabref/gui/ClipBoardManagerTest.java delete mode 100644 src/test/java/org/jabref/gui/fieldeditors/HtmlTransferableTest.java diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 31bba397dd6..f7b19d2b8a4 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -1,9 +1,7 @@ package org.jabref.gui; -import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; -import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.io.File; import java.io.IOException; @@ -648,8 +646,7 @@ private void copyTitle() { output(Localization.lang("None of the selected entries have titles.")); return; } - StringSelection ss = new StringSelection(String.join("\n", titles)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, BasePanel.this); + Globals.clipboardManager.setContent(String.join("\n", titles)); if (titles.size() == selectedBibEntries.size()) { // All entries had titles. @@ -677,8 +674,7 @@ private void copyCiteKey() { String citeCommand = Optional.ofNullable(Globals.prefs.get(JabRefPreferences.CITE_COMMAND)) .filter(cite -> cite.contains("\\")) // must contain \ .orElse("\\cite"); - StringSelection ss = new StringSelection(citeCommand + "{" + sb + '}'); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, BasePanel.this); + Globals.clipboardManager.setContent(citeCommand + "{" + sb + '}'); if (keys.size() == bes.size()) { // All entries had keys. @@ -702,8 +698,7 @@ private void copyKey() { return; } - StringSelection ss = new StringSelection(String.join(",", keys)); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, BasePanel.this); + Globals.clipboardManager.setContent(String.join(",", keys)); if (keys.size() == bes.size()) { // All entries had keys. @@ -744,8 +739,7 @@ private void copyKeyAndTitle() { return; } - final StringSelection ss = new StringSelection(sb.toString()); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, BasePanel.this); + Globals.clipboardManager.setContent(sb.toString()); if (copied == bes.size()) { // All entries had keys. diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index eddcd6a67de..006ab49d3e8 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -1,19 +1,13 @@ package org.jabref.gui; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.ClipboardOwner; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; +import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; +import javafx.scene.input.DataFormat; import org.jabref.Globals; import org.jabref.logic.bibtex.BibEntryWriter; @@ -22,24 +16,28 @@ import org.jabref.logic.importer.ImportException; import org.jabref.logic.importer.ImportFormatReader; import org.jabref.logic.importer.ImportFormatReader.UnknownFormatImport; +import org.jabref.logic.importer.ParseException; import org.jabref.logic.importer.fetcher.DoiFetcher; +import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.identifier.DOI; +import org.jabref.model.util.OptionalUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ClipBoardManager implements ClipboardOwner { +public class ClipBoardManager { private static final Logger LOGGER = LoggerFactory.getLogger(ClipBoardManager.class); + public static final DataFormat XML = new DataFormat("application/xml"); private final Clipboard clipboard; private final ImportFormatReader importFormatReader; public ClipBoardManager() { - this(Toolkit.getDefaultToolkit().getSystemClipboard(), Globals.IMPORT_FORMAT_READER); + this(Clipboard.getSystemClipboard(), Globals.IMPORT_FORMAT_READER); } public ClipBoardManager(Clipboard clipboard, ImportFormatReader importFormatReader) { @@ -48,18 +46,10 @@ public ClipBoardManager(Clipboard clipboard, ImportFormatReader importFormatRead } /** - * Empty implementation of the ClipboardOwner interface. + * Puts content onto the clipboard. */ - @Override - public void lostOwnership(Clipboard aClipboard, Transferable aContents) { - //do nothing - } - - /** - * Places the string into the clipboard using a {@link Transferable}. - */ - public void setTransferableClipboardContents(Transferable transferable) { - clipboard.setContents(transferable, this); + public void setContent(ClipboardContent content) { + clipboard.setContent(content); } /** @@ -68,40 +58,28 @@ public void setTransferableClipboardContents(Transferable transferable) { * @return any text found on the Clipboard; if none found, return an * empty String. */ - public String getClipboardContents() { - String result = ""; - //odd: the Object param of getContents is not currently used - Transferable contents = clipboard.getContents(null); - if ((contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor)) { - try { - result = (String) contents.getTransferData(DataFlavor.stringFlavor); - } catch (UnsupportedFlavorException | IOException e) { - //highly unlikely since we are using a standard DataFlavor - LOGGER.info("problem with getting clipboard contents", e); - } + public String getContents() { + String result = clipboard.getString(); + if (result == null) { + return ""; + } else { + return result; } - return result; } - public void setClipboardHtmlContent(String html) { - // TODO: This works on Mac and Windows 10, but not on Ubuntu 16.04 - final javafx.scene.input.Clipboard clipboard = javafx.scene.input.Clipboard.getSystemClipboard(); + public void setHtmlContent(String html) { final ClipboardContent content = new ClipboardContent(); content.putHtml(html); clipboard.setContent(content); } - public void setClipboardContent(String string) { - // TODO: This works on Mac and Windows 10, but not on Ubuntu 16.04 - final javafx.scene.input.Clipboard clipboard = javafx.scene.input.Clipboard.getSystemClipboard(); + public void setContent(String string) { final ClipboardContent content = new ClipboardContent(); content.putString(string); clipboard.setContent(content); } - public void setClipboardContent(List entries) throws IOException { - // TODO: This works on Mac and Windows 10, but not on Ubuntu 16.04 - final javafx.scene.input.Clipboard clipboard = javafx.scene.input.Clipboard.getSystemClipboard(); + public void setContent(List entries) throws IOException { final ClipboardContent content = new ClipboardContent(); BibEntryWriter writer = new BibEntryWriter(new LatexFieldFormatter(Globals.prefs.getLatexFieldFormatterPreferences()), false); String serializedEntries = writer.serializeAll(entries, BibDatabaseMode.BIBTEX); @@ -110,60 +88,40 @@ public void setClipboardContent(List entries) throws IOException { clipboard.setContent(content); } - /** - * Place a String on the clipboard, and make this class the - * owner of the Clipboard's contents. - * - * @deprecated use {@link #setClipboardContent(String)} instead - */ - @Deprecated - public void setClipboardContents(String aString) { - StringSelection stringSelection = new StringSelection(aString); - clipboard.setContents(stringSelection, this); - } + public List extractEntries() { + Object entries = clipboard.getContent(DragAndDropDataFormats.ENTRIES); - public List extractBibEntriesFromClipboard() { - // Get clipboard contents, and see if TransferableBibtexEntry is among the content flavors offered - Transferable content = clipboard.getContents(null); - List result = new ArrayList<>(); - - if (content.isDataFlavorSupported(TransferableBibtexEntry.ENTRY_FLAVOR)) { - // We have determined that the clipboard data is a set of entries. + BibtexParser parser = new BibtexParser(Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + if (entries != null) { + // We have determined that the clipboard data is a set of entries (serialized as a string). try { - @SuppressWarnings("unchecked") - List contents = (List) content.getTransferData(TransferableBibtexEntry.ENTRY_FLAVOR); - // We clone the entries to make sure we don't accidentally paste references - result = contents.stream().map(entry -> (BibEntry) entry.clone()).collect(Collectors.toList()); - } catch (UnsupportedFlavorException | ClassCastException ex) { - LOGGER.warn("Could not paste this type", ex); - } catch (IOException ex) { - LOGGER.warn("Could not paste", ex); + return parser.parseEntries((String) entries); + } catch (ParseException ex) { + LOGGER.error("Could not paste", ex); } - } else if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) { - try { - String data = (String) content.getTransferData(DataFlavor.stringFlavor); - // fetch from doi - if (DOI.parse(data).isPresent()) { - LOGGER.info("Found DOI in clipboard"); - Optional entry = new DoiFetcher(Globals.prefs.getImportFormatPreferences()).performSearchById(new DOI(data).getDOI()); - entry.ifPresent(result::add); - } else { - try { - UnknownFormatImport unknownFormatImport = importFormatReader.importUnknownFormat(data); - result = unknownFormatImport.parserResult.getDatabase().getEntries(); - } catch (ImportException e) { - // import failed and result will be empty + } else { + String data = clipboard.getString(); + if (data != null) { + try { + // fetch from doi + Optional doi = DOI.parse(data); + if (doi.isPresent()) { + LOGGER.info("Found DOI in clipboard"); + Optional entry = new DoiFetcher(Globals.prefs.getImportFormatPreferences()).performSearchById(doi.get().getDOI()); + return OptionalUtil.toList(entry); + } else { + try { + UnknownFormatImport unknownFormatImport = importFormatReader.importUnknownFormat(data); + return unknownFormatImport.parserResult.getDatabase().getEntries(); + } catch (ImportException e) { + // import failed and result will be empty + } } + } catch (FetcherException ex) { + LOGGER.error("Error while fetching", ex); } - } catch (UnsupportedFlavorException ex) { - LOGGER.warn("Could not parse this type", ex); - } catch (IOException ex) { - LOGGER.warn("Data is no longer available in the requested flavor", ex); - } catch (FetcherException ex) { - LOGGER.error("Error while fetching", ex); } - } - return result; + return Collections.emptyList(); } } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index fe47af976ce..381966df1e1 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -418,11 +418,6 @@ public JabRefPreferences prefs() { * @param filenames the filenames of all currently opened files - used for storing them if prefs openLastEdited is set to true */ private void tearDownJabRef(List filenames) { - Globals.stopBackgroundTasks(); - Globals.shutdownThreadPools(); - - //dispose(); - //prefs.putBoolean(JabRefPreferences.WINDOW_MAXIMISED, getExtendedState() == Frame.MAXIMIZED_BOTH); if (prefs.getBoolean(JabRefPreferences.OPEN_LAST_EDITED)) { diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index b2e39f825e6..b5067e7accf 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -74,7 +74,7 @@ public PreviewPanel(BasePanel panel, BibDatabaseContext databaseContext, KeyBind this.databaseContext = Optional.ofNullable(databaseContext); this.basePanel = Optional.ofNullable(panel); this.dialogService = dialogService; - this.clipBoardManager = new ClipBoardManager(); + this.clipBoardManager = Globals.clipboardManager; this.keyBindingRepository = keyBindingRepository; // Set up scroll pane for preview pane @@ -293,6 +293,6 @@ public void close() { private void copyPreviewToClipBoard() { String previewContent = (String) previewView.getEngine().executeScript("document.documentElement.outerHTML"); - clipBoardManager.setClipboardContents(previewContent); + clipBoardManager.setContent(previewContent); } } diff --git a/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java b/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java index 831ac29ec93..6f55af1e27b 100644 --- a/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java +++ b/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java @@ -47,7 +47,7 @@ public void action() throws Exception { sb.append(OS.NEWLINE); } - DefaultTaskExecutor.runInJavaFXThread(() -> clipboardManager.setClipboardHtmlContent(sb.toString())); + DefaultTaskExecutor.runInJavaFXThread(() -> clipboardManager.setHtmlContent(sb.toString())); int copied = entriesWithKey.size(); int toCopy = entries.size(); diff --git a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java b/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java index fd8bfb7ec86..aa8ee344abe 100644 --- a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java +++ b/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java @@ -7,8 +7,8 @@ import javafx.scene.control.TextArea; +import org.jabref.Globals; import org.jabref.JabRefGUI; -import org.jabref.gui.ClipBoardManager; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.identifier.DOI; @@ -36,8 +36,7 @@ public void actionPerformed(ActionEvent e) { Optional urlOptional = DOI.parse(identifier).map(DOI::getURIAsASCIIString); if (urlOptional.isPresent()) { - ClipBoardManager clipBoard = new ClipBoardManager(); - clipBoard.setClipboardContents(urlOptional.get()); + Globals.clipboardManager.setContent(urlOptional.get()); JabRefGUI.getMainFrame().output(Localization.lang("The link has been copied to the clipboard.")); } else { JabRefGUI.getMainFrame().output(Localization.lang("Invalid DOI: '%0'.", identifier)); diff --git a/src/main/java/org/jabref/gui/actions/CopyVersionToClipboardAction.java b/src/main/java/org/jabref/gui/actions/CopyVersionToClipboardAction.java deleted file mode 100644 index c0de2fcd01d..00000000000 --- a/src/main/java/org/jabref/gui/actions/CopyVersionToClipboardAction.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.jabref.gui.actions; - -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; - -import org.jabref.Globals; -import org.jabref.JabRefGUI; -import org.jabref.gui.ClipBoardManager; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.util.BuildInfo; - -public class CopyVersionToClipboardAction extends AbstractAction { - - @Override - public void actionPerformed(ActionEvent e) { - String info = String.format("JabRef %s%n%s %s %s %nJava %s", Globals.BUILD_INFO.getVersion(), BuildInfo.OS, - BuildInfo.OS_VERSION, BuildInfo.OS_ARCH, BuildInfo.JAVA_VERSION); - new ClipBoardManager().setClipboardContents(info); - JabRefGUI.getMainFrame().output(Localization.lang("Copied version to clipboard")); - } - -} diff --git a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java index 2dd7ae8134c..cfff8fb441c 100644 --- a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java @@ -14,7 +14,6 @@ import org.jabref.Globals; import org.jabref.JabRefGUI; -import org.jabref.gui.ClipBoardManager; import org.jabref.gui.desktop.os.DefaultDesktop; import org.jabref.gui.desktop.os.Linux; import org.jabref.gui.desktop.os.NativeDesktop; @@ -198,7 +197,7 @@ public static void openBrowserShowPopup(String url) { try { openBrowser(url); } catch (IOException exception) { - new ClipBoardManager().setClipboardContents(url); + Globals.clipboardManager.setContent(url); LOGGER.error("Could not open browser", exception); String couldNotOpenBrowser = Localization.lang("Could not open browser."); String openManually = Localization.lang("Please open %0 manually.", url); diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java index ec828e67840..60bf434bdfe 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java @@ -16,8 +16,8 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; +import org.jabref.Globals; import org.jabref.gui.AbstractViewModel; -import org.jabref.gui.ClipBoardManager; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.pdf.FileAnnotationCache; @@ -122,7 +122,7 @@ public void copyCurrentAnnotation() { sj.add(Localization.lang("Content") + ": " + getCurrentAnnotation().getContent()); sj.add(Localization.lang("Marking") + ": " + getCurrentAnnotation().markingProperty().get()); - new ClipBoardManager().setClipboardContents(sj.toString()); + Globals.clipboardManager.setContent(sj.toString()); } private FileAnnotationViewModel getCurrentAnnotation() { diff --git a/src/main/java/org/jabref/gui/errorconsole/ErrorConsoleViewModel.java b/src/main/java/org/jabref/gui/errorconsole/ErrorConsoleViewModel.java index da09f42e5f0..d5b25ae7aea 100644 --- a/src/main/java/org/jabref/gui/errorconsole/ErrorConsoleViewModel.java +++ b/src/main/java/org/jabref/gui/errorconsole/ErrorConsoleViewModel.java @@ -75,7 +75,7 @@ public void copyLog(List messages) { if (messages.isEmpty()) { return; } - clipBoardManager.setClipboardContents(getLogMessagesAsString(messages)); + clipBoardManager.setContent(getLogMessagesAsString(messages)); dialogService.notify(Localization.lang("Log copied to clipboard.")); } @@ -100,7 +100,7 @@ public void reportIssue() { // log messages String issueDetails = "
\n" + "" + "Detail information:" + "\n\n```\n" + getLogMessagesAsString(allMessagesData) + "\n```\n\n
"; - clipBoardManager.setClipboardContents(issueDetails); + clipBoardManager.setContent(issueDetails); // bug report body String issueBody = systemInfo + "\n\n" + howToReproduce + "\n\n" + "Paste your log details here."; diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index a55b40e50c8..4a6a095864c 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -1,6 +1,5 @@ package org.jabref.gui.exporter; -import java.awt.Toolkit; import java.awt.datatransfer.ClipboardOwner; import java.io.IOException; import java.io.InputStreamReader; @@ -14,6 +13,8 @@ import java.util.Optional; import java.util.stream.Collectors; +import javafx.scene.input.ClipboardContent; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; @@ -99,10 +100,9 @@ public void run() { ClipboardOwner owner = (clipboard, content) -> { // Do nothing }; - RtfTransferable rs = new RtfTransferable(sb.toString()); - Toolkit.getDefaultToolkit() - .getSystemClipboard() - .setContents(rs, owner); + ClipboardContent clipboardContent = new ClipboardContent(); + clipboardContent.putRtf(sb.toString()); + Globals.clipboardManager.setContent(clipboardContent); message = Localization.lang("Entries exported to clipboard") + ": " + entries.size(); } catch (Exception e) { diff --git a/src/main/java/org/jabref/gui/exporter/RtfTransferable.java b/src/main/java/org/jabref/gui/exporter/RtfTransferable.java deleted file mode 100644 index 5d936b98086..00000000000 --- a/src/main/java/org/jabref/gui/exporter/RtfTransferable.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.jabref.gui.exporter; - -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -public class RtfTransferable implements Transferable { - - private static final DataFlavor RTF_FLAVOR = new DataFlavor("text/rtf; class=java.io.InputStream", "RTF Format"); - private static final DataFlavor TEXT_FLAVOR = DataFlavor.stringFlavor; - - private static final List ALL_FLAVORS = Arrays.asList(RTF_FLAVOR, TEXT_FLAVOR); - - private final String rtfText; - private final String plainText; - - - public RtfTransferable(String text) { - this.rtfText = text; - this.plainText = text; - } - - public RtfTransferable(String rtfText, String plainText) { - this.rtfText = rtfText; - this.plainText = plainText; - } - - @Override - public DataFlavor[] getTransferDataFlavors() { - return ALL_FLAVORS.toArray(new DataFlavor[ALL_FLAVORS.size()]); - } - - @Override - public boolean isDataFlavorSupported(DataFlavor flavor) { - return ALL_FLAVORS.parallelStream().anyMatch(flavor::equals); - } - - @Override - public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { - if (flavor.equals(RTF_FLAVOR)) { - return new ByteArrayInputStream(rtfText.getBytes()); - } else if (flavor.equals(TEXT_FLAVOR)) { - return plainText; - } else { - throw new UnsupportedFlavorException(flavor); - } - } - -} diff --git a/src/main/java/org/jabref/gui/fieldeditors/HtmlTransferable.java b/src/main/java/org/jabref/gui/fieldeditors/HtmlTransferable.java deleted file mode 100644 index 47e866f73c0..00000000000 --- a/src/main/java/org/jabref/gui/fieldeditors/HtmlTransferable.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -import org.jabref.logic.formatter.bibtexfields.HtmlToUnicodeFormatter; -import org.jabref.logic.util.OS; - - -/** - Based on http://newsgroups.derkeiler.com/Archive/De/de.comp.lang.java/2010-04/msg00203.html - */ -public class HtmlTransferable implements Transferable { - - public static final DataFlavor HTML_FLAVOR = new DataFlavor("text/html;charset=utf-8;class=java.lang.String", "HTML Format"); - public static final DataFlavor TEXT_FLAVOR = DataFlavor.stringFlavor; - private static final List ALL_FLAVORS = Arrays.asList(HTML_FLAVOR, DataFlavor.allHtmlFlavor, TEXT_FLAVOR); - private static final Pattern HTML_NEWLINE = Pattern.compile(" ?
|
"); - private static final Pattern REMOVE_HTML = Pattern.compile("<(?!br)(?!BR).*?>"); - private static final Pattern WHITESPACE_AROUND_NEWLINE = Pattern.compile("(?m)^\\s+|\\v+"); - private static final Pattern DOUBLE_WHITESPACES = Pattern.compile("[ ]{2,}"); - private final String htmlText; - private final String plainText; - - public HtmlTransferable(String html) { - this.htmlText = html; - - // convert html to text by stripping out HTML - String plain = html; - plain = REMOVE_HTML.matcher(plain).replaceAll(" "); - plain = WHITESPACE_AROUND_NEWLINE.matcher(plain).replaceAll(""); - plain = DOUBLE_WHITESPACES.matcher(plain).replaceAll(" "); - plain = HTML_NEWLINE.matcher(plain).replaceAll(OS.NEWLINE); - // replace all HTML codes such as & - plain = new HtmlToUnicodeFormatter().format(plain); - this.plainText = plain.trim(); - } - - public HtmlTransferable(String htmlText, String plainText) { - this.htmlText = htmlText; - this.plainText = plainText; - } - - @Override - public DataFlavor[] getTransferDataFlavors() { - return ALL_FLAVORS.toArray(new DataFlavor[ALL_FLAVORS.size()]); - } - - @Override - public boolean isDataFlavorSupported(DataFlavor flavor) { - return ALL_FLAVORS.parallelStream().anyMatch(flavor::equals); - } - - @Override - public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { - if (flavor.equals(HTML_FLAVOR) || flavor.equals(DataFlavor.allHtmlFlavor)) { - return htmlText; - } else if (flavor.equals(TEXT_FLAVOR)) { - return plainText; - } else { - throw new UnsupportedFlavorException(flavor); - } - } - -} diff --git a/src/main/java/org/jabref/gui/fieldeditors/XmlTransferable.java b/src/main/java/org/jabref/gui/fieldeditors/XmlTransferable.java deleted file mode 100644 index 457e9f446fd..00000000000 --- a/src/main/java/org/jabref/gui/fieldeditors/XmlTransferable.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -public class XmlTransferable implements Transferable { - - private static final DataFlavor XML_FLAVOR = new DataFlavor("application/xml;charset=utf-8;class=java.lang.String", "XML Format"); - private static final DataFlavor TEXT_FLAVOR = DataFlavor.stringFlavor; - - private static final List ALL_FLAVORS = Arrays.asList(XML_FLAVOR, HtmlTransferable.HTML_FLAVOR, TEXT_FLAVOR); - - private final String xmlText; - private final String plainText; - - public XmlTransferable(String text) { - this(text, text); - } - - public XmlTransferable(String xmlText, String plainText) { - this.xmlText = xmlText; - this.plainText = plainText; - } - - @Override - public DataFlavor[] getTransferDataFlavors() { - return ALL_FLAVORS.toArray(new DataFlavor[ALL_FLAVORS.size()]); - } - - @Override - public boolean isDataFlavorSupported(DataFlavor flavor) { - return ALL_FLAVORS.parallelStream().anyMatch(flavor::equals); - } - - @Override - public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { - if (flavor.equals(XML_FLAVOR) || flavor.equals(HtmlTransferable.HTML_FLAVOR)) { - return xmlText; - } else if (flavor.equals(TEXT_FLAVOR)) { - return plainText; - } else { - throw new UnsupportedFlavorException(flavor); - } - } - -} diff --git a/src/main/java/org/jabref/gui/help/AboutDialogViewModel.java b/src/main/java/org/jabref/gui/help/AboutDialogViewModel.java index 5ebc5a0f5d0..f6534230b57 100644 --- a/src/main/java/org/jabref/gui/help/AboutDialogViewModel.java +++ b/src/main/java/org/jabref/gui/help/AboutDialogViewModel.java @@ -119,7 +119,7 @@ public String getEnvironmentInfo() { } public void copyVersionToClipboard() { - clipBoardManager.setClipboardContents(versionInfo); + clipBoardManager.setContent(versionInfo); dialogService.notify(Localization.lang("Copied version to clipboard")); } diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index d704560cf49..663a046ba4e 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -20,7 +20,6 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; -import org.jabref.gui.ClipBoardManager; import org.jabref.gui.JabRefFrame; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.keyboard.KeyBinding; @@ -85,7 +84,7 @@ public MainTable(MainTableDataModel model, JabRefFrame frame, pane.setFitToWidth(true); this.pane.getStylesheets().add(MainTable.class.getResource("MainTable.css").toExternalForm()); - + // Store visual state new PersistenceVisualStateTable(this, Globals.prefs); @@ -115,7 +114,7 @@ public void copy() { if (!selectedEntries.isEmpty()) { try { - Globals.clipboardManager.setClipboardContent(selectedEntries); + Globals.clipboardManager.setContent(selectedEntries); panel.output(panel.formatOutputMessage(Localization.lang("Copied"), selectedEntries.size())); } catch (IOException e) { LOGGER.error("Error while copying selected entries to clipboard", e); @@ -182,7 +181,7 @@ private void clearAndSelectLast() { public void paste() { // Find entries in clipboard - List entriesToAdd = new ClipBoardManager().extractBibEntriesFromClipboard(); + List entriesToAdd = Globals.clipboardManager.extractEntries(); if (!entriesToAdd.isEmpty()) { // Add new entries diff --git a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java index f8aac892478..c5b9468ff0a 100644 --- a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java @@ -59,7 +59,6 @@ import javax.swing.text.StyledDocument; import org.jabref.Globals; -import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefDialog; import org.jabref.gui.JabRefFrame; @@ -521,7 +520,7 @@ public PasteAction() { @Override public void actionPerformed(ActionEvent e) { - String data = new ClipBoardManager().getClipboardContents(); + String data = Globals.clipboardManager.getContents(); int selStart = textPane.getSelectionStart(); int selEnd = textPane.getSelectionEnd(); if ((selEnd - selStart) > 0) { diff --git a/src/main/java/org/jabref/gui/search/SearchResultFrame.java b/src/main/java/org/jabref/gui/search/SearchResultFrame.java index 59e9a8ccb6a..5be6cc368aa 100644 --- a/src/main/java/org/jabref/gui/search/SearchResultFrame.java +++ b/src/main/java/org/jabref/gui/search/SearchResultFrame.java @@ -2,7 +2,6 @@ import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; @@ -41,7 +40,6 @@ import org.jabref.gui.GUIGlobals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.PreviewPanel; -import org.jabref.gui.TransferableBibtexEntry; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.externalfiletype.ExternalFileMenuItem; @@ -219,10 +217,11 @@ public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent e) { if (!selectionModel.getSelected().isEmpty()) { List bes = selectionModel.getSelected(); - TransferableBibtexEntry trbe = new TransferableBibtexEntry(bes); - // ! look at ClipBoardManager - Toolkit.getDefaultToolkit().getSystemClipboard() - .setContents(trbe, frame.getCurrentBasePanel()); + try { + Globals.clipboardManager.setContent(bes); + } catch (IOException e1) { + LOGGER.error("Error while serializing entries for clipboard", e1); + } frame.output(Localization.lang("Copied") + ' ' + (bes.size() > 1 ? bes.size() + " " + Localization.lang("entries") : "1 " + Localization.lang("entry") + '.')); diff --git a/src/main/java/org/jabref/gui/worker/CitationStyleToClipboardWorker.java b/src/main/java/org/jabref/gui/worker/CitationStyleToClipboardWorker.java index b685a1cf081..73fe46be70d 100644 --- a/src/main/java/org/jabref/gui/worker/CitationStyleToClipboardWorker.java +++ b/src/main/java/org/jabref/gui/worker/CitationStyleToClipboardWorker.java @@ -1,7 +1,5 @@ package org.jabref.gui.worker; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -9,12 +7,11 @@ import javax.swing.SwingWorker; +import javafx.scene.input.ClipboardContent; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.ClipBoardManager; -import org.jabref.gui.exporter.RtfTransferable; -import org.jabref.gui.fieldeditors.HtmlTransferable; -import org.jabref.gui.fieldeditors.XmlTransferable; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; @@ -81,75 +78,39 @@ protected List doInBackground() throws Exception { } } - @Override - public void done() { - try { - List citations = get(); - - // if it's not a citation style take care of the preview - if (!CitationStyle.isCitationStyleFile(style)) { - new ClipBoardManager().setTransferableClipboardContents(processPreview(citations)); - } else { - // if it's generated by a citation style take care of each output format - Transferable transferable; - switch (outputFormat) { - case HTML: - transferable = processHtml(citations); - break; - case RTF: - transferable = processRtf(citations); - break; - case XSL_FO: - transferable = processXslFo(citations); - break; - case ASCII_DOC: - case TEXT: - transferable = processText(citations); - break; - default: - LOGGER.warn("unknown output format: '" + outputFormat + "', processing it via the default."); - transferable = processText(citations); - break; - } - new ClipBoardManager().setTransferableClipboardContents(transferable); - } - - basePanel.frame().setStatus(Localization.lang("Copied %0 citations.", String.valueOf(selectedEntries.size()))); - } catch (InterruptedException | ExecutionException e) { - LOGGER.error("Error while copying citations to the clipboard", e); - } - } - /** * Generates a plain text string out of the preview and copies it additionally to the html to the clipboard * (WYSIWYG Editors use the HTML, plain text editors the text) */ - protected static HtmlTransferable processPreview(List citations) { - String html = String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations); - return new HtmlTransferable(html); + protected static String processPreview(List citations) { + return String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations); } /** * Joins every citation with a newline and returns it. */ - protected static StringSelection processText(List citations) { - return new StringSelection(String.join(CitationStyleOutputFormat.TEXT.getLineSeparator(), citations)); + protected static ClipboardContent processText(List citations) { + ClipboardContent content = new ClipboardContent(); + content.putString(String.join(CitationStyleOutputFormat.TEXT.getLineSeparator(), citations)); + return content; } /** * Converts the citations into the RTF format. */ - protected static RtfTransferable processRtf(List citations) { + protected static ClipboardContent processRtf(List citations) { String result = "{\\rtf" + OS.NEWLINE + String.join(CitationStyleOutputFormat.RTF.getLineSeparator(), citations) + "}"; - return new RtfTransferable(result); + ClipboardContent content = new ClipboardContent(); + content.putRtf(result); + return content; } /** * Inserts each citation into a XLSFO body and copies it to the clipboard */ - protected static XmlTransferable processXslFo(List citations) { + protected static ClipboardContent processXslFo(List citations) { String result = "" + OS.NEWLINE + "" + OS.NEWLINE + " " + OS.NEWLINE + @@ -167,13 +128,15 @@ protected static XmlTransferable processXslFo(List citations) { " " + OS.NEWLINE + "" + OS.NEWLINE; - return new XmlTransferable(result); + ClipboardContent content = new ClipboardContent(); + content.put(ClipBoardManager.XML, result); + return content; } /** * Inserts each citation into a HTML body and copies it to the clipboard */ - protected static HtmlTransferable processHtml(List citations) { + protected static ClipboardContent processHtml(List citations) { String result = "" + OS.NEWLINE + "" + OS.NEWLINE + " " + OS.NEWLINE + @@ -187,6 +150,47 @@ protected static HtmlTransferable processHtml(List citations) { " " + OS.NEWLINE + "" + OS.NEWLINE; - return new HtmlTransferable(result); + ClipboardContent content = new ClipboardContent(); + content.putHtml(result); + return content; + } + + @Override + public void done() { + try { + List citations = get(); + + // if it's not a citation style take care of the preview + if (!CitationStyle.isCitationStyleFile(style)) { + Globals.clipboardManager.setHtmlContent(processPreview(citations)); + } else { + // if it's generated by a citation style take care of each output format + ClipboardContent content; + switch (outputFormat) { + case HTML: + content = processHtml(citations); + break; + case RTF: + content = processRtf(citations); + break; + case XSL_FO: + content = processXslFo(citations); + break; + case ASCII_DOC: + case TEXT: + content = processText(citations); + break; + default: + LOGGER.warn("unknown output format: '" + outputFormat + "', processing it via the default."); + content = processText(citations); + break; + } + Globals.clipboardManager.setContent(content); + } + + basePanel.frame().setStatus(Localization.lang("Copied %0 citations.", String.valueOf(selectedEntries.size()))); + } catch (InterruptedException | ExecutionException e) { + LOGGER.error("Error while copying citations to the clipboard", e); + } } } diff --git a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java b/src/test/java/org/jabref/gui/ClipBoardManagerTest.java deleted file mode 100644 index 04dbd054056..00000000000 --- a/src/test/java/org/jabref/gui/ClipBoardManagerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.jabref.gui; - -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.util.Arrays; -import java.util.List; - -import org.jabref.logic.importer.ImportException; -import org.jabref.logic.importer.ImportFormatReader; -import org.jabref.logic.importer.ImportFormatReader.UnknownFormatImport; -import org.jabref.logic.importer.ParserResult; -import org.jabref.model.entry.BibEntry; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ClipBoardManagerTest { - - private ClipBoardManager clipBoardManager; - private Transferable content; - private ImportFormatReader importFormatReader; - - @BeforeEach - public void setUp() throws Exception { - importFormatReader = mock(ImportFormatReader.class); - - Clipboard clipboard = mock(Clipboard.class); - clipBoardManager = new ClipBoardManager(clipboard, importFormatReader); - content = mock(Transferable.class); - when(clipboard.getContents(ArgumentMatchers.any())).thenReturn(content); - } - - @Test - public void extractBibEntriesFromClipboardParsesStringFlavor() throws Exception { - BibEntry expected = new BibEntry(); - expected.setType("article"); - expected.setCiteKey("canh05"); - expected.setField("author", "Crowston, K. and Annabi, H."); - expected.setField("title", "Title A"); - - when(content.isDataFlavorSupported(TransferableBibtexEntry.ENTRY_FLAVOR)).thenReturn(false); - when(content.isDataFlavorSupported(DataFlavor.stringFlavor)).thenReturn(true); - String data = "@article{canh05, author = {Crowston, K. and Annabi, H.},\n" + " title = {Title A}}\n"; - when(content.getTransferData(DataFlavor.stringFlavor)).thenReturn(data); - when(importFormatReader.importUnknownFormat(data)).thenReturn(new UnknownFormatImport("abc", new ParserResult(Arrays.asList(expected)))); - - List actual = clipBoardManager.extractBibEntriesFromClipboard(); - - assertEquals(Arrays.asList(expected), actual); - } - - @Test - public void extractBibEntriesFromClipboardReturnsEmptyIfStringparsingFailed() throws Exception { - when(content.isDataFlavorSupported(TransferableBibtexEntry.ENTRY_FLAVOR)).thenReturn(false); - when(content.isDataFlavorSupported(DataFlavor.stringFlavor)).thenReturn(true); - when(content.getTransferData(DataFlavor.stringFlavor)).thenReturn("testData"); - when(importFormatReader.importUnknownFormat("testData")).thenThrow(new ImportException("")); - - List actual = clipBoardManager.extractBibEntriesFromClipboard(); - - assertEquals(Arrays.asList(), actual); - } - -} diff --git a/src/test/java/org/jabref/gui/fieldeditors/HtmlTransferableTest.java b/src/test/java/org/jabref/gui/fieldeditors/HtmlTransferableTest.java deleted file mode 100644 index 0577cc73e7f..00000000000 --- a/src/test/java/org/jabref/gui/fieldeditors/HtmlTransferableTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.datatransfer.DataFlavor; - -import org.jabref.logic.util.OS; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class HtmlTransferableTest { - - @Test - public void testSimpleDivConstruct() throws Exception { - String html = "
" + OS.NEWLINE + - "
Text
" + OS.NEWLINE + - "
" + OS.NEWLINE; - HtmlTransferable htmlTransferable = new HtmlTransferable(html); - assertEquals("Text", htmlTransferable.getTransferData(DataFlavor.stringFlavor)); - } - - @Test - public void testAdvancedDivConstruct() throws Exception { - String html = "" + OS.NEWLINE + - "" + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - OS.NEWLINE + - "
" + OS.NEWLINE + - "
Content 1
" + OS.NEWLINE + - "
" + OS.NEWLINE + - OS.NEWLINE + - "
" + OS.NEWLINE + - "
" + OS.NEWLINE + - "
Content 2
" + OS.NEWLINE + - "
" + OS.NEWLINE + - OS.NEWLINE + - " " + OS.NEWLINE + - "" + OS.NEWLINE; - String expected = "Content 1" + OS.NEWLINE + "Content 2"; - HtmlTransferable htmlTransferable = new HtmlTransferable(html); - assertEquals(expected, htmlTransferable.getTransferData(DataFlavor.stringFlavor)); - } - - @Test - public void testGenerateMagicSpaces() throws Exception { - String html = "" + OS.NEWLINE + - "" + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - OS.NEWLINE + - "
" + OS.NEWLINE + - "
number1
Content 1
" + OS.NEWLINE + - "
" + OS.NEWLINE + - OS.NEWLINE + - "
" + OS.NEWLINE + - "
" + OS.NEWLINE + - "
number2
Content 2
" + OS.NEWLINE + - "
" + OS.NEWLINE + - OS.NEWLINE + - " " + OS.NEWLINE + - "" + OS.NEWLINE; - String expected = "number1 Content 1" + OS.NEWLINE + "number2 Content 2"; - HtmlTransferable htmlTransferable = new HtmlTransferable(html); - assertEquals(expected, htmlTransferable.getTransferData(DataFlavor.stringFlavor)); - } - - @Test - public void testAmpersandConversion() throws Exception { - String html = "" + OS.NEWLINE + - "" + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - " " + OS.NEWLINE + - OS.NEWLINE + - "
Let's rock & have fun" + OS.NEWLINE + - "
" + OS.NEWLINE + - OS.NEWLINE + - " " + OS.NEWLINE + - "" + OS.NEWLINE; - String expected = "Let's rock & have fun"; - HtmlTransferable htmlTransferable = new HtmlTransferable(html); - assertEquals(expected, htmlTransferable.getTransferData(DataFlavor.stringFlavor)); - } - -} diff --git a/src/test/java/org/jabref/gui/worker/CitationStyleToClipboardWorkerTest.java b/src/test/java/org/jabref/gui/worker/CitationStyleToClipboardWorkerTest.java index 5b899af7beb..02e1121f570 100644 --- a/src/test/java/org/jabref/gui/worker/CitationStyleToClipboardWorkerTest.java +++ b/src/test/java/org/jabref/gui/worker/CitationStyleToClipboardWorkerTest.java @@ -1,24 +1,35 @@ package org.jabref.gui.worker; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; import java.util.Arrays; -import org.jabref.gui.exporter.RtfTransferable; -import org.jabref.gui.fieldeditors.HtmlTransferable; -import org.jabref.gui.fieldeditors.XmlTransferable; +import javafx.scene.input.ClipboardContent; + +import org.jabref.gui.ClipBoardManager; import org.jabref.logic.util.OS; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; -public class CitationStyleToClipboardWorkerTest { +class CitationStyleToClipboardWorkerTest { @Test - public void processPreviewText() throws Exception { - String expected = "Article (Smith2016)Smith, B.; Jones, B. & Williams, J.Taylor, P. (Ed.)Title of the test entry BibTeX Journal, JabRef Publishing, 2016, 34, 45-67 Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger." + OS.NEWLINE + - "Article (Smith2016)Smith, B.; Jones, B. & Williams, J.Taylor, P. (Ed.)Title of the test entry BibTeX Journal, JabRef Publishing, 2016, 34, 45-67 Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger."; + void processPreviewText() throws Exception { + String expected = "Article (Smith2016)" + OS.NEWLINE + + "Smith, B.; Jones, B. & Williams, J." + OS.NEWLINE + + "Taylor, P. (Ed.)" + OS.NEWLINE + + "Title of the test entry " + OS.NEWLINE + + "BibTeX Journal, JabRef Publishing, 2016, 34, 45-67 " + OS.NEWLINE + + "" + OS.NEWLINE + + "Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger. " + OS.NEWLINE + + "
" + OS.NEWLINE + + "Article (Smith2016)" + OS.NEWLINE + + "Smith, B.; Jones, B. & Williams, J." + OS.NEWLINE + + "Taylor, P. (Ed.)" + OS.NEWLINE + + "Title of the test entry " + OS.NEWLINE + + "BibTeX Journal, JabRef Publishing, 2016, 34, 45-67 " + OS.NEWLINE + + "" + OS.NEWLINE + + "Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger. "; String citation = "Article (Smith2016)" + OS.NEWLINE + "Smith, B.; Jones, B. & Williams, J." + OS.NEWLINE + @@ -28,14 +39,13 @@ public void processPreviewText() throws Exception { OS.NEWLINE + "Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger. "; - HtmlTransferable HtmlTransferable = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); + String actual = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); - Object actual = HtmlTransferable.getTransferData(DataFlavor.stringFlavor); assertEquals(expected, actual); } @Test - public void processPreviewHtml() throws Exception { + void processPreviewHtml() throws Exception { String expected = "Article (Smith2016)
" + OS.NEWLINE + " Smith, B.; Jones, B. & Williams, J.
" + OS.NEWLINE + " Taylor, P. (Ed.)
" + OS.NEWLINE + @@ -81,26 +91,25 @@ public void processPreviewHtml() throws Exception { "" + OS.NEWLINE + "

"; - HtmlTransferable transferable = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); + String actual = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); - Object actual = transferable.getTransferData(HtmlTransferable.HTML_FLAVOR); assertEquals(expected, actual); } @Test - public void processText() throws Exception { + void processText() throws Exception { String expected = "[1]B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016." + OS.NEWLINE + "[1]B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016." + OS.NEWLINE; String citation = "[1]B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016." + OS.NEWLINE; - StringSelection textTransferable = CitationStyleToClipboardWorker.processText(Arrays.asList(citation, citation)); + ClipboardContent textTransferable = CitationStyleToClipboardWorker.processText(Arrays.asList(citation, citation)); - Object actual = textTransferable.getTransferData(DataFlavor.stringFlavor); + String actual = textTransferable.getString(); assertEquals(expected, actual); } @Test - public void processRtf() throws Exception { + void processRtf() throws Exception { String expected = "{\\rtf" + OS.NEWLINE + "[1]\\tab B. Smith, B. Jones, and J. Williams, \\uc0\\u8220{}Title of the test entry,\\uc0\\u8221{} {\\i{}BibTeX Journal}, vol. 34, no. 3, pp. 45\\uc0\\u8211{}67, Jul. 2016." + OS.NEWLINE + "\\line" + OS.NEWLINE + @@ -108,14 +117,14 @@ public void processRtf() throws Exception { "}"; String citation = "[1]\\tab B. Smith, B. Jones, and J. Williams, \\uc0\\u8220{}Title of the test entry,\\uc0\\u8221{} {\\i{}BibTeX Journal}, vol. 34, no. 3, pp. 45\\uc0\\u8211{}67, Jul. 2016." + OS.NEWLINE; - RtfTransferable rtfTransferable = CitationStyleToClipboardWorker.processRtf(Arrays.asList(citation, citation)); + ClipboardContent content = CitationStyleToClipboardWorker.processRtf(Arrays.asList(citation, citation)); - Object actual = rtfTransferable.getTransferData(DataFlavor.stringFlavor); + Object actual = content.getRtf(); assertEquals(expected, actual); } @Test - public void processXslFo() throws Exception { + void processXslFo() throws Exception { String expected = "" + OS.NEWLINE + "" + OS.NEWLINE + " " + OS.NEWLINE + @@ -181,14 +190,14 @@ public void processXslFo() throws Exception { " " + OS.NEWLINE + "" + OS.NEWLINE; - XmlTransferable xmlTransferable = CitationStyleToClipboardWorker.processXslFo(Arrays.asList(citation, citation)); + ClipboardContent xmlTransferable = CitationStyleToClipboardWorker.processXslFo(Arrays.asList(citation, citation)); - Object actual = xmlTransferable.getTransferData(DataFlavor.stringFlavor); + Object actual = xmlTransferable.get(ClipBoardManager.XML); assertEquals(expected, actual); } @Test - public void processHtmlAsHtml() throws Exception { + void processHtmlAsHtml() throws Exception { String expected = "" + OS.NEWLINE + "" + OS.NEWLINE + " " + OS.NEWLINE + @@ -211,23 +220,9 @@ public void processHtmlAsHtml() throws Exception { String citation = "
" + OS.NEWLINE + "
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016.
" + OS.NEWLINE + "
" + OS.NEWLINE; - HtmlTransferable htmlTransferable = CitationStyleToClipboardWorker.processHtml(Arrays.asList(citation, citation)); - - Object actual = htmlTransferable.getTransferData(DataFlavor.allHtmlFlavor); - assertEquals(expected, actual); - } - - @Test - public void processHtmlAsText() throws Exception { - String expected = "[1] B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal , vol. 34, no. 3, pp. 45–67, Jul. 2016." + OS.NEWLINE + - "[1] B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal , vol. 34, no. 3, pp. 45–67, Jul. 2016."; - - String citation = "
" + OS.NEWLINE + - "
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016.
" + OS.NEWLINE + - "
" + OS.NEWLINE; - HtmlTransferable htmlTransferable = CitationStyleToClipboardWorker.processHtml(Arrays.asList(citation, citation)); + ClipboardContent htmlTransferable = CitationStyleToClipboardWorker.processHtml(Arrays.asList(citation, citation)); - Object actual = htmlTransferable.getTransferData(DataFlavor.stringFlavor); + Object actual = htmlTransferable.getHtml(); assertEquals(expected, actual); } } From 78676fa238147e1cf33faf2ef6f05419692fde0d Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 15:57:17 +0200 Subject: [PATCH 04/22] Properly shutdown JabRef (not with System.exit) --- src/main/java/org/jabref/Globals.java | 6 +++--- src/main/java/org/jabref/JabRefMain.java | 13 +++---------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/Globals.java b/src/main/java/org/jabref/Globals.java index 4cc1cef90b6..ffa77408a3b 100644 --- a/src/main/java/org/jabref/Globals.java +++ b/src/main/java/org/jabref/Globals.java @@ -1,10 +1,11 @@ package org.jabref; import java.awt.GraphicsEnvironment; -import java.awt.Toolkit; import java.util.Optional; import java.util.UUID; +import javafx.stage.Screen; + import org.jabref.gui.ClipBoardManager; import org.jabref.gui.GlobalFocusListener; import org.jabref.gui.StateManager; @@ -107,8 +108,7 @@ private static void startTelemetryClient() { telemetryClient.getContext().getSession().setId(UUID.randomUUID().toString()); telemetryClient.getContext().getDevice().setOperatingSystem(StandardSystemProperty.OS_NAME.value()); telemetryClient.getContext().getDevice().setOperatingSystemVersion(StandardSystemProperty.OS_VERSION.value()); - telemetryClient.getContext().getDevice().setScreenResolution( - Toolkit.getDefaultToolkit().getScreenSize().toString()); + telemetryClient.getContext().getDevice().setScreenResolution(Screen.getPrimary().getVisualBounds().toString()); telemetryClient.trackSessionState(SessionState.Start); } diff --git a/src/main/java/org/jabref/JabRefMain.java b/src/main/java/org/jabref/JabRefMain.java index fd4ffda4dde..72901437243 100644 --- a/src/main/java/org/jabref/JabRefMain.java +++ b/src/main/java/org/jabref/JabRefMain.java @@ -67,7 +67,7 @@ public void start(Stage mainStage) throws Exception { // Check for running JabRef if (!handleMultipleAppInstances(arguments) || argumentProcessor.shouldShutDown()) { - shutdownCurrentInstance(); + Platform.exit(); return; } @@ -77,8 +77,8 @@ public void start(Stage mainStage) throws Exception { @Override public void stop() { - Platform.exit(); - System.exit(0); + Globals.stopBackgroundTasks(); + Globals.shutdownThreadPools(); } /** @@ -145,13 +145,6 @@ private static boolean handleMultipleAppInstances(String[] args) { return true; } - private static void shutdownCurrentInstance() { - Globals.stopBackgroundTasks(); - Globals.shutdownThreadPools(); - Platform.exit(); - System.exit(0); - } - private static void applyPreferences(JabRefPreferences preferences) { // Update handling of special fields based on preferences InternalBibtexFields.updateSpecialFields(Globals.prefs.getBoolean(JabRefPreferences.SERIALIZESPECIALFIELDS)); From 7416369e4748b77b9e67fcab172f64b0e25fb5b6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 16:22:38 +0200 Subject: [PATCH 05/22] Remove Swing stuff (L&F, font customization) --- src/main/java/org/jabref/JabRefGUI.java | 54 +------- src/main/java/org/jabref/gui/GUIGlobals.java | 6 +- src/main/java/org/jabref/gui/JabRefFrame.java | 57 ++------ .../gui/fieldeditors/LinkedFilesEditor.java | 1 - .../org/jabref/gui/groups/GroupTreeView.java | 2 - .../java/org/jabref/gui/icon/IconTheme.java | 4 +- .../gui/icon/InternalMaterialDesignIcon.java | 3 +- .../gui/importer/ImportInspectionDialog.java | 2 +- .../gui/preftabs/AppearancePrefsTab.java | 129 +----------------- .../jabref/gui/search/GlobalSearchBar.java | 4 - .../jabref/preferences/JabRefPreferences.java | 26 +--- 11 files changed, 26 insertions(+), 262 deletions(-) diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index fbde85a059f..edf51c98ef1 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -1,19 +1,11 @@ package org.jabref; -import java.awt.Font; import java.io.File; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; import java.util.Iterator; import java.util.List; -import javax.swing.UIDefaults; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; -import javax.swing.plaf.FontUIResource; - import javafx.scene.Scene; import javafx.stage.Stage; @@ -34,7 +26,6 @@ import org.jabref.logic.l10n.Localization; import org.jabref.logic.shared.exception.InvalidDBMSConnectionPropertiesException; import org.jabref.logic.shared.exception.NotASharedDatabaseException; -import org.jabref.logic.util.OS; import org.jabref.logic.util.Version; import org.jabref.model.database.shared.DatabaseNotSupportedException; import org.jabref.preferences.JabRefPreferences; @@ -242,46 +233,11 @@ private boolean isLoaded(File fileToOpen) { } private void setLookAndFeel() { - try { - - if (OS.WINDOWS) { - UIManager.setLookAndFeel(WINDOWS_LOOK_AND_FEEL); - } - if (OS.OS_X) { - UIManager.setLookAndFeel(OSX_AQUA_LOOk_AND_FEEL); - } else { - UIManager.setLookAndFeel(NIMBUS_LOOK_AND_FEEL); - } - // On Linux, Java FX fonts look blurry per default. This can be improved by using a non-default rendering - // setting. See https://github.com/woky/javafx-hates-linux - if (Globals.prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK)) { - System.setProperty("prism.text", "t2k"); - System.setProperty("prism.lcdtext", "true"); - } - } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { - try { - LOGGER.warn("Setting Look and Feel to Nimbus", e); - - UIManager.setLookAndFeel(NIMBUS_LOOK_AND_FEEL); - } catch (Exception ex) { - LOGGER.warn("Look and feel could not be set", e); - } - - } - - // In JabRef v2.8, we did it only on NON-Mac. Now, we try on all platforms - boolean overrideDefaultFonts = Globals.prefs.getBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONTS); - if (overrideDefaultFonts) { - int fontSize = Globals.prefs.getInt(JabRefPreferences.MENU_FONT_SIZE); - UIDefaults defaults = UIManager.getDefaults(); - Enumeration keys = defaults.keys(); - for (Object key : Collections.list(keys)) { - if ((key instanceof String) && ((String) key).endsWith(".font")) { - Font font = (Font) UIManager.get(key); - font = new FontUIResource(font.getName(), font.getStyle(), fontSize); - defaults.put(key, font); - } - } + // On Linux, Java FX fonts look blurry per default. This can be improved by using a non-default rendering + // setting. See https://github.com/woky/javafx-hates-linux + if (Globals.prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK)) { + System.setProperty("prism.text", "t2k"); + System.setProperty("prism.lcdtext", "true"); } } diff --git a/src/main/java/org/jabref/gui/GUIGlobals.java b/src/main/java/org/jabref/gui/GUIGlobals.java index cbfeb8dc34d..153018119e8 100644 --- a/src/main/java/org/jabref/gui/GUIGlobals.java +++ b/src/main/java/org/jabref/gui/GUIGlobals.java @@ -20,12 +20,10 @@ public class GUIGlobals { public static Color activeBackgroundColor; public static Color invalidFieldBackgroundColor; public static Font currentFont; - public static final Color NULL_FIELD_COLOR = new Color(75, 130, 95); // Valid field, green. - public static final Color ACTIVE_EDITOR_COLOR = new Color(230, 230, 255); - public static final int WIDTH_ICON_COL = JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_SMALL) + 12; // add some additional space to improve appearance + public static final int WIDTH_ICON_COL = 16 + 12; // add some additional space to improve appearance - public static final int WIDTH_ICON_COL_RANKING = 5 * JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_SMALL); // Width of Ranking Icon Column + public static final int WIDTH_ICON_COL_RANKING = 5 * 16; // Width of Ranking Icon Column public static final String UNTITLED_TITLE = Localization.lang("untitled"); diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 381966df1e1..a06872e4046 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -1,8 +1,6 @@ package org.jabref.gui; import java.awt.Component; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Window; import java.awt.event.ActionEvent; @@ -21,11 +19,8 @@ import javax.swing.Action; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; @@ -38,8 +33,10 @@ import javafx.scene.control.Button; import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; +import javafx.scene.control.ProgressBar; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SplitPane; import javafx.scene.control.Tab; @@ -152,12 +149,9 @@ public class JabRefFrame extends BorderPane implements OutputPrinter { private final SplitPane splitPane = new SplitPane(); private final JabRefPreferences prefs = Globals.prefs; private final GlobalSearchBar globalSearchBar = new GlobalSearchBar(this); - private final JLabel statusLine = new JLabel("", SwingConstants.LEFT); - private final JLabel statusLabel = new JLabel( - Localization.lang("Status") - + ':', - SwingConstants.LEFT); - private final JProgressBar progressBar = new JProgressBar(); + private final Label statusLine = new Label(""); + private final Label statusLabel = new Label(Localization.lang("Status") + ':'); + private final ProgressBar progressBar = new ProgressBar(); private final FileHistoryMenu fileHistory = new FileHistoryMenu(prefs, this); // Lists containing different subsets of actions for different purposes @@ -539,6 +533,7 @@ public void changed(ObservableValue observable, Boolean oldVa UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); + /* GridBagLayout gbl = new GridBagLayout(); GridBagConstraints con = new GridBagConstraints(); con.fill = GridBagConstraints.BOTH; @@ -562,6 +557,7 @@ public void changed(ObservableValue observable, Boolean oldVa gbl.setConstraints(progressBar, con); status.add(progressBar); statusLabel.setForeground(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR.darker()); + */ } private void setDividerPosition() { @@ -1005,10 +1001,7 @@ public void addParserResult(ParserResult pr, boolean focusPanel) { * displays the String on the Status Line visible on the bottom of the JabRef mainframe */ public void output(final String s) { - SwingUtilities.invokeLater(() -> { statusLine.setText(s); - statusLine.repaint(); - }); } private void initActions() { @@ -1246,21 +1239,6 @@ public void setProgressBarVisible(final boolean visible) { } } - /** - * Sets the current value of the progress bar. - *

- * If not called on the event dispatch thread, this method uses - * SwingUtilities.invokeLater() to do the actual operation on the EDT. - */ - public void setProgressBarValue(final int value) { - if (SwingUtilities.isEventDispatchThread()) { - progressBar.setValue(value); - } else { - SwingUtilities.invokeLater(() -> progressBar.setValue(value)); - } - - } - /** * Sets the indeterminate status of the progress bar. *

@@ -1268,29 +1246,14 @@ public void setProgressBarValue(final int value) { * SwingUtilities.invokeLater() to do the actual operation on the EDT. */ public void setProgressBarIndeterminate(final boolean value) { + // TODO: Reimplement + /* if (SwingUtilities.isEventDispatchThread()) { progressBar.setIndeterminate(value); } else { SwingUtilities.invokeLater(() -> progressBar.setIndeterminate(value)); } - - } - - /** - * Sets the maximum value of the progress bar. Always call this method - * before using the progress bar, to set a maximum value appropriate to - * the task at hand. - *

- * If not called on the event dispatch thread, this method uses - * SwingUtilities.invokeLater() to do the actual operation on the EDT. - */ - public void setProgressBarMaximum(final int value) { - if (SwingUtilities.isEventDispatchThread()) { - progressBar.setMaximum(value); - } else { - SwingUtilities.invokeLater(() -> progressBar.setMaximum(value)); - } - + */ } /** diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java index ca936caa1a7..2758f5583cd 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java @@ -238,7 +238,6 @@ private void addFromURL(ActionEvent event) { private ContextMenu createContextMenuForFile(LinkedFileViewModel linkedFile) { ContextMenu menu = new ContextMenu(); - menu.setStyle("-fx-font-size: " + Globals.prefs.getFontSizeFX() + "pt;"); MenuItem edit = new MenuItem(Localization.lang("Edit")); edit.setOnAction(event -> linkedFile.edit()); diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeView.java b/src/main/java/org/jabref/gui/groups/GroupTreeView.java index 72fbec509d5..c9aa5081e43 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeView.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeView.java @@ -32,7 +32,6 @@ import javafx.scene.layout.StackPane; import javafx.scene.text.Text; -import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.DragAndDropDataFormats; import org.jabref.gui.StateManager; @@ -77,7 +76,6 @@ public void initialize() { viewModel = new GroupTreeViewModel(stateManager, dialogService, taskExecutor); // Set-up groups tree - groupTree.setStyle("-fx-font-size: " + Globals.prefs.getFontSizeFX() + "pt;"); groupTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); // Set-up bindings diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index 20f7a7f1803..73dcd876c75 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -383,7 +383,7 @@ public static class FontBasedIcon implements Icon { public FontBasedIcon(String code, Color iconColor) { this.iconCode = code; this.iconColor = iconColor; - this.size = JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_LARGE); + this.size = 24; } public FontBasedIcon(String code, Color iconColor, int size) { @@ -426,7 +426,7 @@ public FontBasedIcon createDisabledIcon() { } public FontBasedIcon createSmallIcon() { - return new FontBasedIcon(this.iconCode, this.iconColor, JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_SMALL)); + return new FontBasedIcon(this.iconCode, this.iconColor, 16); } public FontBasedIcon createWithNewColor(Color newColor) { diff --git a/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java b/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java index b2837e0169c..6eb64b8fc4a 100644 --- a/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java +++ b/src/main/java/org/jabref/gui/icon/InternalMaterialDesignIcon.java @@ -12,7 +12,6 @@ import javafx.scene.text.Text; import org.jabref.gui.util.ColorUtil; -import org.jabref.preferences.JabRefPreferences; import de.jensd.fx.glyphs.GlyphIcons; @@ -51,7 +50,7 @@ public Icon getIcon() { @Override public Icon getSmallIcon() { - return new IconTheme.FontBasedIcon(this.unicode, ColorUtil.toAWT(this.color.orElse(IconTheme.getDefaultColor())), JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_SMALL)); + return new IconTheme.FontBasedIcon(this.unicode, ColorUtil.toAWT(this.color.orElse(IconTheme.getDefaultColor()))); } @Override diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 222d7990fc1..3366019169c 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -1346,7 +1346,7 @@ public EntryTable(TableModel model) { getTableHeader().setReorderingAllowed(false); setFont(GUIGlobals.currentFont); - int maxOfIconsAndFontSize = Math.max(GUIGlobals.currentFont.getSize(), Globals.prefs.getInt(JabRefPreferences.ICON_SIZE_SMALL)); + int maxOfIconsAndFontSize = GUIGlobals.currentFont.getSize(); setRowHeight(maxOfIconsAndFontSize); // Update Table header with new settings this.getTableHeader().resizeAndRepaint(); diff --git a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java index d70bd20303e..46e4879f5aa 100644 --- a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java @@ -6,9 +6,7 @@ import javax.swing.BorderFactory; import javax.swing.JCheckBox; -import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JTextField; import org.jabref.gui.DialogService; import org.jabref.gui.GUIGlobals; @@ -16,7 +14,6 @@ import org.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.builder.FormBuilder; import com.jgoodies.forms.layout.FormLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,15 +24,7 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final JCheckBox overrideFonts; private final Font usedFont = GUIGlobals.currentFont; - private int oldMenuFontSize; - private int oldSmallIconSize; - private int oldLargeIconSize; - private boolean oldOverrideFontSize; - private final JTextField fontSize; - private final JTextField largeIconsTextField; - private final JTextField smallIconsTextField; private final JCheckBox fxFontTweaksLAF; private final DialogService dialogService; @@ -50,15 +39,6 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) this.prefs = prefs; setLayout(new BorderLayout()); - // Font sizes: - fontSize = new JTextField(5); - - // Icon sizes: - largeIconsTextField = new JTextField(5); - smallIconsTextField = new JTextField(5); - - overrideFonts = new JCheckBox(Localization.lang("Override default font settings")); - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, fill:pref", ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); @@ -72,35 +52,6 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) builder.leadingColumnOffset(2); - // General appearance settings - builder.appendSeparator(Localization.lang("General")); - - FormBuilder generalBuilder = FormBuilder.create(); - JPanel generalPanel = generalBuilder.columns("left:pref, left:pref, 3dlu, pref, 7dlu, right:pref, 3dlu, pref") - .rows("pref, 3dlu, pref, 3dlu, pref") - .columnGroup(2, 6) - .columnGroup(4, 8) - .add(overrideFonts) - .xyw(1, 1, 5) - .add(new JLabel(" ")) - .xy(1, 3) - .add(new JLabel(Localization.lang("Menu and label font size") + ":")) - .xy(2, 3) - .add(fontSize) - .xy(4, 3) - .add(new JLabel(Localization.lang("Size of large icons") + ":")) - .xy(2, 5) - .add(largeIconsTextField) - .xy(4, 5) - .add(new JLabel(Localization.lang("Size of small icons") + ":")) - .xy(6, 5) - .add(smallIconsTextField) - .xy(8, 5) - .build(); - - builder.append(generalPanel); - builder.nextLine(); - JPanel upper = new JPanel(); JPanel sort = new JPanel(); JPanel namesp = new JPanel(); @@ -111,10 +62,6 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) namesp.setLayout(gbl); iconCol.setLayout(gbl); - overrideFonts.addActionListener(e -> fontSize.setEnabled(overrideFonts.isSelected())); - overrideFonts.addActionListener(e -> largeIconsTextField.setEnabled(overrideFonts.isSelected())); - overrideFonts.addActionListener(e -> smallIconsTextField.setEnabled(overrideFonts.isSelected())); - JPanel pan = builder.getPanel(); pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(pan, BorderLayout.CENTER); @@ -122,23 +69,7 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) @Override public void setValues() { - // L&F - fxFontTweaksLAF.setSelected(prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK)); - - oldOverrideFontSize = prefs.getBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONTS); - oldMenuFontSize = prefs.getInt(JabRefPreferences.MENU_FONT_SIZE); - oldLargeIconSize = prefs.getInt(JabRefPreferences.ICON_SIZE_LARGE); - oldSmallIconSize = prefs.getInt(JabRefPreferences.ICON_SIZE_SMALL); - - overrideFonts.setSelected(oldOverrideFontSize); - fontSize.setText(String.valueOf(oldMenuFontSize)); - smallIconsTextField.setText(String.valueOf(oldSmallIconSize)); - largeIconsTextField.setText(String.valueOf(oldLargeIconSize)); - - fontSize.setEnabled(overrideFonts.isSelected()); - smallIconsTextField.setEnabled(overrideFonts.isSelected()); - largeIconsTextField.setEnabled(overrideFonts.isSelected()); } @Override @@ -153,69 +84,17 @@ public void storeSettings() { prefs.put(JabRefPreferences.FONT_FAMILY, usedFont.getFamily()); prefs.putInt(JabRefPreferences.FONT_STYLE, usedFont.getStyle()); prefs.putInt(JabRefPreferences.FONT_SIZE, usedFont.getSize()); - prefs.putBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONTS, overrideFonts.isSelected()); GUIGlobals.currentFont = usedFont; - try { - int size = Integer.parseInt(fontSize.getText()); - int smallIconSize = Integer.parseInt(smallIconsTextField.getText()); - int largeIconSize = Integer.parseInt(largeIconsTextField.getText()); - if (overrideFonts.isSelected()) { - if (size != oldMenuFontSize) { - prefs.putInt(JabRefPreferences.MENU_FONT_SIZE, size); - isRestartRequired = true; - } - if (smallIconSize != oldSmallIconSize) { - prefs.putInt(JabRefPreferences.ICON_SIZE_SMALL, smallIconSize); - isRestartRequired = true; - } - if (largeIconSize != oldLargeIconSize) { - prefs.putInt(JabRefPreferences.ICON_SIZE_LARGE, largeIconSize); - isRestartRequired = true; - } - } else if (overrideFonts.isSelected() != oldOverrideFontSize) { - prefs.remove(JabRefPreferences.ICON_SIZE_SMALL); - prefs.remove(JabRefPreferences.ICON_SIZE_LARGE); - prefs.remove(JabRefPreferences.MENU_FONT_SIZE); - isRestartRequired = true; - } - - if (isRestartRequired) { - dialogService.showWarningDialogAndWait(Localization.lang("Settings"), - Localization.lang("Some appearance settings you changed require to restart JabRef to come into effect.")); - } - } catch (NumberFormatException ex) { - // should not happen as values are checked beforehand - LOGGER.error("Invalid data value, integer expected", ex); - } - } - - private boolean validateIntegerField(String fieldName, String fieldValue, String errorTitle) { - try { - // Test if the field value is a number: - Integer.parseInt(fieldValue); - } catch (NumberFormatException ex) { - dialogService.showErrorDialogAndWait(errorTitle, Localization.lang("You must enter an integer value in the text field for") + " '" + fieldName + "'"); - return false; + if (isRestartRequired) { + dialogService.showWarningDialogAndWait(Localization.lang("Settings"), + Localization.lang("Some appearance settings you changed require to restart JabRef to come into effect.")); } - return true; } @Override public boolean validateSettings() { - // Test if font size is a number: - if (!validateIntegerField(Localization.lang("Menu and label font size"), fontSize.getText(), - Localization.lang("Invalid setting"))) { - return false; - } - - if (!validateIntegerField(Localization.lang("Size of large icons"), largeIconsTextField.getText(), - Localization.lang("Invalid setting"))) { - return false; - } - - return validateIntegerField(Localization.lang("Size of small icons"), smallIconsTextField.getText(), - Localization.lang("Invalid setting")); + return true; } @Override diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 051583b948b..04fc40e2bdc 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -7,8 +7,6 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.swing.JLabel; - import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; @@ -91,8 +89,6 @@ public class GlobalSearchBar extends HBox { private SearchDisplayMode searchDisplayMode; - private final JLabel searchIcon = new JLabel(IconTheme.JabRefIcons.SEARCH.getIcon()); - /** * if this flag is set the searchbar won't be selected after the next search */ diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 3f62361f1d3..107852e391a 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -214,12 +214,8 @@ public class JabRefPreferences implements PreferencesService { public static final String VALID_FIELD_BACKGROUND_COLOR = "validFieldBackgroundColor"; public static final String ICON_ENABLED_COLOR = "iconEnabledColor"; public static final String ICON_DISABLED_COLOR = "iconDisabledColor"; - public static final String MENU_FONT_SIZE = "menuFontSize"; - public static final String OVERRIDE_DEFAULT_FONTS = "overrideDefaultFonts"; public static final String FONT_SIZE = "fontSize"; public static final String FONT_STYLE = "fontStyle"; - public static final String ICON_SIZE_LARGE = "iconSizeLarge"; - public static final String ICON_SIZE_SMALL = "iconSizeSmall"; public static final String RECENT_DATABASES = "recentDatabases"; public static final String RENAME_ON_MOVE_FILE_TO_FILE_DIR = "renameOnMoveFileToFileDir"; public static final String MEMORY_STICK_MODE = "memoryStickMode"; @@ -405,8 +401,6 @@ public class JabRefPreferences implements PreferencesService { // Helper string private static final String USER_HOME = System.getProperty("user.home"); - // solves the issue java.lang.RuntimeException: Internal graphics not initialized yet - private final static Integer UNSET_MENU_FONT_SIZE = -123; // The only instance of this class: private static JabRefPreferences singleton; /** @@ -601,10 +595,6 @@ private JabRefPreferences() { defaults.put(FONT_STYLE, Font.PLAIN); defaults.put(FONT_SIZE, 12); - defaults.put(OVERRIDE_DEFAULT_FONTS, Boolean.FALSE); - defaults.put(MENU_FONT_SIZE, UNSET_MENU_FONT_SIZE); - defaults.put(ICON_SIZE_LARGE, 24); - defaults.put(ICON_SIZE_SMALL, 16); // Main table color settings: defaults.put(VALID_FIELD_BACKGROUND_COLOR, "255:255:255"); defaults.put(INVALID_FIELD_BACKGROUND_COLOR, "255:0:0"); @@ -926,11 +916,6 @@ public Map getSidePanePreferredPositions() { return preferredPositions; } - public int getFontSizeFX() { - // Decrease font size by 3 since JavaFX has default font size of 9, while Swing uses 12 - return getInt(MENU_FONT_SIZE) - 3; - } - public String getUser() { try { return get(DEFAULT_OWNER) + '-' + InetAddress.getLocalHost().getHostName(); @@ -1018,16 +1003,7 @@ public double getDouble(String key) { } public int getIntDefault(String key) { - if (key.equals(JabRefPreferences.MENU_FONT_SIZE)) { - Integer menuFontSize = (Integer) defaults.get(key); - if (menuFontSize.equals(UNSET_MENU_FONT_SIZE)) { - menuFontSize = (int) javafx.scene.text.Font.getDefault().getSize(); - defaults.put(key, menuFontSize); - } - return menuFontSize; - } else { - return (Integer) defaults.get(key); - } + return (Integer) defaults.get(key); } private double getDoubleDefault(String key) { From 330416700276aee798c2ae81ace393579b0c7209 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 16:27:07 +0200 Subject: [PATCH 06/22] Code cleanup --- .../java/org/jabref/gui/importer/fetcher/GeneralFetcher.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java index 487794ab9bb..84b76b67c30 100644 --- a/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java +++ b/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java @@ -57,10 +57,6 @@ public GeneralFetcher(SidePaneManager sidePaneManager, JabRefPreferences prefere this.preferences = preferences; } - private JTextField getTextField() { - return tf; - } - @Override public Action getToggleAction() { return StandardActions.TOGGLE_WEB_SEARCH; From 39e30cca85b79a4a1aa23a4742d06650203834a1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 21:06:16 +0200 Subject: [PATCH 07/22] Properly shutdown telemetry client --- src/main/java/org/jabref/Globals.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/Globals.java b/src/main/java/org/jabref/Globals.java index ffa77408a3b..6ce8e4274c0 100644 --- a/src/main/java/org/jabref/Globals.java +++ b/src/main/java/org/jabref/Globals.java @@ -26,6 +26,7 @@ import com.google.common.base.StandardSystemProperty; import com.microsoft.applicationinsights.TelemetryClient; import com.microsoft.applicationinsights.TelemetryConfiguration; +import com.microsoft.applicationinsights.internal.shutdown.SDKShutdownActivity; import com.microsoft.applicationinsights.telemetry.SessionState; public class Globals { @@ -91,10 +92,13 @@ public static void startBackgroundTasks() { } private static void stopTelemetryClient() { - if (Globals.prefs.shouldCollectTelemetry()) { - getTelemetryClient().ifPresent(client -> client.trackSessionState(SessionState.End)); - getTelemetryClient().ifPresent(client -> client.flush()); - } + getTelemetryClient().ifPresent(client -> { + client.trackSessionState(SessionState.End); + client.flush(); + + // Workaround for bug https://github.com/Microsoft/ApplicationInsights-Java/issues/662 + SDKShutdownActivity.INSTANCE.stopAll(); + }); } private static void startTelemetryClient() { From 2c0ed8f6a3370db035b6fc765ac1c9d6a71a4734 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 6 Jun 2018 21:12:43 +0200 Subject: [PATCH 08/22] Don't run on Swing thread --- src/main/java/org/jabref/gui/JabRefFrame.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index a06872e4046..ebf26264f6a 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -1,7 +1,6 @@ package org.jabref.gui; import java.awt.Component; -import java.awt.Insets; import java.awt.Window; import java.awt.event.ActionEvent; import java.io.File; @@ -22,7 +21,6 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javafx.application.Platform; import javafx.beans.value.ChangeListener; @@ -531,8 +529,6 @@ public void changed(ObservableValue observable, Boolean oldVa setCenter(splitPane); - UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); - /* GridBagLayout gbl = new GridBagLayout(); GridBagConstraints con = new GridBagConstraints(); @@ -1227,16 +1223,9 @@ public FileHistoryMenu getFileHistory() { /** * Set the visibility of the progress bar in the right end of the * status line at the bottom of the frame. - *

- * If not called on the event dispatch thread, this method uses - * SwingUtilities.invokeLater() to do the actual operation on the EDT. */ public void setProgressBarVisible(final boolean visible) { - if (SwingUtilities.isEventDispatchThread()) { - progressBar.setVisible(visible); - } else { - SwingUtilities.invokeLater(() -> progressBar.setVisible(visible)); - } + progressBar.setVisible(visible); } /** From db9e4e5a723165d19849d2a3f3baea3d3cdc68f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mu=C3=B1oz=20Ferrara?= Date: Tue, 12 Jun 2018 22:16:11 +0200 Subject: [PATCH 09/22] Opens the directory of the currently edited file when opening a new file (#4106) * Opens the directory of the currently edited file when opening a new file (resolves #4097) * Undone change on gradle-wrapper.properties * Undone change on gradle-wrapper.properties * Added description of the last modification to CHANGELOG.md * Improved use of optionals when selecting the path to open in the OpenDatabaseAction --- CHANGELOG.md | 1 + .../importer/actions/OpenDatabaseAction.java | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81eca4ec3b3..61515c0dcb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). +- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) diff --git a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java index 7658a7942dc..ef98593fc5a 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -92,7 +92,7 @@ public void execute() { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(StandardFileType.BIBTEX_DB) .withDefaultExtension(StandardFileType.BIBTEX_DB) - .withInitialDirectory(Paths.get(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY))) + .withInitialDirectory(getInitialDirectory()) .build(); List chosenFiles = ds.showFileOpenDialogAndGetMultipleFiles(fileDialogConfiguration); @@ -101,6 +101,23 @@ public void execute() { openFiles(filesToOpen, true); } + /** + * + * @return Path of current panel database directory or the working directory + */ + private Path getInitialDirectory() { + if (frame.getBasePanelCount() == 0) { + return getWorkingDirectoryPath(); + } else { + Optional databasePath = frame.getCurrentBasePanel().getBibDatabaseContext().getDatabasePath(); + return databasePath.map(p -> p.getParent()).orElse(getWorkingDirectoryPath()); + } + } + + private Path getWorkingDirectoryPath() { + return Paths.get(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)); + } + /** * Opens the given file. If null or 404, nothing happens * From 0ae726908601afb755bb858d5ec289c37e123f95 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 13 Jun 2018 08:23:36 +0200 Subject: [PATCH 10/22] Fix convert to bibtex moves contents of the file field (#4123) * Fix convert to bibtex moves contents of the file field Fixes #4210 * fix twisted numbers of issue --- CHANGELOG.md | 1 + .../java/org/jabref/model/entry/EntryConverter.java | 1 - .../logic/cleanup/ConvertToBibtexCleanupTest.java | 10 ++++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61515c0dcb2..68a7e0588ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 - We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. - Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) +- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) ### Removed diff --git a/src/main/java/org/jabref/model/entry/EntryConverter.java b/src/main/java/org/jabref/model/entry/EntryConverter.java index 131ef12bb1a..8a607b05647 100644 --- a/src/main/java/org/jabref/model/entry/EntryConverter.java +++ b/src/main/java/org/jabref/model/entry/EntryConverter.java @@ -25,7 +25,6 @@ public class EntryConverter { EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put("archiveprefix", FieldName.EPRINTTYPE); EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put(FieldName.JOURNAL, FieldName.JOURNALTITLE); EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put(FieldName.KEY, "sortkey"); - EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put(FieldName.PDF, FieldName.FILE); EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put("primaryclass", FieldName.EPRINTCLASS); EntryConverter.FIELD_ALIASES_TEX_TO_LTX.put(FieldName.SCHOOL, FieldName.INSTITUTION); diff --git a/src/test/java/org/jabref/logic/cleanup/ConvertToBibtexCleanupTest.java b/src/test/java/org/jabref/logic/cleanup/ConvertToBibtexCleanupTest.java index df46c7da884..08ab57eae9d 100644 --- a/src/test/java/org/jabref/logic/cleanup/ConvertToBibtexCleanupTest.java +++ b/src/test/java/org/jabref/logic/cleanup/ConvertToBibtexCleanupTest.java @@ -51,4 +51,14 @@ public void cleanupMovesJournaltitleToJournal() { assertEquals(Optional.empty(), entry.getField(FieldName.JOURNALTITLE)); assertEquals(Optional.of("Best of JabRef"), entry.getField(FieldName.JOURNAL)); } + + @Test + public void cleanUpDoesntMoveFileField() { + String fileField = ":Ambriola2006 - On the Systematic Analysis of Natural Language Requirements with CIRCE.pdf:PDF"; + BibEntry entry = new BibEntry().withField(FieldName.FILE, fileField); + + worker.cleanup(entry); + + assertEquals(Optional.of(fileField), entry.getField(FieldName.FILE)); + } } From 08b28a247f84056f6df6f70d1359f05132349e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mu=C3=B1oz=20Ferrara?= Date: Wed, 13 Jun 2018 08:28:50 +0200 Subject: [PATCH 11/22] Saves and reloads window state on close and on open (#4124) * Solved typo on OSX_AQUA_LOOK_AND_FEEL constant * Window state (pos, size, maximization) is saved on close and restored on start * Added message to CHANGELOG. --- CHANGELOG.md | 1 + src/main/java/org/jabref/JabRefGUI.java | 18 ++++++++++++++++-- .../jabref/preferences/JabRefPreferences.java | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a7e0588ae..3433dc2a581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). - 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 ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index fbde85a059f..04e25f904ff 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -46,7 +46,7 @@ public class JabRefGUI { private static final String NIMBUS_LOOK_AND_FEEL = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; private static final String WINDOWS_LOOK_AND_FEEL = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - private static final String OSX_AQUA_LOOk_AND_FEEL = "apple.laf.AquaLookAndFeel"; + private static final String OSX_AQUA_LOOK_AND_FEEL = "apple.laf.AquaLookAndFeel"; private static final Logger LOGGER = LoggerFactory.getLogger(JabRefGUI.class); @@ -155,6 +155,11 @@ private void openWindow(Stage mainStage) { // do it here: if (Globals.prefs.getBoolean(JabRefPreferences.WINDOW_MAXIMISED)) { mainStage.setMaximized(true); + } else { + mainStage.setX(Globals.prefs.getDouble(JabRefPreferences.POS_X)); + mainStage.setY(Globals.prefs.getDouble(JabRefPreferences.POS_Y)); + mainStage.setWidth(Globals.prefs.getDouble(JabRefPreferences.SIZE_X)); + mainStage.setHeight(Globals.prefs.getDouble(JabRefPreferences.SIZE_Y)); } Scene scene = new Scene(JabRefGUI.mainFrame, 800, 800); @@ -165,6 +170,7 @@ private void openWindow(Stage mainStage) { mainStage.show(); mainStage.setOnCloseRequest(event -> { + saveWindowState(mainStage); boolean reallyQuit = mainFrame.quit(); if (!reallyQuit) { event.consume(); @@ -203,6 +209,14 @@ private void openWindow(Stage mainStage) { LOGGER.debug("Finished adding panels"); } + private void saveWindowState(Stage mainStage) { + Globals.prefs.putBoolean(JabRefPreferences.WINDOW_MAXIMISED, mainStage.isMaximized()); + Globals.prefs.putDouble(JabRefPreferences.POS_X, mainStage.getX()); + Globals.prefs.putDouble(JabRefPreferences.POS_Y, mainStage.getY()); + Globals.prefs.putDouble(JabRefPreferences.SIZE_X, mainStage.getWidth()); + Globals.prefs.putDouble(JabRefPreferences.SIZE_Y, mainStage.getHeight()); + } + private void openLastEditedDatabases() { if (Globals.prefs.get(JabRefPreferences.LAST_EDITED) == null) { return; @@ -248,7 +262,7 @@ private void setLookAndFeel() { UIManager.setLookAndFeel(WINDOWS_LOOK_AND_FEEL); } if (OS.OS_X) { - UIManager.setLookAndFeel(OSX_AQUA_LOOk_AND_FEEL); + UIManager.setLookAndFeel(OSX_AQUA_LOOK_AND_FEEL); } else { UIManager.setLookAndFeel(NIMBUS_LOOK_AND_FEEL); } diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 3f62361f1d3..28bbd554926 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -501,7 +501,7 @@ private JabRefPreferences() { defaults.put(POS_Y, 0); defaults.put(SIZE_X, 1024); defaults.put(SIZE_Y, 768); - defaults.put(WINDOW_MAXIMISED, Boolean.FALSE); + defaults.put(WINDOW_MAXIMISED, Boolean.TRUE); defaults.put(AUTO_RESIZE_MODE, Boolean.TRUE); defaults.put(ENTRY_EDITOR_HEIGHT, 0.65); defaults.put(NAMES_AS_IS, Boolean.FALSE); // "Show names unchanged" From 4e50f63af0168a9def54a0aa178f83e476c5f304 Mon Sep 17 00:00:00 2001 From: Stefan Kolb Date: Wed, 13 Jun 2018 11:25:51 +0200 Subject: [PATCH 12/22] Extract v4.x changelog (#4125) --- CHANGELOG.md | 376 +++------------------------------------------------ 1 file changed, 19 insertions(+), 357 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3433dc2a581..3948b0df0ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,14 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - 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 + + + + + + + + ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) - Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 @@ -47,6 +55,14 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) + + + + + + + + ### Removed - The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. - The number column was removed. @@ -85,367 +101,13 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - - -## [4.3] - 2018-06-01 - -### Changed -- We changed the minimum required version of Java to 1.8.0_172, as 1.8.0_162 has introduced a CPU leak [3943](https://github.com/JabRef/jabref/issues/3943) -- We added a validity check for dates in the `date` and `urldate` fields. -- We added a text file export for 'Find Unlinked Files'. [#3341](https://github.com/JabRef/jabref/issues/3341) -- We added a fetcher based on RFC-IDs. [#3971](https://github.com/JabRef/jabref/issues/3971) -- We changed the implementation of the `[shorttitle]` key pattern. It now removes small words like `a`, `an`, `on`, `the` etc. Refer to the help page for a complete overview. [Feature request in the forum](http://discourse.jabref.org/t/jabref-differences-in-shorttitle-between-versions-3-8-1-and-4-not-discounting-the-a-an-of-in-titles/1147) -- We added a formatter for adding braces around the `title` field. E.g., `title = {ExamPle}` becomes `title = {{ExamPle}}`, which prevents BibTeX to convert it to lower case. You can use it at the [cleanup entries](http://help.jabref.org/en/CleanupEntries) functionality. -- We added a formatter to ensure correct en dashes in the `title` field. E.g., `title = {Example - illustrative}` becomes `title = {Example -- illustrative}`. -- We streamlined the defaults for a [cleanup of entries](http://help.jabref.org/en/CleanupEntries) in the case of BibTeX. -- The import inspection window now uses the same font size setting as the maintable [Feature request in the forum](http://discourse.jabref.org/t/inspection-window-and-others-line-height-of-table-too-small-for-fonts/1168) - -### Fixed -- We fixed an issue where the export to clipboard functionality could not be invoked. [#3994](https://github.com/JabRef/jabref/issues/3994) -- We fixed an issue with the migration of invalid Look and Feels. [#3995, comment](https://github.com/JabRef/jabref/issues/3995#issuecomment-385649448) -- We fixed an issue where JabRef would no longer start, when the option "Override default font settings" was activated. [#3986](https://github.com/JabRef/jabref/issues/3986) -- We fixed an issue where JabRef removed whitespace from the Title-fetcher which resulting in no entries being found. [#4014](https://github.com/JabRef/jabref/issues/4014) -- We fixed an issue where fetched entries from the ACM fetcher could not be imported. [#4018](https://github.com/JabRef/jabref/issues/4018) -- We fixed an issue to enable push to application on macOs again [#4041](https://github.com/JabRef/jabref/issues/4041) - -### Removed -- We removed the GTK Look and Feel from the Options, as it leads to freezes in JabRef on MacOSX and Linux [#3995](https://github.com/JabRef/jabref/issues/3995). -The GTK Look and Feel is now replaced with the "Nimbus" style as default. - - -## [4.2] - 2018-04-26 - -### Changed -- Added "*.*" (any file type) to the Import File Filter Dialog. [#3757](https://github.com/JabRef/jabref/issues/3757) -- Abbreviate journal names functionality is now running parallel, increasing performance significantly. [#2831](https://github.com/JabRef/jabref/issues/2831) -- Changed order of items in context menu [#298](https://github.com/koppor/jabref/issues/298) -- Changed ID-based entry generator to store the last used fetcher. [#2796](https://github.com/JabRef/jabref/issues/2796) -- Reorganised annotation information on the right side of the "File annotations" tab. [#3109](https://github.com/JabRef/jabref/issues/3109) -- We now show a small notification icon in the entry editor when we detect data inconsistency or other problems. [#3145](https://github.com/JabRef/jabref/issues/3145) -- We added [oaDOI](https://oadoi.org/) as a fulltext provider, so that JabRef is now able to provide fulltexts for more than 90 million open-access articles. -- We changed one default of [Cleanup entries dialog](http://help.jabref.org/en/CleanupEntries): Per default, the PDF are not moved to the default file directory anymore. [#3619](https://github.com/JabRef/jabref/issues/3619) -- We added a new type of group that shows all items referenced in a given LaTeX file (actually the generated AUX file). [#1664](https://github.com/JabRef/jabref/issues/1664) -- We added an importer for the EndNote XML format. [Feature request in the forum](http://discourse.jabref.org/t/import-from-bookends-or-endnote/1048) -- We added the export of the `translator` field to the according MS-Office XML field. [#1750, comment](https://github.com/JabRef/jabref/issues/1750#issuecomment-357350986) -- We changed the import of the MS-Office XML fields `bookauthor` and `translator`. Both are now imported to their corresponding bibtex/biblatex fields. -- We improved the export of the `address` and `location` field to the MS-Office XML fields. If the address field does not contain a comma, it is treated as single value and exported to the field `city`. [#1750, comment](https://github.com/JabRef/jabref/issues/1750#issuecomment-357539167) -For more details refer to the [field mapping help page](http://help.jabref.org/en/MsOfficeBibFieldMapping) -- We added Facebook and Twitter icons in the toolbar to link to our [Facebook](https://www.facebook.com/JabRef/) and [Twitter](https://twitter.com/jabref_org) pages. -- Renamed the _Review_ Tab into _Comments_ Tab -- We no longer print empty lines when exporting an entry in RIS format [#3634](https://github.com/JabRef/jabref/issues/3634) -- We added the option to download linked URLs in the context menu in the entry editor. -- We improved file saving so that hard links are now preserved when a save is performed [#2633](https://github.com/JabRef/jabref/issues/2633) -- We changed the default dialog option when removing a [file link](http://help.jabref.org/en/FileLinks#adding-external-links-to-an-entry) from an entry. -The new default removes the linked file from the entry instead of deleting the file from disk. [#3679](https://github.com/JabRef/jabref/issues/3679) -- The magnifier icon at the search shows the [search mode](https://help.jabref.org/en/Search#search-modes) again. [#3535](https://github.com/JabRef/jabref/issues/3535) -- We added a new cleanup operation that replaces ligatures with their expanded form. [#3613](https://github.com/JabRef/jabref/issues/3613) -- We added the function to parse German month names. [#3536](https://github.com/JabRef/jabref/pull/3536) -- Pressing ESC while searching will clear the search field and select the first entry, if available, in the table. [koppor#293](https://github.com/koppor/jabref/issues/293) -- We changed the metadata reading and writing. DublinCore is now the only metadata format, JabRef supports. (https://github.com/JabRef/jabref/pull/3710) -- We added another CLI functionality for reading and writing metadata to pdfs. (see https://github.com/JabRef/jabref/pull/3756 and see http://help.jabref.org/en/CommandLine) -- We no longer print errors in field values during autosave into the log [#3811](https://github.com/JabRef/jabref/issues/3811) -- We improved the search performance by adding a short delay before starting to display search results [Bug report in the forum](http://discourse.jabref.org/t/poor-performance-of-jabref-4/1110/2) -- We re-added the Generate BibTeX Key button to the EntryEditor toolbar on the left - -### Fixed -- We fixed several performance problems with the management of journal abbreviations [#3323](https://github.com/JabRef/jabref/issues/3323) -- We fixed an issue where changing the type of an entry did not update the label in the tool bar of the entry editor and the contents of the currently visible entry editor tab -- We fixed an issue where pressing space caused the cursor to jump to the start of the text field. [#3471](https://github.com/JabRef/jabref/issues/3471) -- We fixed the missing dot in the name of an exported file. [#3576](https://github.com/JabRef/jabref/issues/3576) -- Autocompletion in the search bar can now be disabled via the preferences. [#3598](https://github.com/JabRef/jabref/issues/3598) -- We fixed an issue where the progress of an ongoing file download was not shown correctly. [#3614](https://github.com/JabRef/jabref/issues/3614) -- We fixed an issue where odd linked files could not be selected in the entry editor. [#3639](https://github.com/JabRef/jabref/issues/3639) -- We fixed and extended the RIS import functionality to cover more fields. [#3634](https://github.com/JabRef/jabref/issues/3634)[#2607](https://github.com/JabRef/jabref/issues/2607) -- Chaining modifiers in BibTeX key pattern now works as described in the documentation. [#3648](https://github.com/JabRef/jabref/issues/3648) -- We fixed an issue where not all bibtex/biblatex fields would be exported as latex-free to MS-Office XML [koppor#284](https://github.com/koppor/jabref/issues/284) -- We fixed an issue where linked files would be deleted from bibliography entries despite choosing the "Cancel" option in the dialog menu. -- We fixed the name of the group editing window to "Add group" instead of "Edit Group" when adding a new group. [koppor#277](https://github.com/koppor/jabref/issues/277) -- We fixed the `pureauth` [BibTeX key generator pattern](https://help.jabref.org/en/BibtexKeyPatterns) to just return the author if no author, but an editor is present. -- We fixed an issue where the "Copy linked files" dialog produced an error when the entry had no file [#3818](https://github.com/JabRef/jabref/issues/3818) -- We fixed the coloring of the search box icon in case a user switches to advanced search mode [#3870](https://github.com/JabRef/jabref/issues/3870) -- We fixed an issue where pressing del in the `file` field would trigger the delete dialog a second file, if the first file is deleted [#3926](https://github.com/JabRef/jabref/issues/3926) -- We fixed the saving of entry preview preferences [#3845](https://github.com/JabRef/jabref/issues/3845) - -### Removed -- We removed the [Look and Feels from JGoodies](http://www.jgoodies.com/freeware/libraries/looks/), because the open source version is not compatible with Java 9. - - -## [4.1] - 2017-12-23 - -### Changed -- We added bracketed expression support for file search patterns, import file name patterns and file directory patters, in addition to bibtexkey patterns. -- We added support for `[entrytype]` bracketed expression. -- Updated French translation -- We improved the handling of abstracts in the "Astrophysics Data System" fetcher. [#2471](https://github.com/JabRef/jabref/issues/2471) -- We added support for pasting entries in different formats [#3143](https://github.com/JabRef/jabref/issues/3143) -- In the annotation tab, PDF files are now monitored for new or changed annotation. A manual reload is no longer necessary. [#3292](https://github.com/JabRef/jabref/issues/3292) -- We increased the relative size of the "abstract" field in the entry editor. [Feature request in the forum](http://discourse.jabref.org/t/entry-preview-in-version-4/827) -- Crossreferenced entries are now used when a BibTex key is generated for an entry with empty fields. [#2811](https://github.com/JabRef/jabref/issues/2811) -- We now set the `WM_CLASS` of the UI to org-jabref-JabRefMain to allow certain Un*x window managers to properly identify its windows -- We added an option to convert entries in the biblatex format to BibTeX so that you can again collaborate with these nostalgic diehards. [Feature request in the forum](http://discourse.jabref.org/t/convert-back-from-biblatex-to-bib/) -- We changed the default paths for the OpenOffice/LibreOffice binaries to the default path for LibreOffice -- File annotation tab now removes newlines and hyphens before newlines from content and displays an empty String instead of N/A if no contents are found. [#3280](https://github.com/JabRef/jabref/issues/3280) -- We moved the groups field from the "Other fields" tab to "General" (you may have to reset your editor preferences under Options > Set up general fields) -- We no longer create a new entry editor when selecting a new entry to increase performance. [#3187](https://github.com/JabRef/jabref/pull/3187) -- We added the possibility to copy linked files from entries to a single output folder. [#2539](https://github.com/JabRef/jabref/pull/2593) -- We increased performance and decreased the memory footprint of the entry editor drastically. [#3331](https://github.com/JabRef/jabref/pull/3331) -- Late initialization of the context menus in the entry editor. This improves performance and memory footprint further [#3340](https://github.com/JabRef/jabref/pull/3340) -- Integrity check "Abbreviation Detection" detects abbreviated names for journals and booktitles based on the internal list instead of only looking for `.` signs. Fixes [#3144](https://github.com/JabRef/jabref/issues/3144). -- We added a dialog to show that JabRef is working on checking integrity. [#3358](https://github.com/JabRef/jabref/issues/3358) -- When you click the PDF icon in the file list of the entry editor, then the file is opened. [#3491](https://github.com/JabRef/jabref/issues/3491) -- We added an option to mass append to fields via the Quality -> [set/clear/append/rename fields dialog](http://help.jabref.org/en/SetClearRenameFields). [#2721](https://github.com/JabRef/jabref/issues/2721) -- We added a check on startup to ensure JabRef is run with an adequate Java version. [3310](https://github.com/JabRef/jabref/issues/3310) -- In the preference, all installed java Look and Feels are now listed and selectable -- We added an ID fetcher for [IACR eprints](https://eprint.iacr.org/). [#3473](https://github.com/JabRef/jabref/pull/3473) -- We added a clear option to the right-click menu of the text field in the entry editor. [koppor#198](https://github.com/koppor/jabref/issues/198) -- We improved the performance and memory footprint of the citation preview when [CSL styles](http://citationstyles.org/) are used. [#2533](https://github.com/JabRef/jabref/issues/2533) -- We disabled the auto completion as default, because it still causes issues. [#3522](https://github.com/JabRef/jabref/issues/3522) - -### Fixed - - We fixed the translation of `\textendash` and `\textquotesingle` in the entry preview. [#3307](https://github.com/JabRef/jabref/issues/3307) - - We fixed an issue where JabRef would not terminated after asking to collect anonymous statistics. [#2955 comment](https://github.com/JabRef/jabref/issues/2955#issuecomment-334591123) - - We fixed an issue where JabRef would not shut down when started with the `-n` (No GUI) option. [#3247](https://github.com/JabRef/jabref/issues/3247) - - We improved the way metadata is updated in remote databases. [#3235](https://github.com/JabRef/jabref/issues/3235) - - We improved font rendering of the Entry Editor for Linux based systems. [#3295](https://github.com/JabRef/jabref/issues/3295) - - We fixed an issue where JabRef would freeze when trying to replace the original entry after a merge with new information from identifiers like DOI/ISBN etc. [#3294](https://github.com/JabRef/jabref/issues/3294) - - We no longer allow to add a field multiple times in customized entry types and thereby fix an issue in the entry editor that resulted from having a field multiple times. [#3046](https://github.com/JabRef/jabref/issues/3046) - - We fixed an issue where JabRef would not show the translated content at some points, although there existed a translation - - We fixed an issue where editing in the source tab would override content of other entries. [#3352](https://github.com/JabRef/jabref/issues/3352#issue-268580818) - - We fixed an issue where file links created under Windows could not be opened on Linux/OSX. [#3311](https://github.com/JabRef/jabref/issues/3311) - - We fixed several issues with the automatic linking of files in the entry editor where files were not found or not correctly saved in the bibtex source. [#3346](https://github.com/JabRef/jabref/issues/3346) - - We fixed an issue where fetching entries from crossref that had no titles caused an error. [#3376](https://github.com/JabRef/jabref/issues/3376) - - We fixed an issue where the same Java Look and Feel would be listed more than once in the Preferences. [#3391](https://github.com/JabRef/jabref/issues/3391) - - We fixed an issue where errors in citation styles triggered an exception when opening the preferences dialog. [#3389](https://github.com/JabRef/jabref/issues/3389) - - We fixed an issue where entries were displayed twice after insertion into a shared database. [#3164](https://github.com/JabRef/jabref/issues/3164) - - We improved the auto link algorithm so that files starting with a similar key are no longer found (e.g, `Einstein1902` vs `Einstein1902a`). [#3472](https://github.com/JabRef/jabref/issues/3472) - - We fixed an issue where special fields (such as `printed`) could not be cleared when syncing special fields via the keywords. [#3432](https://github.com/JabRef/jabref/issues/3432) - - We fixed an issue where the tooltip of the global search bar showed html tags instead of formatting the text. [#3381](https://github.com/JabRef/jabref/issues/3381) - - We fixed an issue where timestamps were not updated for changed entries. [#2810](https://github.com/JabRef/jabref/issues/2810) - - We fixed an issue where trying to fetch data from Medline/PubMed resulted in an error. [#3463](https://github.com/JabRef/jabref/issues/3463) - - We fixed an issue where double clicking on an entry in the integrity check dialog resulted in an exception. [#3485](https://github.com/JabRef/jabref/issues/3485) - - We fixed an issue where the entry type could sometimes not be changed when the entry editor was open [#3435](https://github.com/JabRef/jabref/issues/3435) - - We fixed an issue where dropping a pdf on the entry table and renaming it triggered an exception. [#3490](https://github.com/JabRef/jabref/issues/3490) - - We fixed an issue where no longer existing files could not be removed from the entry by pressing the del key. [#3493](https://github.com/JabRef/jabref/issues/3493) - - We fixed an issue where integrating external changes to a bib file caused instability. [#3498](https://github.com/JabRef/jabref/issues/3498) - - We fixed an issue where fetched entries from the ACM fetcher could not be imported. [#3500](https://github.com/JabRef/jabref/issues/3500) - - We fixed an issue where custom data in combobox fields in the entry editor was not saved. [#3538](https://github.com/JabRef/jabref/issues/3538) - - We fixed an issue where automatically found files were not added with a relative paths when the bib file is in the same directory as the files. [#3476](https://github.com/JabRef/jabref/issues/3476) - - We improved the key generator to remove certain illegal characters such as colons or apostrophes. [#3359](https://github.com/JabRef/jabref/issues/3359) - - -## [4.0] - 2017-10-04 - -### Changed - -- We added a textArea to see versionInfo in the About JabRef Dialog. [#2942](https://github.com/JabRef/jabref/issues/2942) -- We turned the validation feature in the entry editor off by default, because of a bug in the library we have been using [#3145](https://github.com/JabRef/jabref/issues/3145) -- Added 'Filter All' and 'Filter None' buttons with corresponding functionality to Quality Check tool. -- We increased the size of the keywords and file text areas in the entry editor -- When the entry that is currently shown in the entry editor is deleted externally, the editor is now closed automatically [#2946](https://github.com/JabRef/jabref/issues/2946) -- We added reordering of file and link entries in the `General`-Tab [3165, comment](https://github.com/JabRef/jabref/issues/3165#issuecomment-326269715) -- We added autcompletion for the `crossref` field on basis of the BibTeX-key. To accept such an autcompleted key as new entry-link, you have to press Enter two times, otherwise the field data is not stored in the library file.[koppor#257](https://github.com/koppor/jabref/issues/257) -- We added drag and drop support for adding files directly in the `General`-Tab. The dragged files are currently only linked from their existing directory. For more advanced features use the `Add files` dialog. [#koppor#244](https://github.com/koppor/jabref/issues/244) -- We added the file description filed back to the list of files in the `General`-Tab [#2930, comment](https://github.com/JabRef/jabref/issues/2930#issuecomment-328328172) -- Added an error dialog if the file is open in another process and cannot be renamed. [#3229] -- On Windows, the `JabRef.exe` executable can now be used to start JabRef from the command line. By default, no output is shown unless the new "-console" option is specified. - -### Fixed - -- We re-added the "Normalize to BibTeX name format" context menu item [#3136](https://github.com/JabRef/jabref/issues/3136) -- We fixed a memory leak in the source tab of the entry editor [#3113](https://github.com/JabRef/jabref/issues/3113) -- We fixed a [java bug](https://bugs.openjdk.java.net/browse/JDK-8185792) where linux users could not enter accented characters in the entry editor and the search bar [#3028](https://github.com/JabRef/jabref/issues/3028) -- We fixed a regression introduced in v4.0-beta2: A file can be dropped to the entry preview to attach it to the entry [koppor#245](https://github.com/koppor/jabref/issues/245) -- We fixed an issue in the "Replace String" dialog (Ctrl+R where search and replace did not work for the `bibtexkey` field. [#3132](https://github.com/JabRef/jabref/issues/3132) -- We fixed an issue in the entry editor where adding a term to a new protected terms list freezed JabRef completely. [#3157](https://github.com/JabRef/jabref/issues/3157) -- We fixed an issue in the "Manage protected terms" dialog where an 'Open file' dialog instead of a 'Save file' dialog was shown when creating a new list. [#3157](https://github.com/JabRef/jabref/issues/3157) -- We fixed an issue where unparseable dates of the FileAnnotations caused the FileAnnotationsTab to crash. -- We fixed an issue where a new protected terms list was not available immediately after its addition. [#3161](https://github.com/JabRef/jabref/issues/3161) -- We fixed an issue where an online file link could not be removed from an entry [#3165](https://github.com/JabRef/jabref/issues/3165) -- We fixed an issue where an online file link did not open the browser and created an error [#3165](https://github.com/JabRef/jabref/issues/3165) -- We fixed an issue where the arrow keys in the search bar did not work as expected [#3081](https://github.com/JabRef/jabref/issues/3081) -- We fixed wrong hotkey being displayed at "automatically file links" in the entry editor -- We fixed an issue where metadata syncing with local and shared database were unstable. It will also fix syncing groups and sub-groups in database. [#2284](https://github.com/JabRef/jabref/issues/2284) -- We fixed an issue where renaming a linked file would fail silently if a file with the same name existed. Added support for overriding existing file at user discretion. [#3172](https://github.com/JabRef/jabref/issues/3172) -- We fixed an issue where the "Remove group and subgroups" operation did not remove group information from entries in the group [#3190](https://github.com/JabRef/jabref/issues/3190) -- We fixed an issue where it was possible to leave the entry editor with an imbalance of braces. [#3167](https://github.com/JabRef/jabref/issues/3167) -- Renaming files now truncates the filename to not exceed the limit of 255 chars [#2622](https://github.com/JabRef/jabref/issues/2622) -- We improved the handling of hyphens in names. [#2775](https://github.com/JabRef/jabref/issues/2775) -- We fixed an issue where an entered file description was not written to the bib-file [#3208](https://github.com/JabRef/jabref/issues/3208) -- We improved the auto completion in the search bar. [koppor#253](https://github.com/koppor/jabref/issues/253) -- We fixed renaming files which are not in the main directory. [#3230](https://github.com/JabRef/jabref/issues/3230) - -### Removed -- We removed support for LatexEditor, as it is not under active development. [#3199](https://github.com/JabRef/jabref/issues/3199) - - -## [4.0-beta3] – 2017-08-16 - -### Changed -- We made the font size in the entry editor and group panel customizable by "Menu and label font size". [#3034](https://github.com/JabRef/jabref/issues/3034) -- If fetched article is already in database, then the entry merge dialog is shown. -- An error message is now displayed if you try to create a group containing the keyword separator or if there is already a group with the same name. [#3075](https://github.com/JabRef/jabref/issues/3075) and [#1495](https://github.com/JabRef/jabref/issues/1495) -- The FileAnnotationsTab was re-implemented in JavaFx. [#3082](https://github.com/JabRef/jabref/pull/3082) -- Integrity warnings are now directly displayed in the entry editor. -- We added the functionality to have `regex` as modifier. [#457](https://github.com/JabRef/jabref/issues/457) - -### Fixed - -- We fixed an issue where the fetcher for the Astrophysics Data System (ADS) added some non-bibtex data to the entry returned from the search [#3035](https://github.com/JabRef/jabref/issues/3035) -- We improved the auto completion so that minor changes are not added as suggestions. [#2998](https://github.com/JabRef/jabref/issues/2998) -- We readded the undo mechanism for changes in the entry editor [#2973](https://github.com/JabRef/jabref/issues/2973) -- We fixed an issue where assigning an entry via drag and drop to a group caused JabRef to stop/freeze completely [#3036](https://github.com/JabRef/jabref/issues/3036) -- We fixed the shortcut Ctrl+F for the search field. -- We fixed an issue where `title_case` and `capitalize` modifiers did not work with shorttitle. -- We fixed an issue where the preferences could not be imported without a restart of JabRef [#3064](https://github.com/JabRef/jabref/issues/3064) -- We fixed an issue where DEL, Ctrl+C, Ctrl+V and Ctrl+A in the search field triggered corresponding actions in the main table [#3067](https://github.com/JabRef/jabref/issues/3067) -- We fixed an issue where JabRef freezed when editing an assigned file in the `General`-Tab [#2930, comment](https://github.com/JabRef/jabref/issues/2930#issuecomment-311050976) -- We fixed an issue where a file could not be assigned to an existing entry via the entry context menu action `Attach file` [#3080](https://github.com/JabRef/jabref/issues/3080) -- We fixed an issue where entry editor was not focused after opening up. [#3052](https://github.com/JabRef/jabref/issues/3052) -- We fixed an issue where changes in the source tab were not stored when selecting a new entry. [#3086](https://github.com/JabRef/jabref/issues/3086) -- We fixed an issue where the other tab was not updated when fields where changed in the source tab. [#3063](https://github.com/JabRef/jabref/issues/3063) -- We fixed an issue where the source tab was not updated after fetching data by DOI. [#3103](https://github.com/JabRef/jabref/issues/3103) -- We fixed an issue where the move to group operation did not remove the entry from other groups [#3101](https://github.com/JabRef/jabref/issues/3101) -- We fixed an issue where the main table was not updated when grouping changes [#1903](https://github.com/JabRef/jabref/issues/1903) - -## [4.0-beta2] – 2017-07-18 - -### Changed -- We moved the `adsurl` field to `url` field when fetching with the ADS fetcher. -- We continued to improve the new groups interface: - - You can now again select multiple groups (and a few related settings were added to the preferences) [#2786](https://github.com/JabRef/jabref/issues/2786). - - We further improved performance of group operations, especially of the new filter feature [#2852](https://github.com/JabRef/jabref/issues/2852). - - It is now possible to resort groups using drag & drop [#2785](https://github.com/JabRef/jabref/issues/2785). -- The entry editor got a fresh coat of paint: - - Homogenize the size of text fields. - - The buttons were changed to icons. - - Completely new interface to add or modify linked files. - - Removed the hidden feature that a double click in the editor inserted the current date. - - Complete new implementation of the the auto complete feature. -- All authors and editors are separated using semicolons when exporting to csv. [#2762](https://github.com/JabRef/jabref/issues/2762) -- Improved wording of "Show recommendations: into "Show 'Related Articles' tab" in the preferences -- We added integration of the Library of Congress catalog as a fetcher based on the [LCCN identifier](https://en.wikipedia.org/wiki/Library_of_Congress_Control_Number). [Feature request 636 in the forum](http://discourse.jabref.org/t/loc-marc-mods-connection/636) -- The integrity check for person names now also tests that the names are specified in one of the standard BibTeX formats. -- Links in the Recommended Articles tab (Mr.DLib), when clicked, are now opened in the system's default browser. [2931](https://github.com/JabRef/jabref/issues/2931) -- We improved the duplicate checker such that different editions of the same publication are not marked as duplicates. [2960](https://github.com/JabRef/jabref/issues/2960) - -### Fixed -- We fixed a bug that leaves .sav file after SaveAs [#2947](https://github.com/JabRef/jabref/issues/2947) -- We fixed the function "Edit - Copy BibTeX key and link" to pass a hyperlink rather than an HTML statement. -- We fixed the adding of a new entry from DOI which led to a connection error. The DOI resolution now uses HTTPS to protect the user's privacy.[#2879](https://github.com/JabRef/jabref/issues/2897) -- We fixed the IEEE Xplore web search functionality [#2789](https://github.com/JabRef/jabref/issues/2789) -- We fixed an error in the CrossRef fetcher that occurred if one of the fetched entries had no title -- We fixed an issue that prevented new entries to be automatically assigned to the currently selected group [#2783](https://github.com/JabRef/jabref/issues/2783). -- We fixed a bug that only allowed parsing positive timezones from a FileAnnotation [#2839](https://github.com/JabRef/jabref/issues/2839) -- We fixed a bug that did not allow the correct re-export of the MS-Office XML field `msbib-accessed` with a different date format [#2859](https://github.com/JabRef/jabref/issues/2859). -- We fixed some bugs that prevented the display of FileAnnotations that were created using the Foxit Reader. [#2839, comment](https://github.com/JabRef/jabref/issues/2839#issuecomment-302058227). -- We fixed an error that prevented the FileAnnotation tab to load when the entry had no bibtexkey [#2903](https://github.com/JabRef/jabref/issues/2903). -- We fixed a bug which which could result in an exception when opening/saving files from/to a nonexistent directory [#2917](https://github.com/JabRef/jabref/issues/2917). -- We fixed a bug where recursive RegExpBased search found a file in a subdirectory multiple times and non-recursive RegExpBased search erroneously found files in subdirectories. -- We fixed a bug where new groups information was not stored on save [#2932](https://github.com/JabRef/jabref/issues/2932) -- We fixed a bug where the language files for Brazilian Portugese could not be loaded and the GUI localization remained in English [#1128](https://github.com/JabRef/jabref/issues/1182) -- We fixed a bug where the database was not marked as dirty when entries or groups were changed [#2787](https://github.com/JabRef/jabref/issues/2787) -- We fixed a bug where editors in the DocBook export were not exported [#3020](https://github.com/JabRef/jabref/issues/3020) -- We fixed a bug where the source tab was not updated when one the fields was changed [#2888](https://github.com/JabRef/jabref/issues/2888) -- We restored the original functionality that when browsing through the MainTable, the Entry Editor remembers which tab was opened before [#2896](https://github.com/JabRef/jabref/issues/2896) - -## [4.0-beta] – 2017-04-17 - -### Changed -- JabRef has a new logo! The logo was designed by "[AikTheOne](https://99designs.de/profiles/theonestudio)" - who was the winner of a design contest at 99designs.com -- Partly switched to a new UI technology ([JavaFX]). - - Redesigned group panel. - - Number of matched entries is always shown. - - The background color of the hit counter signals whether the group contains all/any of the entries selected in the main table. - - Added a possibility to filter the groups panel [#1904](https://github.com/JabRef/jabref/issues/1904) - - Removed edit mode. - - Removed the following commands in the right-click menu: - - Expand/collapse subtree - - Move up/down/left/right - - Remove option to "highlight overlapping groups" - - Moved the option to "Gray out non-hits" / "Hide non-hits" to the preferences - - Removed the following options from the group preferences: - - Show icons (icons can now be customized) - - Show dynamic groups in italics (dynamic groups are not treated specially now) - - Initially show groups tree expanded (always true now) - - Expansion status of groups are saved across sessions. [#1428](https://github.com/JabRef/jabref/issues/1428) - - Redesigned about dialog. - - Redesigned key bindings dialog. - - Redesigned journal abbreviations dialog. - - New error console. - - All file dialogs now use the native file selector of the OS. [#1711](https://github.com/JabRef/jabref/issues/1711) -- We added a few properties to a group: - - Icon (with customizable color) that is shown in the groups panel (implements a [feature request in the forum](http://discourse.jabref.org/t/assign-colors-to-groups/321)). - - Description text that is shown on mouse hover (implements old feature requests [489](https://sourceforge.net/p/jabref/feature-requests/489/) and [818](https://sourceforge.net/p/jabref/feature-requests/818/)) -- We introduced "automatic groups" that automatically create subgroups based on a certain criteria (e.g., a subgroup for every author or keyword) and supports hierarchies. Implements [91](https://sourceforge.net/p/jabref/feature-requests/91/), [398](https://sourceforge.net/p/jabref/feature-requests/398/), [#1173](https://github.com/JabRef/jabref/issues/1173) and [#628](https://github.com/JabRef/jabref/issues/628). -- We added a document viewer which allows you to have a glance at your PDF documents directly from within JabRef. -- Using "Look up document identifier" in the quality menu, it is possible to look up DOIs, ArXiv ids and other identifiers for multiple entries. -- Comments in PDF files can now be displayed inside JabRef in a separate tab -- We separated the `Move file` and `Rename Pdfs` logic and context menu entries in the `General`-Tab for the Field `file` to improve the semantics -- We integrated support for the [paper recommender system Mr.DLib](http://help.jabref.org/en/EntryEditor#related-articles-tab) in a new tab in the entry editor. -- We renamed "database" to "library" to have a real distinction to SQL databases ("shared database") and `bib` files ("library"). [#2095](https://github.com/JabRef/jabref/issues/2095) -- We improved the UI customization possibilities: - - It is now possible to customize the colors and the size of the icons (implements a [feature request in the forum](http://discourse.jabref.org/t/menu-and-buttons-with-a-dark-theme/405)). - - Resizing the menu and label sizes has been improved. - - Font sizes can now be increased Ctrl + Plus, decreased Ctrl + Minus, and reset to default CTRL + 0. -- F4 opens selected file in current JTable context not just from selected entry inside the main table [#2355](https://github.com/JabRef/jabref/issues/2355) -- We are happy to welcome [CrossRef](https://www.crossref.org/) as a new member of our fetcher family. [#2455](https://github.com/JabRef/jabref/issues/2455) -- We added MathSciNet as a ID-based fetcher in the `BibTeX -> New entry` dialog (implements a [feature request in the forum](http://discourse.jabref.org/t/allow-to-search-by-mr-number-mathscinet)) -- Add tab which shows the MathSciNet review website if the `MRNumber` field is present. -- A scrollbar was added to the cleanup panel, as a result of issue [#2501](https://github.com/JabRef/jabref/issues/2501) -- Several scrollbars were added to the preference dialog which show up when content is too large [#2559](https://github.com/JabRef/jabref/issues/2559) -- We fixed and improved the auto detection of the [OpenOffice and LibreOffice connection](http://help.jabref.org/en/OpenOfficeIntegration) -- We added an option to copy the title of BibTeX entries to the clipboard through `Edit -> Copy title` (implements [#210](https://github.com/koppor/jabref/issues/210)) -- The `Move linked files to default file directory`-Cleanup operation respects the `File directory pattern` setting -- We removed the ordinals-to-superscript formatter from the recommendations for biblatex save actions [#2596](https://github.com/JabRef/jabref/issues/2596) -- Improved MS-Office Import/Export - - Improved author handling - - The `day` part of the biblatex `date` field is now exported to the corresponding `day` field. [#2691](https://github.com/JabRef/jabref/issues/2691) - - Entries with a single corporate author are now correctly exported to the corresponding `corporate` author field. [#1497](https://github.com/JabRef/jabref/issues/1497) - - Now exports the field `volumes` and `pubstate`. -- The integrity checker reports now if a journal is not found in the abbreviation list -- JabRef will now no longer delete meta data it does not know, but keeps such entries and tries to keep their formatting as far as possible. -- Switch to the [latex2unicode library](https://github.com/tomtung/latex2unicode) for converting LaTeX to unicode -- Single underscores are not converted during the LaTeX to unicode conversion, which does not follow the rules of LaTeX, but is what users require. [#2664](https://github.com/JabRef/jabref/issues/2664) -- The bibtexkey field is not converted to unicode - -### Fixed - - ArXiV fetcher now checks similarity of entry when using DOI retrieval to avoid false positives [#2575](https://github.com/JabRef/jabref/issues/2575) - - We fixed an issue of duplicate keys after using a fetcher, e.g., DOI or ISBN [#2867](https://github.com/JabRef/jabref/issues/2687) - - We fixed an issue that prevented multiple parallel JabRef instances from terminating gracefully. [#2698](https://github.com/JabRef/jabref/issues/2698) - - We fixed an issue where authors with multiple surnames were not presented correctly in the main table. [#2534](https://github.com/JabRef/jabref/issues/2534) - - Repairs the handling of apostrophes in the LaTeX to unicode conversion. [#2500](https://github.com/JabRef/jabref/issues/2500) - - Fix import of journal title in RIS format. [#2506](https://github.com/JabRef/jabref/issues/2506) - - We fixed the export of the `number` field in MS-Office XML export. [#2509](https://github.com/JabRef/jabref/issues/2509) - - The field `issue` is now always exported to the corresponding `issue` field in MS-Office XML. - - We fixed the import of MS-Office XML files, when the `month` field contained an invalid value. - - We fixed an issue with repeated escaping of the %-sign when running the LaTeXCleanup more than once. [#2451](https://github.com/JabRef/jabref/issues/2451) - - Sciencedirect/Elsevier fetcher is now able to scrape new HTML structure [#2576](https://github.com/JabRef/jabref/issues/2576) - - Fixed the synchronization logic of keywords and special fields and vice versa [#2580](https://github.com/JabRef/jabref/issues/2580) - - We fixed an exception that prevented JabRef from starting in rare cases [bug report in the forum](http://discourse.jabref.org/t/jabref-not-opening/476). - - We fixed an unhandled exception when saving an entry containing unbalanced braces [#2571](https://github.com/JabRef/jabref/issues/2571) - - Fixed a display issue when removing a group with a long name [#1407](https://github.com/JabRef/jabref/issues/1407) - - We fixed an issue where the "find unlinked files" functionality threw an error when only one PDF was imported but not assigned to an entry [#2577](https://github.com/JabRef/jabref/issues/2577) - - We fixed issue where escaped braces were incorrectly counted when calculating brace balance in a field [#2561](https://github.com/JabRef/jabref/issues/2561) - - We fixed an issue introduced with Version 3.8.2 where executing the `Rename PDFs`-cleanup operation moved the files to the file directory. [#2526](https://github.com/JabRef/jabref/issues/2526) - - We improved the performance when opening a big library that still used the old groups format. Fixes an [issue raised in the forum](http://discourse.jabref.org/t/v3-8-2-x64-windows-problem-saving-large-bib-libraries/456). - - We fixed an issue where the `Move linked files to default file directory`- cleanup operation did not move the files to the location of the bib-file. [#2454](https://github.com/JabRef/jabref/issues/2454) - - We fixed an issue where executing `Move file` on a selected file in the `general`-tab could overwrite an existing file. [#2385](https://github.com/JabRef/jabref/issues/2358) - - We fixed an issue with importing groups and subgroups [#2600](https://github.com/JabRef/jabref/issues/2600) - - Fixed an issue where title-related key patterns did not correspond to the documentation. [#2604](https://github.com/JabRef/jabref/issues/2604) [#2589](https://github.com/JabRef/jabref/issues/2589) - - We fixed an issue which prohibited the citation export to external programs on MacOS. [#2613](https://github.com/JabRef/jabref/issues/2613) - - We fixed an issue where the file folder could not be changed when running `Get fulltext` in the `general`-tab. [#2572](https://github.com/JabRef/jabref/issues/2572) - - Newly created libraries no longer have the executable bit set under POSIX/Linux systems. The file permissions are now set to `664 (-rw-rw-r--)`. [#2635](https://github.com/JabRef/jabref/issues/#2635) - - Fixed an issue where names were split inconsistently with the BibTeX conventions [#2652](https://github.com/JabRef/jabref/issues/2652) - - Ctrl + A now correctly selects all entries again. [#2615](https://github.com/JabRef/jabref/issues/#2615) - - We fixed an issue where the dialog for selecting the main file directory in the preferences opened the wrong folder - - OpenOffice text formatting now handles nested tags properly [#2483](https://github.com/JabRef/jabref/issues/#2483) - - The group selection is no longer lost when switching tabs [#1104](https://github.com/JabRef/jabref/issues/1104) ## Older versions -The changelog of versions 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of 2.11 and versions before is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). [Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD [4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 From 2f5bffa3eae6f0f721e7e4e8e928035cd4b2484d Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 13 Jun 2018 15:31:33 +0200 Subject: [PATCH 13/22] Fix open thread prevents shutdown (#4111) * Properly shutdown telemetry client * Fix thread leak at shutdown * add fixme --- src/main/java/org/jabref/Globals.java | 12 ++++++++---- src/main/java/org/jabref/JabRefMain.java | 12 +++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/Globals.java b/src/main/java/org/jabref/Globals.java index 4cc1cef90b6..8c7626705d9 100644 --- a/src/main/java/org/jabref/Globals.java +++ b/src/main/java/org/jabref/Globals.java @@ -25,6 +25,7 @@ import com.google.common.base.StandardSystemProperty; import com.microsoft.applicationinsights.TelemetryClient; import com.microsoft.applicationinsights.TelemetryConfiguration; +import com.microsoft.applicationinsights.internal.shutdown.SDKShutdownActivity; import com.microsoft.applicationinsights.telemetry.SessionState; public class Globals { @@ -90,10 +91,13 @@ public static void startBackgroundTasks() { } private static void stopTelemetryClient() { - if (Globals.prefs.shouldCollectTelemetry()) { - getTelemetryClient().ifPresent(client -> client.trackSessionState(SessionState.End)); - getTelemetryClient().ifPresent(client -> client.flush()); - } + getTelemetryClient().ifPresent(client -> { + client.trackSessionState(SessionState.End); + client.flush(); + + //FIXME: Workaround for bug https://github.com/Microsoft/ApplicationInsights-Java/issues/662 + SDKShutdownActivity.INSTANCE.stopAll(); + }); } private static void startTelemetryClient() { diff --git a/src/main/java/org/jabref/JabRefMain.java b/src/main/java/org/jabref/JabRefMain.java index fd4ffda4dde..a0ad2dff94d 100644 --- a/src/main/java/org/jabref/JabRefMain.java +++ b/src/main/java/org/jabref/JabRefMain.java @@ -35,6 +35,7 @@ * JabRef MainClass */ public class JabRefMain extends Application { + private static final Logger LOGGER = LoggerFactory.getLogger(JabRefMain.class); private static String[] arguments; @@ -75,12 +76,6 @@ public void start(Stage mainStage) throws Exception { new JabRefGUI(mainStage, argumentProcessor.getParserResults(), argumentProcessor.isBlank()); } - @Override - public void stop() { - Platform.exit(); - System.exit(0); - } - /** * Tests if we are running an acceptable Java and terminates JabRef when we are sure the version is not supported. * This test uses the requirements for the Java version as specified in gradle.build. It is possible to @@ -149,7 +144,6 @@ private static void shutdownCurrentInstance() { Globals.stopBackgroundTasks(); Globals.shutdownThreadPools(); Platform.exit(); - System.exit(0); } private static void applyPreferences(JabRefPreferences preferences) { @@ -165,9 +159,9 @@ private static void applyPreferences(JabRefPreferences preferences) { /* Build list of Import and Export formats */ Globals.IMPORT_FORMAT_READER.resetImportFormats(Globals.prefs.getImportFormatPreferences(), - Globals.prefs.getXMPPreferences(), Globals.getFileUpdateMonitor()); + Globals.prefs.getXMPPreferences(), Globals.getFileUpdateMonitor()); EntryTypes.loadCustomEntryTypes(preferences.loadCustomEntryTypes(BibDatabaseMode.BIBTEX), - preferences.loadCustomEntryTypes(BibDatabaseMode.BIBLATEX)); + preferences.loadCustomEntryTypes(BibDatabaseMode.BIBLATEX)); Globals.exportFactory = Globals.prefs.getExporterFactory(Globals.journalAbbreviationLoader); // Initialize protected terms loader From 9398c3e1c5a5d92ca8f54e9f2a0213b85958d382 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 13 Jun 2018 17:51:00 +0200 Subject: [PATCH 14/22] Groups right click (#4061) * Right click does not select group * Consume event upon click on disclosure node --- .../java/org/jabref/gui/groups/GroupTreeView.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeView.java b/src/main/java/org/jabref/gui/groups/GroupTreeView.java index 72fbec509d5..bf0137fb465 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeView.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeView.java @@ -28,6 +28,8 @@ import javafx.scene.input.ClipboardContent; import javafx.scene.input.DragEvent; import javafx.scene.input.Dragboard; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; import javafx.scene.layout.StackPane; import javafx.scene.text.Text; @@ -148,7 +150,10 @@ public void initialize() { disclosureNode.getChildren().add(disclosureNodeArrow); return disclosureNode; }) - .withOnMouseClickedEvent(group -> event -> group.toggleExpansion())); + .withOnMouseClickedEvent(group -> event -> { + group.toggleExpansion(); + event.consume(); + })); // Set pseudo-classes to indicate if row is root or sub-item ( > 1 deep) PseudoClass rootPseudoClass = PseudoClass.getPseudoClass("root"); @@ -178,6 +183,12 @@ public void initialize() { EasyBind.monadic(row.itemProperty()) .map(this::createContextMenuForGroup) .orElse((ContextMenu) null)); + row.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> { + if (event.getButton() == MouseButton.SECONDARY) { + // Prevent right-click to select group + event.consume(); + } + }); // Drag and drop support row.setOnDragDetected(event -> { From 2797e107650782597281a251651134702d6f6950 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 13 Jun 2018 17:54:59 +0200 Subject: [PATCH 15/22] Use in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17609efbce5..f06020d437b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). -- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀ alt + up/down`. +- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) From be1117a6f434959b161baccd0cd94d8f8127da5a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 13 Jun 2018 18:06:30 +0200 Subject: [PATCH 16/22] Fix #4115: Don't report journal name as abbreviated when full name = abbreviated name (#4116) --- CHANGELOG.md | 1 + .../JournalAbbreviationRepository.java | 12 ++++++- .../integrity/AbbreviationCheckerTest.java | 35 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/jabref/logic/integrity/AbbreviationCheckerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6260be33304..50e5c1783c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 - We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 - We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 +- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) - We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 - We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 - We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java index 72a90329e4b..68bc4c17370 100644 --- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java +++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java @@ -27,18 +27,28 @@ private static boolean isMatched(String name, Abbreviation abbreviation) { } private static boolean isMatchedAbbreviated(String name, Abbreviation abbreviation) { - return name.equalsIgnoreCase(abbreviation.getIsoAbbreviation()) + boolean isAbbreviated = name.equalsIgnoreCase(abbreviation.getIsoAbbreviation()) || name.equalsIgnoreCase(abbreviation.getMedlineAbbreviation()); + boolean isExpanded = name.equalsIgnoreCase(abbreviation.getName()); + return isAbbreviated && !isExpanded; } public int size() { return abbreviations.size(); } + /** + * Returns true if the given journal name is contained in the list either in its full form (e.g Physical Review + * Letters) or its abbreviated form (e.g. Phys. Rev. Lett.). + */ public boolean isKnownName(String journalName) { return abbreviations.stream().anyMatch(abbreviation -> isMatched(journalName.trim(), abbreviation)); } + /** + * Returns true if the given journal name is in its abbreviated form (e.g. Phys. Rev. Lett.). The test is strict, + * i.e. journals whose abbreviation is the same as the full name are not considered + */ public boolean isAbbreviatedName(String journalName) { return abbreviations.stream().anyMatch(abbreviation -> isMatchedAbbreviated(journalName.trim(), abbreviation)); } diff --git a/src/test/java/org/jabref/logic/integrity/AbbreviationCheckerTest.java b/src/test/java/org/jabref/logic/integrity/AbbreviationCheckerTest.java new file mode 100644 index 00000000000..033bdbe98d1 --- /dev/null +++ b/src/test/java/org/jabref/logic/integrity/AbbreviationCheckerTest.java @@ -0,0 +1,35 @@ +package org.jabref.logic.integrity; + +import java.util.Optional; + +import org.jabref.logic.journals.Abbreviation; +import org.jabref.logic.journals.JournalAbbreviationRepository; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +class AbbreviationCheckerTest { + + private JournalAbbreviationRepository abbreviationRepository; + private AbbreviationChecker checker; + + @BeforeEach + void setUp() { + abbreviationRepository = new JournalAbbreviationRepository(new Abbreviation("Test Journal", "T. J.")); + checker = new AbbreviationChecker(abbreviationRepository); + } + + @Test + void checkValueComplainsAboutAbbreviatedJournalName() { + assertNotEquals(Optional.empty(), checker.checkValue("T. J.")); + } + + @Test + void checkValueDoesNotComplainAboutJournalNameThatHasSameAbbreviation() { + abbreviationRepository.addEntry(new Abbreviation("Journal", "Journal")); + assertEquals(Optional.empty(), checker.checkValue("Journal")); + } +} From d8c5b880b69d70dcec69abd30d4b0c8e2c7786cb Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 13 Jun 2018 18:17:24 +0200 Subject: [PATCH 17/22] Fix checkstyle --- src/main/java/org/jabref/gui/ClipBoardManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index 006ab49d3e8..c7c6ce2b9d4 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -29,8 +29,9 @@ public class ClipBoardManager { - private static final Logger LOGGER = LoggerFactory.getLogger(ClipBoardManager.class); public static final DataFormat XML = new DataFormat("application/xml"); + + private static final Logger LOGGER = LoggerFactory.getLogger(ClipBoardManager.class); private final Clipboard clipboard; From 45b967b1ce080e26a368ba3e66b09dba5041bf3f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 13 Jun 2018 23:35:07 +0200 Subject: [PATCH 18/22] [WIP] Split push to applications in logic and gui (#4110) * Split push to applications in logic and gui * Properly implement settings factory --- .../org/jabref/gui/preftabs/ExternalTab.java | 11 +- .../gui/push/AbstractPushToApplication.java | 48 +----- .../jabref/gui/push/PushToApplication.java | 17 -- .../gui/push/PushToApplicationButton.java | 149 ------------------ .../gui/push/PushToApplicationSettings.java | 77 +++++++++ .../push/PushToApplicationSettingsDialog.java | 3 +- .../jabref/gui/push/PushToApplications.java | 16 +- .../java/org/jabref/gui/push/PushToEmacs.java | 22 --- .../jabref/gui/push/PushToEmacsSettings.java | 33 ++++ .../java/org/jabref/gui/push/PushToLyx.java | 8 - .../jabref/gui/push/PushToLyxSettings.java | 16 ++ .../java/org/jabref/gui/push/PushToVim.java | 22 --- .../jabref/gui/push/PushToVimSettings.java | 33 ++++ 13 files changed, 183 insertions(+), 272 deletions(-) create mode 100644 src/main/java/org/jabref/gui/push/PushToApplicationSettings.java create mode 100644 src/main/java/org/jabref/gui/push/PushToEmacsSettings.java create mode 100644 src/main/java/org/jabref/gui/push/PushToLyxSettings.java create mode 100644 src/main/java/org/jabref/gui/push/PushToVimSettings.java diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index 19140e538bf..b8cab7e7e72 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -20,7 +20,9 @@ import org.jabref.gui.JabRefFrame; import org.jabref.gui.externalfiletype.ExternalFileTypeEditor; import org.jabref.gui.push.PushToApplication; +import org.jabref.gui.push.PushToApplicationSettings; import org.jabref.gui.push.PushToApplicationSettingsDialog; +import org.jabref.gui.push.PushToApplications; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.preferences.JabRefPreferences; @@ -196,10 +198,11 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere } - private void addSettingsButton(final PushToApplication pt, JPanel p) { - JButton button = new JButton(Localization.lang("Settings for %0", pt.getApplicationName()), pt.getIcon().getIcon()); - button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, pt, pt.getSettingsPanel())); - p.add(button); + private void addSettingsButton(final PushToApplication application, JPanel panel) { + PushToApplicationSettings settings = PushToApplications.getSettings(application); + JButton button = new JButton(Localization.lang("Settings for %0", application.getApplicationName()), application.getIcon().getIcon()); + button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); + panel.add(button); } @Override diff --git a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java index f0d44765ddc..38310f93512 100644 --- a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java +++ b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java @@ -34,11 +34,10 @@ public abstract class AbstractPushToApplication implements PushToApplication { protected boolean couldNotCall; // Set to true in case the command could not be executed, e.g., if the file is not found protected boolean couldNotConnect; // Set to true in case the tunnel to the program (if one is used) does not operate protected boolean notDefined; // Set to true if the corresponding path is not defined in the preferences - protected JPanel settings; - protected final JTextField path = new JTextField(30); + protected String commandPath; protected String commandPathPreferenceKey; - protected FormBuilder builder; + protected DialogService dialogService; public AbstractPushToApplication(DialogService dialogService) { @@ -144,55 +143,12 @@ protected String getCommandName() { return null; } - @Override - public JPanel getSettingsPanel() { - initParameters(); - commandPath = Globals.prefs.get(commandPathPreferenceKey); - if (settings == null) { - initSettingsPanel(); - } - path.setText(commandPath); - return settings; - } - /** * Function to initialize parameters. Currently it is expected that commandPathPreferenceKey is set to the path of * the application. */ protected abstract void initParameters(); - /** - * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings - */ - protected void initSettingsPanel() { - builder = FormBuilder.create(); - builder.layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "p")); - StringBuilder label = new StringBuilder(Localization.lang("Path to %0", getApplicationName())); - // In case the application name and the actual command is not the same, add the command in brackets - if (getCommandName() == null) { - label.append(':'); - } else { - label.append(" (").append(getCommandName()).append("):"); - } - builder.add(label.toString()).xy(1, 1); - builder.add(path).xy(3, 1); - JButton browse = new JButton(Localization.lang("Browse")); - - FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); - - browse.addActionListener( - e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) - .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); - builder.add(browse).xy(5, 1); - settings = builder.build(); - } - - @Override - public void storeSettings() { - Globals.prefs.put(commandPathPreferenceKey, path.getText()); - } - protected String getCiteCommand() { return Globals.prefs.get(JabRefPreferences.CITE_COMMAND); } diff --git a/src/main/java/org/jabref/gui/push/PushToApplication.java b/src/main/java/org/jabref/gui/push/PushToApplication.java index 382d2a68565..0f9109212c2 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplication.java +++ b/src/main/java/org/jabref/gui/push/PushToApplication.java @@ -23,23 +23,6 @@ public interface PushToApplication { JabRefIcon getIcon(); - /** - * This method asks the implementing class to return a JPanel populated with the imlementation's options panel, if - * necessary. If the JPanel is shown to the user, and the user indicates that settings should be stored, the - * implementation's storeSettings() method will be called. This method must make sure all widgets in the panel are - * in the correct selection states. - * - * @return a JPanel containing options, or null if options are not needed. - */ - JPanel getSettingsPanel(); - - /** - * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been - * shown to the user and that the user has indicated that the settings should be stored. This method must store the - * state of the widgets in the settings panel to Globals.prefs. - */ - void storeSettings(); - /** * The actual operation. This method will not be called on the event dispatch thread, so it should not do GUI * operations without utilizing invokeLater(). diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationButton.java b/src/main/java/org/jabref/gui/push/PushToApplicationButton.java index 527a19666f3..fc3f702038c 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationButton.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationButton.java @@ -36,70 +36,16 @@ */ public class PushToApplicationButton extends SimpleCommand implements ActionListener { - private static final Icon ARROW_ICON = IconTheme.JabRefIcons.DOWN.getSmallIcon(); private final JabRefFrame frame; private final List pushActions; - private JPanel comp; - private JButton pushButton; private PushToApplication toApp; - private JPopupMenu popup; private final Map actions = new HashMap<>(); - private final Dimension buttonDim = new Dimension(23, 23); - private final JPopupMenu optPopup = new JPopupMenu(); - private final JMenuItem settings = new JMenuItem(Localization.lang("Settings")); - public PushToApplicationButton(JabRefFrame frame, List pushActions) { this.frame = frame; this.pushActions = pushActions; - init(); - } - - private void init() { - comp = new JPanel(); - comp.setLayout(new BorderLayout()); - - JButton menuButton = new JButton(PushToApplicationButton.ARROW_ICON); - menuButton.setMargin(new Insets(0, 0, 0, 0)); - menuButton.setPreferredSize( - new Dimension(menuButton.getIcon().getIconWidth(), menuButton.getIcon().getIconHeight())); - menuButton.addActionListener(e -> { - if (popup == null) { - buildPopupMenu(); - } - popup.show(comp, 0, menuButton.getHeight()); - }); - - menuButton.setToolTipText(Localization.lang("Select external application")); - - pushButton = new JButton(); - if (OS.OS_X) { - menuButton.putClientProperty("JButton.buttonType", "toolbar"); - pushButton.putClientProperty("JButton.buttonType", "toolbar"); - } - // Set the last used external application toApp = getLastUsedApplication(); - - setSelected(); - pushButton.addActionListener(this); - pushButton.addMouseListener(new PushButtonMouseListener()); - pushButton.setOpaque(false); - menuButton.setOpaque(false); - comp.setOpaque(false); - comp.add(pushButton, BorderLayout.CENTER); - comp.add(menuButton, BorderLayout.EAST); - comp.setMaximumSize(comp.getPreferredSize()); - - optPopup.add(settings); - settings.addActionListener(event -> { - JPanel options = toApp.getSettingsPanel(); - if (options != null) { - PushToApplicationSettingsDialog.showSettingsDialog(null, toApp, options); - } - }); - - buildPopupMenu(); } private PushToApplication getLastUsedApplication() { @@ -114,47 +60,6 @@ private PushToApplication getLastUsedApplication() { return pushActions.get(0); } - /** - * Create a selection menu for the available "Push" options. - */ - private void buildPopupMenu() { - popup = new JPopupMenu(); - for (PushToApplication application : pushActions) { - JMenuItem item = new JMenuItem(application.getApplicationName(), application.getIcon().getIcon()); - item.setToolTipText(application.getTooltip()); - item.addActionListener(new PopupItemActionListener(application)); - popup.add(item); - } - } - - /** - * Update the PushButton to default to the given application. - * - * @param newApplication the application to default to - */ - private void setSelected(PushToApplication newApplication) { - toApp = newApplication; - setSelected(); - } - - private void setSelected() { - pushButton.setIcon(toApp.getIcon().getIcon()); - pushButton.setToolTipText(toApp.getTooltip()); - pushButton.setPreferredSize(buttonDim); - - // Store the last used application - Globals.prefs.put(JabRefPreferences.PUSH_TO_APPLICATION, toApp.getApplicationName()); - } - - /** - * Get the toolbar component for the push button. - * - * @return The component. - */ - public Component getComponent() { - return comp; - } - public org.jabref.gui.actions.Action getMenuAction() { PushToApplication application = getLastUsedApplication(); @@ -196,58 +101,4 @@ public void execute() { } action.actionPerformed(new ActionEvent(toApp, 0, "push")); } - - class PopupItemActionListener implements ActionListener { - - private final PushToApplication application; - - - public PopupItemActionListener(PushToApplication application) { - this.application = application; - } - - @Override - public void actionPerformed(ActionEvent e) { - // Change the selection: - setSelected(application); - // Invoke the selected operation (is that expected behaviour?): - //PushToApplicationButton.this.actionPerformed(null); - // It makes sense to transfer focus to the push button after the - // menu closes: - pushButton.requestFocus(); - } - } - - class PushButtonMouseListener extends MouseAdapter { - - @Override - public void mousePressed(MouseEvent event) { - if (event.isPopupTrigger()) { - processPopupTrigger(event); - } - } - - @Override - public void mouseClicked(MouseEvent event) { - if (event.isPopupTrigger()) { - processPopupTrigger(event); - } - } - - @Override - public void mouseReleased(MouseEvent event) { - if (event.isPopupTrigger()) { - processPopupTrigger(event); - } - } - - private void processPopupTrigger(MouseEvent e) { - // We only want to show the popup if a settings panel exists for the selected - // item: - if (toApp.getSettingsPanel() != null) { - optPopup.show(pushButton, e.getX(), e.getY()); - } - - } - } } diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java new file mode 100644 index 00000000000..30c1faf65d9 --- /dev/null +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -0,0 +1,77 @@ +package org.jabref.gui.push; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import org.jabref.Globals; +import org.jabref.gui.DialogService; +import org.jabref.gui.util.DefaultTaskExecutor; +import org.jabref.gui.util.FileDialogConfiguration; +import org.jabref.logic.l10n.Localization; +import org.jabref.preferences.JabRefPreferences; + +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; + +public class PushToApplicationSettings { + protected final JTextField path = new JTextField(30); + protected JPanel settings; + protected FormBuilder builder; + protected AbstractPushToApplication application; + private DialogService dialogService; + + /** + * This method asks the implementing class to return a JPanel populated with the imlementation's options panel, if + * necessary. If the JPanel is shown to the user, and the user indicates that settings should be stored, the + * implementation's storeSettings() method will be called. This method must make sure all widgets in the panel are + * in the correct selection states. + * + * @return a JPanel containing options, or null if options are not needed. + */ + public JPanel getSettingsPanel() { + application.initParameters(); + String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); + if (settings == null) { + initSettingsPanel(); + } + path.setText(commandPath); + return settings; + } + + /** + * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings + */ + protected void initSettingsPanel() { + builder = FormBuilder.create(); + builder.layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "p")); + StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName())); + // In case the application name and the actual command is not the same, add the command in brackets + if (application.getCommandName() == null) { + label.append(':'); + } else { + label.append(" (").append(application.getCommandName()).append("):"); + } + builder.add(label.toString()).xy(1, 1); + builder.add(path).xy(3, 1); + JButton browse = new JButton(Localization.lang("Browse")); + + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + + browse.addActionListener( + e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) + .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); + builder.add(browse).xy(5, 1); + settings = builder.build(); + } + + /** + * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been + * shown to the user and that the user has indicated that the settings should be stored. This method must store the + * state of the widgets in the settings panel to Globals.prefs. + */ + public void storeSettings() { + Globals.prefs.put(application.commandPathPreferenceKey, path.getText()); + } +} diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java index ec52a2b2d36..099956c4bed 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettingsDialog.java @@ -20,8 +20,9 @@ import com.jgoodies.forms.builder.ButtonBarBuilder; public class PushToApplicationSettingsDialog { - public static void showSettingsDialog(JFrame parent, PushToApplication toApp, JPanel options) { + public static void showSettingsDialog(JFrame parent, PushToApplicationSettings toApp) { final JDialog diag = new JDialog(parent, Localization.lang("Settings"), true); + JPanel options = toApp.getSettingsPanel(); options.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); diag.getContentPane().add(options, BorderLayout.CENTER); ButtonBarBuilder bb = new ButtonBarBuilder(); diff --git a/src/main/java/org/jabref/gui/push/PushToApplications.java b/src/main/java/org/jabref/gui/push/PushToApplications.java index 558f1ff5381..335123dbdb3 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplications.java +++ b/src/main/java/org/jabref/gui/push/PushToApplications.java @@ -10,9 +10,7 @@ public class PushToApplications { private final List applications; public PushToApplications(DialogService dialogService) { - /** - * Set up the current available hoices: - */ + // Set up the current available choices: applications = new ArrayList<>(); @@ -27,4 +25,16 @@ public PushToApplications(DialogService dialogService) { public List getApplications() { return applications; } + + public static PushToApplicationSettings getSettings(PushToApplication application) { + if (application instanceof PushToEmacs) { + return new PushToEmacsSettings(); + } else if (application instanceof PushToLyx) { + return new PushToLyxSettings(); + } else if (application instanceof PushToVim) { + return new PushToVimSettings(); + } else { + return new PushToApplicationSettings(); + } + } } diff --git a/src/main/java/org/jabref/gui/push/PushToEmacs.java b/src/main/java/org/jabref/gui/push/PushToEmacs.java index 4e04434c1da..ba84a69a8c4 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacs.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacs.java @@ -26,7 +26,6 @@ public class PushToEmacs extends AbstractPushToApplication implements PushToApplication { private static final Logger LOGGER = LoggerFactory.getLogger(PushToEmacs.class); - private final JTextField additionalParams = new JTextField(30); public PushToEmacs(DialogService dialogService) { super(dialogService); @@ -42,27 +41,6 @@ public JabRefIcon getIcon() { return IconTheme.JabRefIcons.APPLICATION_EMACS; } - @Override - public JPanel getSettingsPanel() { - additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); - return super.getSettingsPanel(); - } - - @Override - public void storeSettings() { - super.storeSettings(); - Globals.prefs.put(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS, additionalParams.getText()); - } - - @Override - protected void initSettingsPanel() { - super.initSettingsPanel(); - builder.appendRows("2dlu, p, 2dlu, p"); - builder.add(Localization.lang("Additional parameters") + ":").xy(1, 3); - builder.add(additionalParams).xy(3, 3); - settings = builder.build(); - } - @Override public void pushEntries(BibDatabase database, List entries, String keys, MetaData metaData) { diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java new file mode 100644 index 00000000000..6d64205df98 --- /dev/null +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -0,0 +1,33 @@ +package org.jabref.gui.push; + +import javax.swing.JPanel; +import javax.swing.JTextField; + +import org.jabref.Globals; +import org.jabref.logic.l10n.Localization; +import org.jabref.preferences.JabRefPreferences; + +public class PushToEmacsSettings extends PushToApplicationSettings { + private final JTextField additionalParams = new JTextField(30); + + @Override + public JPanel getSettingsPanel() { + additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); + return super.getSettingsPanel(); + } + + @Override + public void storeSettings() { + super.storeSettings(); + Globals.prefs.put(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS, additionalParams.getText()); + } + + @Override + protected void initSettingsPanel() { + super.initSettingsPanel(); + builder.appendRows("2dlu, p, 2dlu, p"); + builder.add(Localization.lang("Additional parameters") + ":").xy(1, 3); + builder.add(additionalParams).xy(3, 3); + settings = builder.build(); + } +} diff --git a/src/main/java/org/jabref/gui/push/PushToLyx.java b/src/main/java/org/jabref/gui/push/PushToLyx.java index 18197ba2491..4e241113b81 100644 --- a/src/main/java/org/jabref/gui/push/PushToLyx.java +++ b/src/main/java/org/jabref/gui/push/PushToLyx.java @@ -62,14 +62,6 @@ public void operationCompleted(BasePanel panel) { } } - @Override - protected void initSettingsPanel() { - super.initSettingsPanel(); - settings = new JPanel(); - settings.add(new JLabel(Localization.lang("Path to LyX pipe") + ":")); - settings.add(path); - } - @Override public void pushEntries(BibDatabase database, final List entries, final String keyString, MetaData metaData) { diff --git a/src/main/java/org/jabref/gui/push/PushToLyxSettings.java b/src/main/java/org/jabref/gui/push/PushToLyxSettings.java new file mode 100644 index 00000000000..22ef2757c3e --- /dev/null +++ b/src/main/java/org/jabref/gui/push/PushToLyxSettings.java @@ -0,0 +1,16 @@ +package org.jabref.gui.push; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.jabref.logic.l10n.Localization; + +public class PushToLyxSettings extends PushToApplicationSettings { + @Override + protected void initSettingsPanel() { + super.initSettingsPanel(); + settings = new JPanel(); + settings.add(new JLabel(Localization.lang("Path to LyX pipe") + ":")); + settings.add(path); + } +} diff --git a/src/main/java/org/jabref/gui/push/PushToVim.java b/src/main/java/org/jabref/gui/push/PushToVim.java index e91f2fccf7a..fdfccfc67a9 100644 --- a/src/main/java/org/jabref/gui/push/PushToVim.java +++ b/src/main/java/org/jabref/gui/push/PushToVim.java @@ -25,7 +25,6 @@ public class PushToVim extends AbstractPushToApplication implements PushToApplication { private static final Logger LOGGER = LoggerFactory.getLogger(PushToVim.class); - private final JTextField vimServer = new JTextField(30); public PushToVim(DialogService dialogService) { super(dialogService); @@ -41,27 +40,6 @@ public JabRefIcon getIcon() { return IconTheme.JabRefIcons.APPLICATION_VIM; } - @Override - public JPanel getSettingsPanel() { - vimServer.setText(Globals.prefs.get(JabRefPreferences.VIM_SERVER)); - return super.getSettingsPanel(); - } - - @Override - public void storeSettings() { - super.storeSettings(); - Globals.prefs.put(JabRefPreferences.VIM_SERVER, vimServer.getText()); - } - - @Override - protected void initSettingsPanel() { - super.initSettingsPanel(); - builder.appendRows("2dlu, p"); - builder.add(Localization.lang("Vim server name") + ":").xy(1, 3); - builder.add(vimServer).xy(3, 3); - settings = builder.build(); - } - @Override public void pushEntries(BibDatabase database, List entries, String keys, MetaData metaData) { diff --git a/src/main/java/org/jabref/gui/push/PushToVimSettings.java b/src/main/java/org/jabref/gui/push/PushToVimSettings.java new file mode 100644 index 00000000000..549fcb9b4c4 --- /dev/null +++ b/src/main/java/org/jabref/gui/push/PushToVimSettings.java @@ -0,0 +1,33 @@ +package org.jabref.gui.push; + +import javax.swing.JPanel; +import javax.swing.JTextField; + +import org.jabref.Globals; +import org.jabref.logic.l10n.Localization; +import org.jabref.preferences.JabRefPreferences; + +public class PushToVimSettings extends PushToApplicationSettings { + private final JTextField vimServer = new JTextField(30); + + @Override + public JPanel getSettingsPanel() { + vimServer.setText(Globals.prefs.get(JabRefPreferences.VIM_SERVER)); + return super.getSettingsPanel(); + } + + @Override + public void storeSettings() { + super.storeSettings(); + Globals.prefs.put(JabRefPreferences.VIM_SERVER, vimServer.getText()); + } + + @Override + protected void initSettingsPanel() { + super.initSettingsPanel(); + builder.appendRows("2dlu, p"); + builder.add(Localization.lang("Vim server name") + ":").xy(1, 3); + builder.add(vimServer).xy(3, 3); + settings = builder.build(); + } +} From 09ceea00ae53cc9c362fffbd6b917ab61c7cc538 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 13 Jun 2018 23:39:09 +0200 Subject: [PATCH 19/22] Migrate Review field in entry preview to comment (#4100) * Migrate Review field in entry preview to comment * Replace review with comment in every layout file * add test and fix small error in replace * simplify test code, create getters and setters * extract Globals.prefs and mainPrefsNode as parameter * fix checkstyle * simply test using verify --- CHANGELOG.md | 3 + .../migrations/PreferencesMigrations.java | 117 +++++----- .../jabref/preferences/JabRefPreferences.java | 220 ++++++++++-------- .../layout/listrefs/listrefs.begin.layout | 30 +-- .../resource/layout/listrefs/listrefs.layout | 10 +- .../layout/listrefs/listrefs.misc.layout | 10 +- .../layout/tablerefs/tablerefs.begin.layout | 4 +- .../tablerefsabsbib.begin.layout | 26 +-- .../tablerefsabsbib/tablerefsabsbib.layout | 10 +- .../migrations/PreferencesMigrationsTest.java | 120 ++++++---- 10 files changed, 301 insertions(+), 249 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e5c1783c7..6b0aacc8ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) +- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) + + diff --git a/src/main/java/org/jabref/migrations/PreferencesMigrations.java b/src/main/java/org/jabref/migrations/PreferencesMigrations.java index fe1c9ae49a8..c7bf596d458 100644 --- a/src/main/java/org/jabref/migrations/PreferencesMigrations.java +++ b/src/main/java/org/jabref/migrations/PreferencesMigrations.java @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory; public class PreferencesMigrations { + private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesMigrations.class); private PreferencesMigrations() { @@ -31,23 +32,25 @@ private PreferencesMigrations() { * Perform checks and changes for users with a preference set from an older JabRef version. */ public static void runMigrations() { - upgradePrefsToOrgJabRef(); - upgradeSortOrder(); - upgradeFaultyEncodingStrings(); - upgradeLabelPatternToBibtexKeyPattern(); - upgradeImportFileAndDirePatterns(); - upgradeStoredCustomEntryTypes(); - upgradeKeyBindingsToJavaFX(); - addCrossRefRelatedFieldsForAutoComplete(); - upgradeObsoleteLookAndFeels(); + + Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); + + upgradePrefsToOrgJabRef(mainPrefsNode); + upgradeSortOrder(Globals.prefs); + upgradeFaultyEncodingStrings(Globals.prefs); + upgradeLabelPatternToBibtexKeyPattern(Globals.prefs); + upgradeImportFileAndDirePatterns(Globals.prefs, mainPrefsNode); + upgradeStoredCustomEntryTypes(Globals.prefs, mainPrefsNode); + upgradeKeyBindingsToJavaFX(Globals.prefs); + addCrossRefRelatedFieldsForAutoComplete(Globals.prefs); + upgradeObsoleteLookAndFeels(Globals.prefs); + upgradePreviewStyleFromReviewToComment(Globals.prefs); } /** * Migrate all preferences from net/sf/jabref to org/jabref */ - private static void upgradePrefsToOrgJabRef() { - JabRefPreferences prefs = Globals.prefs; - Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); + private static void upgradePrefsToOrgJabRef(Preferences mainPrefsNode) { try { if (mainPrefsNode.childrenNames().length != 0) { // skip further processing as prefs already have been migrated @@ -82,8 +85,7 @@ private static void copyPrefsRecursively(Preferences from, Preferences to) throw /** * Added from Jabref 2.11 beta 4 onwards to fix wrong encoding names */ - private static void upgradeFaultyEncodingStrings() { - JabRefPreferences prefs = Globals.prefs; + private static void upgradeFaultyEncodingStrings(JabRefPreferences prefs) { String defaultEncoding = prefs.get(JabRefPreferences.DEFAULT_ENCODING); if (defaultEncoding == null) { return; @@ -123,8 +125,7 @@ private static void upgradeFaultyEncodingStrings() { * these preferences, but it is only used when the new preference does not * exist */ - private static void upgradeSortOrder() { - JabRefPreferences prefs = Globals.prefs; + private static void upgradeSortOrder(JabRefPreferences prefs) { if (prefs.get(JabRefPreferences.EXPORT_IN_SPECIFIED_ORDER, null) == null) { if (prefs.getBoolean("exportInStandardOrder", false)) { @@ -151,13 +152,11 @@ private static void upgradeSortOrder() { /** * Migrate all customized entry types from versions <=3.7 */ - private static void upgradeStoredCustomEntryTypes() { - JabRefPreferences prefs = Globals.prefs; - Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); + private static void upgradeStoredCustomEntryTypes(JabRefPreferences prefs, Preferences mainPrefsNode) { try { if (mainPrefsNode.nodeExists(JabRefPreferences.CUSTOMIZED_BIBTEX_TYPES) || - mainPrefsNode.nodeExists(JabRefPreferences.CUSTOMIZED_BIBLATEX_TYPES)) { + mainPrefsNode.nodeExists(JabRefPreferences.CUSTOMIZED_BIBLATEX_TYPES)) { // skip further processing as prefs already have been migrated } else { LOGGER.info("Migrating old custom entry types."); @@ -171,8 +170,7 @@ private static void upgradeStoredCustomEntryTypes() { /** * Migrate LabelPattern configuration from versions <=3.5 to new BibtexKeyPatterns */ - private static void upgradeLabelPatternToBibtexKeyPattern() { - JabRefPreferences prefs = Globals.prefs; + private static void upgradeLabelPatternToBibtexKeyPattern(JabRefPreferences prefs) { try { Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); @@ -213,12 +211,12 @@ private static void migrateFileImportPattern(String oldStylePattern, String newS String preferenceFileNamePattern = mainPrefsNode.get(JabRefPreferences.IMPORT_FILENAMEPATTERN, null); if ((preferenceFileNamePattern != null) && - oldStylePattern.equals(preferenceFileNamePattern)) { + oldStylePattern.equals(preferenceFileNamePattern)) { // Upgrade the old-style File Name pattern to new one: mainPrefsNode.put(JabRefPreferences.IMPORT_FILENAMEPATTERN, newStylePattern); LOGGER.info("migrated old style " + JabRefPreferences.IMPORT_FILENAMEPATTERN + - " value \"" + oldStylePattern + "\" to new value \"" + - newStylePattern + "\" in the preference file"); + " value \"" + oldStylePattern + "\" to new value \"" + + newStylePattern + "\" in the preference file"); if (prefs.hasKey(JabRefPreferences.IMPORT_FILENAMEPATTERN)) { // Update also the key in the current application settings, if necessary: @@ -226,26 +224,23 @@ private static void migrateFileImportPattern(String oldStylePattern, String newS if (oldStylePattern.equals(fileNamePattern)) { prefs.put(JabRefPreferences.IMPORT_FILENAMEPATTERN, newStylePattern); LOGGER.info("migrated old style " + JabRefPreferences.IMPORT_FILENAMEPATTERN + - " value \"" + oldStylePattern + "\" to new value \"" + - newStylePattern + "\" in the running application"); + " value \"" + oldStylePattern + "\" to new value \"" + + newStylePattern + "\" in the running application"); } } } } - static void upgradeImportFileAndDirePatterns() { - JabRefPreferences prefs = Globals.prefs; - - Preferences mainPrefsNode = Preferences.userNodeForPackage(JabRefMain.class); + static void upgradeImportFileAndDirePatterns(JabRefPreferences prefs, Preferences mainPrefsNode) { // Migrate Import patterns // Check for prefs node for Version <= 4.0 if (mainPrefsNode.get(JabRefPreferences.IMPORT_FILENAMEPATTERN, null) != null) { - String[] oldStylePatterns = new String[]{"\\bibtexkey", - "\\bibtexkey\\begin{title} - \\format[RemoveBrackets]{\\title}\\end{title}"}; - String[] newStylePatterns = new String[]{"[bibtexkey]", - "[bibtexkey] - [fulltitle]"}; + String[] oldStylePatterns = new String[] {"\\bibtexkey", + "\\bibtexkey\\begin{title} - \\format[RemoveBrackets]{\\title}\\end{title}"}; + String[] newStylePatterns = new String[] {"[bibtexkey]", + "[bibtexkey] - [fulltitle]"}; for (int i = 0; i < oldStylePatterns.length; i++) { migrateFileImportPattern(oldStylePatterns[i], newStylePatterns[i], prefs, mainPrefsNode); } @@ -254,7 +249,7 @@ static void upgradeImportFileAndDirePatterns() { // the user defined old-style patterns, and the default pattern is "". } - private static void upgradeKeyBindingsToJavaFX() { + private static void upgradeKeyBindingsToJavaFX(JabRefPreferences prefs) { UnaryOperator replaceKeys = (str) -> { String result = str.replace("ctrl ", "ctrl+"); result = result.replace("shift ", "shift+"); @@ -264,14 +259,12 @@ private static void upgradeKeyBindingsToJavaFX() { return result; }; - JabRefPreferences prefs = Globals.prefs; List keys = prefs.getStringList(JabRefPreferences.BINDINGS); keys.replaceAll(replaceKeys); prefs.putStringList(JabRefPreferences.BINDINGS, keys); } - private static void addCrossRefRelatedFieldsForAutoComplete() { - JabRefPreferences prefs = Globals.prefs; + private static void addCrossRefRelatedFieldsForAutoComplete(JabRefPreferences prefs) { //LinkedHashSet because we want to retain the order and add new fields to the end Set keys = new LinkedHashSet<>(prefs.getStringList(JabRefPreferences.AUTOCOMPLETER_COMPLETE_FIELDS)); keys.add("crossref"); @@ -281,36 +274,42 @@ private static void addCrossRefRelatedFieldsForAutoComplete() { } private static void migrateTypedKeyPrefs(JabRefPreferences prefs, Preferences oldPatternPrefs) - throws BackingStoreException { + throws BackingStoreException { LOGGER.info("Found old Bibtex Key patterns which will be migrated to new version."); GlobalBibtexKeyPattern keyPattern = GlobalBibtexKeyPattern.fromPattern( - prefs.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); + prefs.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); for (String key : oldPatternPrefs.keys()) { keyPattern.addBibtexKeyPattern(key, oldPatternPrefs.get(key, null)); } prefs.putKeyPattern(keyPattern); } - private static void upgradeObsoleteLookAndFeels() { - JabRefPreferences prefs = Globals.prefs; - String currentLandF = prefs.get(JabRefPreferences.WIN_LOOK_AND_FEEL); + private static void upgradeObsoleteLookAndFeels(JabRefPreferences prefs) { + + String currentLandF = prefs.getLookAndFeel(); Stream.of("com.jgoodies.looks.windows.WindowsLookAndFeel", "com.jgoodies.looks.plastic.PlasticLookAndFeel", - "com.jgoodies.looks.plastic.Plastic3DLookAndFeel", "com.jgoodies.looks.plastic.PlasticXPLookAndFeel", - "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") - .filter(style -> style.equals(currentLandF)) - .findAny() - .ifPresent(loolAndFeel -> { - if (OS.WINDOWS) { - String windowsLandF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - prefs.put(JabRefPreferences.WIN_LOOK_AND_FEEL, windowsLandF); - LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + windowsLandF); - } else { - String nimbusLandF = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; - prefs.put(JabRefPreferences.WIN_LOOK_AND_FEEL, nimbusLandF); - LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + nimbusLandF); - } - }); + "com.jgoodies.looks.plastic.Plastic3DLookAndFeel", "com.jgoodies.looks.plastic.PlasticXPLookAndFeel", + "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") + .filter(style -> style.equals(currentLandF)) + .findAny() + .ifPresent(loolAndFeel -> { + if (OS.WINDOWS) { + String windowsLandF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; + prefs.setLookAndFeel(windowsLandF); + LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + windowsLandF); + } else { + String nimbusLandF = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; + prefs.setLookAndFeel(nimbusLandF); + LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + nimbusLandF); + } + }); + } + + static void upgradePreviewStyleFromReviewToComment(JabRefPreferences prefs) { + String currentPreviewStyle = prefs.getPreviewStyle(); + String migratedStyle = currentPreviewStyle.replace("\\begin{review}

Review: \\format[HTMLChars]{\\review} \\end{review}", "\\begin{comment}

Comment: \\format[HTMLChars]{\\comment} \\end{comment}"); + prefs.setPreviewStyle(migratedStyle); } } diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 95c534fd8ef..a0a0de60bbf 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -362,6 +362,14 @@ public class JabRefPreferences implements PreferencesService { // Id Entry Generator Preferences public static final String ID_ENTRY_GENERATOR = "idEntryGenerator"; + // Preview + private static final String PREVIEW_STYLE = "previewStyle"; + + private static final String CYCLE_PREVIEW_POS = "cyclePreviewPos"; + private static final String CYCLE_PREVIEW = "cyclePreview"; + private static final String PREVIEW_PANEL_HEIGHT = "previewPanelHeightFX"; + private static final String PREVIEW_ENABLED = "previewEnabled"; + // Auto completion private static final String AUTO_COMPLETE = "autoComplete"; private static final String AUTOCOMPLETER_FIRSTNAME_MODE = "autoCompFirstNameMode"; @@ -392,13 +400,6 @@ public class JabRefPreferences implements PreferencesService { //GroupViewMode private static final String GROUP_INTERSECT_UNION_VIEW_MODE = "groupIntersectUnionViewModes"; - // Preview - private static final String CYCLE_PREVIEW_POS = "cyclePreviewPos"; - private static final String CYCLE_PREVIEW = "cyclePreview"; - private static final String PREVIEW_PANEL_HEIGHT = "previewPanelHeightFX"; - private static final String PREVIEW_STYLE = "previewStyle"; - private static final String PREVIEW_ENABLED = "previewEnabled"; - // Helper string private static final String USER_HOME = System.getProperty("user.home"); // The only instance of this class: @@ -454,7 +455,6 @@ private JabRefPreferences() { // Set DOI to be the default ID entry generator defaults.put(ID_ENTRY_GENERATOR, DoiFetcher.NAME); - if (OS.OS_X) { defaults.put(FONT_FAMILY, "SansSerif"); defaults.put(WIN_LOOK_AND_FEEL, UIManager.getSystemLookAndFeelClassName()); @@ -761,25 +761,25 @@ private JabRefPreferences() { defaults.put(PREVIEW_PANEL_HEIGHT, 0.65); defaults.put(PREVIEW_ENABLED, Boolean.TRUE); defaults.put(PREVIEW_STYLE, - "" - + "\\bibtextype\\begin{bibtexkey} (\\bibtexkey)" - + "\\end{bibtexkey}
__NEWLINE__" - + "\\begin{author} \\format[Authors(LastFirst,Initials,Semicolon,Amp),HTMLChars]{\\author}
\\end{author}__NEWLINE__" - + "\\begin{editor} \\format[Authors(LastFirst,Initials,Semicolon,Amp),HTMLChars]{\\editor} " - + "(\\format[IfPlural(Eds.,Ed.)]{\\editor})
\\end{editor}__NEWLINE__" - + "\\begin{title} \\format[HTMLChars]{\\title} \\end{title}
__NEWLINE__" - + "\\begin{chapter} \\format[HTMLChars]{\\chapter}
\\end{chapter}__NEWLINE__" - + "\\begin{journal} \\format[HTMLChars]{\\journal}, \\end{journal}__NEWLINE__" - // Include the booktitle field for @inproceedings, @proceedings, etc. - + "\\begin{booktitle} \\format[HTMLChars]{\\booktitle}, \\end{booktitle}__NEWLINE__" - + "\\begin{school} \\format[HTMLChars]{\\school}, \\end{school}__NEWLINE__" - + "\\begin{institution} \\format[HTMLChars]{\\institution}, \\end{institution}__NEWLINE__" - + "\\begin{publisher} \\format[HTMLChars]{\\publisher}, \\end{publisher}__NEWLINE__" - + "\\begin{year}\\year\\end{year}\\begin{volume}, \\volume\\end{volume}" - + "\\begin{pages}, \\format[FormatPagesForHTML]{\\pages} \\end{pages}__NEWLINE__" - + "\\begin{abstract}

Abstract: \\format[HTMLChars]{\\abstract} \\end{abstract}__NEWLINE__" - + "\\begin{review}

Review: \\format[HTMLChars]{\\review} \\end{review}" - + "__NEWLINE__

"); + "" + + "\\bibtextype\\begin{bibtexkey} (\\bibtexkey)" + + "\\end{bibtexkey}
__NEWLINE__" + + "\\begin{author} \\format[Authors(LastFirst,Initials,Semicolon,Amp),HTMLChars]{\\author}
\\end{author}__NEWLINE__" + + "\\begin{editor} \\format[Authors(LastFirst,Initials,Semicolon,Amp),HTMLChars]{\\editor} " + + "(\\format[IfPlural(Eds.,Ed.)]{\\editor})
\\end{editor}__NEWLINE__" + + "\\begin{title} \\format[HTMLChars]{\\title} \\end{title}
__NEWLINE__" + + "\\begin{chapter} \\format[HTMLChars]{\\chapter}
\\end{chapter}__NEWLINE__" + + "\\begin{journal} \\format[HTMLChars]{\\journal}, \\end{journal}__NEWLINE__" + // Include the booktitle field for @inproceedings, @proceedings, etc. + + "\\begin{booktitle} \\format[HTMLChars]{\\booktitle}, \\end{booktitle}__NEWLINE__" + + "\\begin{school} \\format[HTMLChars]{\\school}, \\end{school}__NEWLINE__" + + "\\begin{institution} \\format[HTMLChars]{\\institution}, \\end{institution}__NEWLINE__" + + "\\begin{publisher} \\format[HTMLChars]{\\publisher}, \\end{publisher}__NEWLINE__" + + "\\begin{year}\\year\\end{year}\\begin{volume}, \\volume\\end{volume}" + + "\\begin{pages}, \\format[FormatPagesForHTML]{\\pages} \\end{pages}__NEWLINE__" + + "\\begin{abstract}

Abstract: \\format[HTMLChars]{\\abstract} \\end{abstract}__NEWLINE__" + + "\\begin{comment}

Comment: \\format[HTMLChars]{\\comment} \\end{comment}" + + "__NEWLINE__

"); setLanguageDependentDefaultValues(); } @@ -874,11 +874,11 @@ private static Optional getNextUnit(Reader data) throws IOException { private static void insertDefaultCleanupPreset(Map storage) { EnumSet deactivatedJobs = EnumSet.of( - CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS, - CleanupPreset.CleanupStep.MOVE_PDF, - CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS, - CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX, - CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX); + CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS, + CleanupPreset.CleanupStep.MOVE_PDF, + CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS, + CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX, + CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX); CleanupPreset preset = new CleanupPreset(EnumSet.complementOf(deactivatedJobs), Cleanups.DEFAULT_SAVE_ACTIONS); @@ -1226,9 +1226,9 @@ public List loadCustomEntryTypes(BibDatabaseMode bibDatabaseMod Preferences prefsNode = getPrefsNodeForCustomizedEntryTypes(bibDatabaseMode); try { Arrays.stream(prefsNode.keys()) - .map(key -> prefsNode.get(key, null)) - .filter(Objects::nonNull) - .forEach(typeString -> CustomEntryType.parse(typeString).ifPresent(storedEntryTypes::add)); + .map(key -> prefsNode.get(key, null)) + .filter(Objects::nonNull) + .forEach(typeString -> CustomEntryType.parse(typeString).ifPresent(storedEntryTypes::add)); } catch (BackingStoreException e) { LOGGER.info("Parsing customized entry types failed.", e); } @@ -1310,7 +1310,7 @@ public void exportPreferences(String filename) throws JabRefException { prefs.exportSubtree(os); } catch (BackingStoreException | IOException ex) { throw new JabRefException("Could not export preferences", Localization.lang("Could not export preferences"), - ex); + ex); } } @@ -1327,7 +1327,7 @@ public void importPreferences(String filename) throws JabRefException { Preferences.importPreferences(is); } catch (InvalidPreferencesFormatException | IOException ex) { throw new JabRefException("Could not import preferences", Localization.lang("Could not import preferences"), - ex); + ex); } } @@ -1369,20 +1369,20 @@ public FileDirectoryPreferences getFileDirectoryPreferences() { List fields = Arrays.asList(FieldName.FILE, FieldName.PDF, FieldName.PS); Map fieldDirectories = new HashMap<>(); fields.stream().forEach( - fieldName -> fieldDirectories.put(fieldName, get(fieldName + FileDirectoryPreferences.DIR_SUFFIX))); + fieldName -> fieldDirectories.put(fieldName, get(fieldName + FileDirectoryPreferences.DIR_SUFFIX))); return new FileDirectoryPreferences(getUser(), fieldDirectories, - getBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR)); + getBoolean(JabRefPreferences.BIB_LOC_AS_PRIMARY_DIR)); } public UpdateFieldPreferences getUpdateFieldPreferences() { return new UpdateFieldPreferences(getBoolean(USE_OWNER), getBoolean(OVERWRITE_OWNER), get(DEFAULT_OWNER), - getBoolean(USE_TIME_STAMP), getBoolean(OVERWRITE_TIME_STAMP), get(TIME_STAMP_FIELD), - get(TIME_STAMP_FORMAT)); + getBoolean(USE_TIME_STAMP), getBoolean(OVERWRITE_TIME_STAMP), get(TIME_STAMP_FIELD), + get(TIME_STAMP_FORMAT)); } public LatexFieldFormatterPreferences getLatexFieldFormatterPreferences() { return new LatexFieldFormatterPreferences(getBoolean(RESOLVE_STRINGS_ALL_FIELDS), - getStringList(DO_NOT_RESOLVE_STRINGS_FOR), getFieldContentParserPreferences()); + getStringList(DO_NOT_RESOLVE_STRINGS_FOR), getFieldContentParserPreferences()); } public FieldContentParserPreferences getFieldContentParserPreferences() { @@ -1391,13 +1391,13 @@ public FieldContentParserPreferences getFieldContentParserPreferences() { public boolean isKeywordSyncEnabled() { return getBoolean(JabRefPreferences.SPECIALFIELDSENABLED) - && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS); + && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS); } public ImportFormatPreferences getImportFormatPreferences() { return new ImportFormatPreferences(customImports, getDefaultEncoding(), getKeywordDelimiter(), - getBibtexKeyPatternPreferences(), getFieldContentParserPreferences(), - isKeywordSyncEnabled()); + getBibtexKeyPatternPreferences(), getFieldContentParserPreferences(), + isKeywordSyncEnabled()); } public SavePreferences loadForExportFromPreferences() { @@ -1416,9 +1416,9 @@ public SavePreferences loadForExportFromPreferences() { Boolean takeMetadataSaveOrderInAccount = false; Boolean reformatFile = this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT); LatexFieldFormatterPreferences latexFieldFormatterPreferences = this.getLatexFieldFormatterPreferences(); - GlobalBibtexKeyPattern globalCiteKeyPattern = this.getKeyPattern(); + GlobalBibtexKeyPattern globalCiteKeyPattern = this.getKeyPattern(); return new SavePreferences(saveInOriginalOrder, saveOrder, encoding, makeBackup, saveType, - takeMetadataSaveOrderInAccount, reformatFile, latexFieldFormatterPreferences, globalCiteKeyPattern); + takeMetadataSaveOrderInAccount, reformatFile, latexFieldFormatterPreferences, globalCiteKeyPattern); } public SavePreferences loadForSaveFromPreferences() { @@ -1430,9 +1430,9 @@ public SavePreferences loadForSaveFromPreferences() { Boolean takeMetadataSaveOrderInAccount = true; Boolean reformatFile = this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT); LatexFieldFormatterPreferences latexFieldFormatterPreferences = this.getLatexFieldFormatterPreferences(); - GlobalBibtexKeyPattern globalCiteKeyPattern = this.getKeyPattern(); + GlobalBibtexKeyPattern globalCiteKeyPattern = this.getKeyPattern(); return new SavePreferences(saveInOriginalOrder, saveOrder, encoding, makeBackup, saveType, - takeMetadataSaveOrderInAccount, reformatFile, latexFieldFormatterPreferences, globalCiteKeyPattern); + takeMetadataSaveOrderInAccount, reformatFile, latexFieldFormatterPreferences, globalCiteKeyPattern); } public ExporterFactory getExporterFactory(JournalAbbreviationLoader abbreviationLoader) { @@ -1445,8 +1445,8 @@ public ExporterFactory getExporterFactory(JournalAbbreviationLoader abbreviation public BibtexKeyPatternPreferences getBibtexKeyPatternPreferences() { return new BibtexKeyPatternPreferences(get(KEY_PATTERN_REGEX), - get(KEY_PATTERN_REPLACEMENT), getBoolean(KEY_GEN_ALWAYS_ADD_LETTER), getBoolean(KEY_GEN_FIRST_LETTER_A), - getBoolean(ENFORCE_LEGAL_BIBTEX_KEY), getKeyPattern(), getKeywordDelimiter()); + get(KEY_PATTERN_REPLACEMENT), getBoolean(KEY_GEN_ALWAYS_ADD_LETTER), getBoolean(KEY_GEN_FIRST_LETTER_A), + getBoolean(ENFORCE_LEGAL_BIBTEX_KEY), getKeyPattern(), getKeywordDelimiter()); } public TimestampPreferences getTimestampPreferences() { @@ -1454,27 +1454,27 @@ public TimestampPreferences getTimestampPreferences() { } public LayoutFormatterPreferences getLayoutFormatterPreferences( - JournalAbbreviationLoader journalAbbreviationLoader) { + JournalAbbreviationLoader journalAbbreviationLoader) { Objects.requireNonNull(journalAbbreviationLoader); return new LayoutFormatterPreferences(getNameFormatterPreferences(), getJournalAbbreviationPreferences(), - getFileLinkPreferences(), journalAbbreviationLoader); + getFileLinkPreferences(), journalAbbreviationLoader); } public XmpPreferences getXMPPreferences() { return new XmpPreferences(getBoolean(USE_XMP_PRIVACY_FILTER), getStringList(XMP_PRIVACY_FILTERS), - getKeywordDelimiter()); + getKeywordDelimiter()); } public OpenOfficePreferences getOpenOfficePreferences() { return new OpenOfficePreferences( - this.get(JabRefPreferences.OO_JARS_PATH), - this.get(JabRefPreferences.OO_EXECUTABLE_PATH), - this.get(JabRefPreferences.OO_PATH), - this.getBoolean(JabRefPreferences.OO_USE_ALL_OPEN_BASES), - this.getBoolean(JabRefPreferences.OO_SYNC_WHEN_CITING), - this.getBoolean(JabRefPreferences.OO_SHOW_PANEL), - this.getStringList(JabRefPreferences.OO_EXTERNAL_STYLE_FILES), - this.get(JabRefPreferences.OO_BIBLIOGRAPHY_STYLE_FILE)); + this.get(JabRefPreferences.OO_JARS_PATH), + this.get(JabRefPreferences.OO_EXECUTABLE_PATH), + this.get(JabRefPreferences.OO_PATH), + this.getBoolean(JabRefPreferences.OO_USE_ALL_OPEN_BASES), + this.getBoolean(JabRefPreferences.OO_SYNC_WHEN_CITING), + this.getBoolean(JabRefPreferences.OO_SHOW_PANEL), + this.getStringList(JabRefPreferences.OO_EXTERNAL_STYLE_FILES), + this.get(JabRefPreferences.OO_BIBLIOGRAPHY_STYLE_FILE)); } public void setOpenOfficePreferences(OpenOfficePreferences openOfficePreferences) { @@ -1494,8 +1494,8 @@ private NameFormatterPreferences getNameFormatterPreferences() { public FileLinkPreferences getFileLinkPreferences() { return new FileLinkPreferences( - Collections.singletonList(get(FieldName.FILE + FileDirectoryPreferences.DIR_SUFFIX)), - fileDirForDatabase); + Collections.singletonList(get(FieldName.FILE + FileDirectoryPreferences.DIR_SUFFIX)), + fileDirForDatabase); } public JabRefPreferences storeVersionPreferences(VersionPreferences versionPreferences) { @@ -1548,8 +1548,8 @@ public ProxyPreferences getProxyPreferences() { public ProtectedTermsPreferences getProtectedTermsPreferences() { return new ProtectedTermsPreferences(getStringList(PROTECTED_TERMS_ENABLED_INTERNAL), - getStringList(PROTECTED_TERMS_ENABLED_EXTERNAL), getStringList(PROTECTED_TERMS_DISABLED_INTERNAL), - getStringList(PROTECTED_TERMS_DISABLED_EXTERNAL)); + getStringList(PROTECTED_TERMS_ENABLED_EXTERNAL), getStringList(PROTECTED_TERMS_DISABLED_INTERNAL), + getStringList(PROTECTED_TERMS_DISABLED_EXTERNAL)); } public void setProtectedTermsPreferences(ProtectedTermsLoader loader) { @@ -1584,12 +1584,12 @@ public void setProtectedTermsPreferences(ProtectedTermsLoader loader) { @Override public JournalAbbreviationPreferences getJournalAbbreviationPreferences() { return new JournalAbbreviationPreferences(getStringList(EXTERNAL_JOURNAL_LISTS), get(PERSONAL_JOURNAL_LIST), - getBoolean(USE_IEEE_ABRV), getDefaultEncoding()); + getBoolean(USE_IEEE_ABRV), getDefaultEncoding()); } public CleanupPreferences getCleanupPreferences(JournalAbbreviationLoader journalAbbreviationLoader) { return new CleanupPreferences(get(IMPORT_FILENAMEPATTERN), get(IMPORT_FILEDIRPATTERN), - getLayoutFormatterPreferences(journalAbbreviationLoader), getFileDirectoryPreferences()); + getLayoutFormatterPreferences(journalAbbreviationLoader), getFileDirectoryPreferences()); } public CleanupPreset getCleanupPreset() { @@ -1627,7 +1627,7 @@ public CleanupPreset getCleanupPreset() { } FieldFormatterCleanups formatterCleanups = Cleanups.parse( - this.getStringList(JabRefPreferences.CLEANUP_FORMATTERS)); + this.getStringList(JabRefPreferences.CLEANUP_FORMATTERS)); return new CleanupPreset(activeJobs, formatterCleanups); } @@ -1639,9 +1639,9 @@ public void setCleanupPreset(CleanupPreset cleanupPreset) { this.putBoolean(JabRefPreferences.CLEANUP_MAKE_PATHS_RELATIVE, cleanupPreset.isActive(CleanupPreset.CleanupStep.MAKE_PATHS_RELATIVE)); this.putBoolean(JabRefPreferences.CLEANUP_RENAME_PDF, cleanupPreset.isActive(CleanupPreset.CleanupStep.RENAME_PDF)); this.putBoolean(JabRefPreferences.CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS, - cleanupPreset.isActive(CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS)); + cleanupPreset.isActive(CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS)); this.putBoolean(JabRefPreferences.CLEANUP_UPGRADE_EXTERNAL_LINKS, - cleanupPreset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS)); + cleanupPreset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS)); this.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBLATEX, cleanupPreset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX)); this.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBTEX, cleanupPreset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX)); this.putBoolean(JabRefPreferences.CLEANUP_FIX_FILE_LINKS, cleanupPreset.isActive(CleanupPreset.CleanupStep.FIX_FILE_LINKS)); @@ -1741,20 +1741,20 @@ public void storeJournalAbbreviationPreferences(JournalAbbreviationPreferences a public AutoLinkPreferences getAutoLinkPreferences() { return new AutoLinkPreferences( - getBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY), - get(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY), - getBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY), - getKeywordDelimiter()); + getBoolean(JabRefPreferences.AUTOLINK_USE_REG_EXP_SEARCH_KEY), + get(JabRefPreferences.AUTOLINK_REG_EXP_SEARCH_EXPRESSION_KEY), + getBoolean(JabRefPreferences.AUTOLINK_EXACT_KEY_ONLY), + getKeywordDelimiter()); } public AutoCompletePreferences getAutoCompletePreferences() { return new AutoCompletePreferences( - getBoolean(AUTO_COMPLETE), - AutoCompleteFirstNameMode.parse(get(AUTOCOMPLETER_FIRSTNAME_MODE)), - getBoolean(AUTOCOMPLETER_LAST_FIRST), - getBoolean(AUTOCOMPLETER_FIRST_LAST), - getStringList(AUTOCOMPLETER_COMPLETE_FIELDS), - getJournalAbbreviationPreferences()); + getBoolean(AUTO_COMPLETE), + AutoCompleteFirstNameMode.parse(get(AUTOCOMPLETER_FIRSTNAME_MODE)), + getBoolean(AUTOCOMPLETER_LAST_FIRST), + getBoolean(AUTOCOMPLETER_FIRST_LAST), + getStringList(AUTOCOMPLETER_COMPLETE_FIELDS), + getJournalAbbreviationPreferences()); } public void storeAutoCompletePreferences(AutoCompletePreferences autoCompletePreferences) { @@ -1820,16 +1820,16 @@ private List createSpecialFieldColumns() { private Map createColumnWidths() { List columns = getStringList(COLUMN_NAMES); List widths = getStringList(COLUMN_WIDTHS) - .stream() - .map(string -> { - try { - return Double.parseDouble(string); - } catch (NumberFormatException e) { - LOGGER.error("Exception while parsing column widths. Choosing default.", e); - return BibtexSingleField.DEFAULT_FIELD_LENGTH; - } - }) - .collect(Collectors.toList()); + .stream() + .map(string -> { + try { + return Double.parseDouble(string); + } catch (NumberFormatException e) { + LOGGER.error("Exception while parsing column widths. Choosing default.", e); + return BibtexSingleField.DEFAULT_FIELD_LENGTH; + } + }) + .collect(Collectors.toList()); Map map = new TreeMap<>(); for (int i = 0; i < columns.size(); i++) { @@ -1840,21 +1840,20 @@ private Map createColumnWidths() { public ColumnPreferences getColumnPreferences() { return new ColumnPreferences( - getBoolean(FILE_COLUMN), - getBoolean(URL_COLUMN), - getBoolean(PREFER_URL_DOI), - getBoolean(ARXIV_COLUMN), - getStringList(COLUMN_NAMES), - createSpecialFieldColumns(), - createExtraFileColumns(), - createColumnWidths() - ); + getBoolean(FILE_COLUMN), + getBoolean(URL_COLUMN), + getBoolean(PREFER_URL_DOI), + getBoolean(ARXIV_COLUMN), + getStringList(COLUMN_NAMES), + createSpecialFieldColumns(), + createExtraFileColumns(), + createColumnWidths()); } public MainTablePreferences getMainTablePreferences() { return new MainTablePreferences( - getColumnPreferences(), - getBoolean(AUTO_RESIZE_MODE)); + getColumnPreferences(), + getBoolean(AUTO_RESIZE_MODE)); } @Override @@ -1875,4 +1874,21 @@ public GroupViewMode getGroupViewMode() { public void setGroupViewMode(GroupViewMode mode) { put(GROUP_INTERSECT_UNION_VIEW_MODE, mode.name()); } + + public String getLookAndFeel() { + return get(WIN_LOOK_AND_FEEL); + } + + public void setLookAndFeel(String lookAndFeelClassName) { + put(WIN_LOOK_AND_FEEL, lookAndFeelClassName); + } + + public void setPreviewStyle(String previewStyle) { + put(PREVIEW_STYLE, previewStyle); + } + + public String getPreviewStyle() { + return get(PREVIEW_STYLE); + } + } diff --git a/src/main/resources/resource/layout/listrefs/listrefs.begin.layout b/src/main/resources/resource/layout/listrefs/listrefs.begin.layout index b3c7469a96d..2d4118c7fcc 100644 --- a/src/main/resources/resource/layout/listrefs/listrefs.begin.layout +++ b/src/main/resources/resource/layout/listrefs/listrefs.begin.layout @@ -24,7 +24,7 @@ // Search settings var searchAbstract = true; // search in abstract -var searchReview = true; // search in review +var searchComment = true; // search in comment var noSquiggles = true; // ignore diacritics when searching var searchRegExp = false; // enable RegExp searches @@ -65,7 +65,7 @@ function loadTableData() { searchTable = document.getElementById('qs_table'); var allRows = searchTable.getElementsByTagName('tbody')[0].getElementsByTagName('tr'); - // split all rows into entryRows and infoRows (e.g. abstract, review, bibtex) + // split all rows into entryRows and infoRows (e.g. abstract, comment, bibtex) entryRows = new Array(); infoRows = new Array(); absRows = new Array(); revRows = new Array(); // get data from each row @@ -81,11 +81,11 @@ function loadTableData() { j ++; } else { infoRows[k++] = allRows[i]; - // check for abstract/review + // check for abstract/comment if (allRows[i].className.match(/abstract/)) { absRows.push(allRows[i]); absRowsData[j-1] = stripDiacritics(getTextContent(allRows[i])); - } else if (allRows[i].className.match(/review/)) { + } else if (allRows[i].className.match(/comment/)) { revRows.push(allRows[i]); revRowsData[j-1] = stripDiacritics(getTextContent(allRows[i])); } @@ -141,7 +141,7 @@ function quickSearch(){ if(searchAbstract && absRowsData[i]!=undefined) { if (absRowsData[i].search(textRegExp) != -1){ found=true; } } - if(searchReview && revRowsData[i]!=undefined) { + if(searchComment && revRowsData[i]!=undefined) { if (revRowsData[i].search(textRegExp) != -1){ found=true; } } } @@ -217,8 +217,8 @@ function toggleInfo(articleid,info) { if (abs && info == 'abstract') { abs.className.indexOf('noshow') == -1?abs.className = 'abstract noshow':abs.className = 'abstract show'; - } else if (rev && info == 'review') { - rev.className.indexOf('noshow') == -1?rev.className = 'review noshow':rev.className = 'review show'; + } else if (rev && info == 'comment') { + rev.className.indexOf('noshow') == -1?rev.className = 'comment noshow':rev.className = 'comment show'; } else if (bib && info == 'bibtex') { bib.className.indexOf('noshow') == -1?bib.className = 'bibtex noshow':bib.className = 'bibtex show'; } else { @@ -240,12 +240,12 @@ function toggleInfo(articleid,info) { } } - // When there's a combination of abstract/review/bibtex showing, need to add class for correct styling + // When there's a combination of abstract/comment/bibtex showing, need to add class for correct styling if(absshow) { (revshow||bibshow)?abs.className = 'abstract nextshow':abs.className = 'abstract'; } if (revshow) { - bibshow?rev.className = 'review nextshow': rev.className = 'review'; + bibshow?rev.className = 'comment nextshow': rev.className = 'comment'; } } @@ -304,8 +304,8 @@ function updateSetting(obj){ searchAbstract=!searchAbstract; redoQS(); break; - case "opt_searchRev": - searchReview=!searchReview; + case "opt_searchComment": + searchComment=!searchComment; redoQS(); break; case "opt_useRegExp": @@ -322,12 +322,12 @@ function updateSetting(obj){ function initPreferences(){ if(searchAbstract){document.getElementById("opt_searchAbs").checked = true;} - if(searchReview){document.getElementById("opt_searchRev").checked = true;} + if(searchComment){document.getElementById("opt_searchComment").checked = true;} if(noSquiggles){document.getElementById("opt_noAccents").checked = true;} if(searchRegExp){document.getElementById("opt_useRegExp").checked = true;} if(numAbs==0) {document.getElementById("opt_searchAbs").parentNode.style.display = 'none';} - if(numRev==0) {document.getElementById("opt_searchRev").parentNode.style.display = 'none';} + if(numRev==0) {document.getElementById("opt_searchComment").parentNode.style.display = 'none';} } function toggleSettings(){ @@ -375,7 +375,7 @@ td a:hover { text-decoration: underline; } tr.noshow { display: none;} tr.highlight td { background-color: #EFEFEF; border-top: 2px #2E2E2E solid; font-weight: bold; } -tr.abstract td, tr.review td, tr.bibtex td { background-color: #EFEFEF; text-align: justify; border-bottom: 2px #2E2E2E solid; } +tr.abstract td, tr.comment td, tr.bibtex td { background-color: #EFEFEF; text-align: justify; border-bottom: 2px #2E2E2E solid; } tr.nextshow td { border-bottom-style: none; } tr.bibtex pre { width: 100%; overflow: auto; white-space: pre-wrap;} @@ -396,7 +396,7 @@ p.infolinks { margin: 0.3em 0em 0em 0em; padding: 0px; }