diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dd31e96b03..10fca0048e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## [Unreleased] ### 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 - Add tab which shows the MathSciNet review website if the `MRNumber` field is present. - Partly switched to a new UI technology (JavaFX). - Redesigned group panel. @@ -61,9 +62,10 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - 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 programms 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) + - 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 programms 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) ### Removed diff --git a/README.md b/README.md index a40e93bc1db..07d1a505c54 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,7 @@ [![Build Status](https://travis-ci.org/JabRef/jabref.svg?branch=master)](https://travis-ci.org/JabRef/jabref) [![Dependency Status](https://www.versioneye.com/user/projects/557f2723386664002000009c/badge.svg?style=flat)](https://www.versioneye.com/user/projects/557f2723386664002000009c) [![codecov.io](https://codecov.io/github/JabRef/jabref/coverage.svg?branch=master)](https://codecov.io/github/JabRef/jabref?branch=master) -[![Donation](https://img.shields.io/badge/donate-something-orange.svg)](https://donations.jabref.org) -[![Issue Stats](http://www.issuestats.com/github/jabref/jabref/badge/pr)](http://www.issuestats.com/github/jabref/jabref) -[![Issue Stats](http://www.issuestats.com/github/jabref/jabref/badge/issue)](http://www.issuestats.com/github/jabref/jabref) +[![Donation](https://img.shields.io/badge/donate-to%20jabref-orange.svg)](https://donations.jabref.org) This version is a development version. Features may not work as expected. diff --git a/buildres/JabRef.VisualElementsManifest.xml b/buildres/JabRef.VisualElementsManifest.xml index 4a19accb134..6d28051ba84 100644 --- a/buildres/JabRef.VisualElementsManifest.xml +++ b/buildres/JabRef.VisualElementsManifest.xml @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index a341a2f6962..b5674c29c64 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -179,7 +179,7 @@ private void openWindow() { for (int i = 0; (i < bibDatabases.size()) && (i < JabRefGUI.getMainFrame().getBasePanelCount()); i++) { ParserResult pr = bibDatabases.get(i); BasePanel panel = JabRefGUI.getMainFrame().getBasePanelAt(i); - OpenDatabaseAction.performPostOpenActions(panel, pr, true); + OpenDatabaseAction.performPostOpenActions(panel, pr); } LOGGER.debug("Finished adding panels"); diff --git a/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java b/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java index d37a29901fd..7cfcfd121c5 100644 --- a/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java +++ b/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java @@ -10,10 +10,10 @@ import java.util.concurrent.atomic.AtomicInteger; import org.jabref.Globals; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fetcher.CrossRef; import org.jabref.logic.importer.fileformat.BibtexParser; -import org.jabref.logic.identifier.DOI; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index a182a08c5fd..6aec27cd702 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -14,10 +14,10 @@ import java.util.Optional; import org.jabref.Globals; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.fetcher.DoiFetcher; import org.jabref.logic.importer.fileformat.BibtexParser; -import org.jabref.logic.identifier.DOI; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; diff --git a/src/main/java/org/jabref/gui/IconTheme.java b/src/main/java/org/jabref/gui/IconTheme.java index e1f99c82a3e..dc7a3e8d0a7 100644 --- a/src/main/java/org/jabref/gui/IconTheme.java +++ b/src/main/java/org/jabref/gui/IconTheme.java @@ -14,7 +14,9 @@ import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -341,6 +343,18 @@ public FontBasedIcon createSmallIcon() { public FontBasedIcon createWithNewColor(Color newColor) { return new FontBasedIcon(this.iconCode, newColor, this.size); } + } + public static List getLogoSet() { + List jabrefLogos = new ArrayList<>(); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon16")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon20")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon32")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon40")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon48")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon64")).getImage()); + jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon128")).getImage()); + + return jabrefLogos; } } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index dbdad1539bf..09d3b4b761a 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -30,7 +30,6 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; @@ -551,7 +550,7 @@ private void init() { setGlassPane(glassPane); setTitle(FRAME_TITLE); - setIconImage(new ImageIcon(IconTheme.getIconUrl("jabrefIcon48")).getImage()); + setIconImages(IconTheme.getLogoSet()); setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { diff --git a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java b/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java index 63dbbfec2bd..2974c4becdb 100644 --- a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java +++ b/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java @@ -8,8 +8,8 @@ import org.jabref.JabRefGUI; import org.jabref.gui.ClipBoardManager; -import org.jabref.logic.l10n.Localization; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.l10n.Localization; /** * Copies the doi url to the clipboard diff --git a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java index ce49e4689fd..9d3903f0e9a 100644 --- a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java @@ -29,9 +29,9 @@ import org.jabref.gui.filelist.FileListEntryEditor; import org.jabref.gui.filelist.FileListTableModel; import org.jabref.gui.undo.UndoableFieldChange; -import org.jabref.logic.l10n.Localization; import org.jabref.logic.identifier.DOI; import org.jabref.logic.identifier.Eprint; +import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java index e776e1d18e0..1c169c575ef 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldExtraComponents.java @@ -31,11 +31,11 @@ import org.jabref.gui.fieldeditors.FieldEditor; import org.jabref.gui.mergeentries.FetchAndMergeEntry; import org.jabref.gui.undo.UndoableFieldChange; +import org.jabref.logic.identifier.DOI; +import org.jabref.logic.identifier.ISBN; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.URLUtil; -import org.jabref.logic.identifier.DOI; -import org.jabref.logic.identifier.ISBN; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java b/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java index 19483c75e4e..4dac6274a20 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java @@ -3,11 +3,14 @@ import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.StringJoiner; import javax.swing.BoxLayout; @@ -40,7 +43,7 @@ class FileAnnotationTab extends JPanel { private final JList annotationList = new JList<>(); private final JScrollPane annotationScrollPane = new JScrollPane(); - private final JLabel fileNameLabel = new JLabel(Localization.lang("Filename"),JLabel.CENTER); + private final JLabel fileNameLabel = new JLabel(Localization.lang("Filename"), JLabel.CENTER); private final JComboBox fileNameComboBox = new JComboBox<>(); private final JScrollPane fileNameScrollPane = new JScrollPane(); private final JLabel authorLabel = new JLabel(Localization.lang("Author"), JLabel.CENTER); @@ -71,9 +74,8 @@ class FileAnnotationTab extends JPanel { FileAnnotationTab(EntryEditor parent) { this.parent = parent; setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); - listModel = new DefaultListModel<>(); + listModel = new DefaultListModel<>(); this.isInitialized = false; - } public FileAnnotationTab initializeTab(FileAnnotationTab tab) { @@ -99,7 +101,6 @@ public FileAnnotationTab initializeTab(FileAnnotationTab tab, Map annotations) { listModel.clear(); if (annotations.isEmpty()) { - listModel.addElement(new FileAnnotation("", "", "", 0, Localization.lang("File has no attached annotations"), "")); + listModel.addElement(new FileAnnotation("", LocalDateTime.now(), 0, Localization.lang("File has no attached annotations"), "", Optional.empty())); } else { Comparator byPage = Comparator.comparingInt(FileAnnotation::getPage); annotations.stream() - .filter(annotation -> !(null == annotation.getContent())) + .filter(annotation -> (null != annotation.getContent())) .filter(annotation -> annotation.getAnnotationType().equals(FDFAnnotationHighlight.SUBTYPE) - || (null == annotation.getLinkedFileAnnotation())) + || !annotation.hasLinkedAnnotation()) .sorted(byPage) .forEach(listModel::addElement); } @@ -149,13 +151,14 @@ private void updateShownAnnotations(List annotations) { /** * Updates the text fields showing meta data and the content from the selected annotation + * * @param annotation pdf annotation which data should be shown in the text fields */ private void updateTextFields(FileAnnotation annotation) { authorArea.setText(annotation.getAuthor()); - dateArea.setText(annotation.getDate()); + dateArea.setText(annotation.getTimeModified().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); pageArea.setText(String.valueOf(annotation.getPage())); - updateContentAndHighlightTextfields(annotation); + updateContentAndHighlightTextAreas(annotation); } /** @@ -180,22 +183,22 @@ private void setUpGui() { .columns("pref, $lcgap, pref:grow") .rows("pref, $lg, fill:pref:grow, $lg, pref") .padding(Paddings.DIALOG) - .add(fileNameLabel).xy(1,1, "left, top") + .add(fileNameLabel).xy(1, 1, "left, top") .add(fileNameScrollPane).xyw(2, 1, 2) .add(annotationScrollPane).xyw(1, 3, 3) .build(); annotationScrollPane.setViewportView(annotationList); - JPanel informationPanel = FormBuilder.create() + JPanel informationPanel = FormBuilder.create() .columns("pref, $lcgap, pref:grow") .rows("pref, $lg, pref, $lg, pref, $lg, pref, $lg, pref:grow, $lg, pref:grow, $lg, fill:pref") .padding(Paddings.DIALOG) - .add(authorLabel).xy(1,3, "left, top") - .add(authorScrollPane).xy(3,3) - .add(dateLabel).xy(1,5, "left, top") - .add(dateScrollPane).xy(3,5) - .add(pageLabel).xy(1,7, "left, top") - .add(pageScrollPane).xy(3,7) + .add(authorLabel).xy(1, 3, "left, top") + .add(authorScrollPane).xy(3, 3) + .add(dateLabel).xy(1, 5, "left, top") + .add(dateScrollPane).xy(3, 5) + .add(pageLabel).xy(1, 7, "left, top") + .add(pageScrollPane).xy(3, 7) .add(annotationTextLabel).xy(1, 9, "left, top") .add(annotationTextScrollPane).xywh(3, 9, 1, 2) .add(highlightTxtLabel).xy(1, 11, "left, top") @@ -237,7 +240,7 @@ private void setUpGui() { .build()); } - private JPanel setUpButtons(){ + private JPanel setUpButtons() { JPanel buttonPanel = new JPanel(new GridBagLayout()); GridBagConstraints buttonConstraints = new GridBagConstraints(); @@ -262,7 +265,7 @@ private JPanel setUpButtons(){ /** * Copies the meta and content information of the pdf annotation to the clipboard */ - private void copyToClipboard(){ + private void copyToClipboard() { StringJoiner sj = new StringJoiner(System.getProperty("line.separator")); sj.add("Author: " + authorArea.getText()); sj.add("Date: " + dateArea.getText()); @@ -286,22 +289,25 @@ private void reloadAnnotations() { * * @param annotation either a text annotation or a highlighting from a pdf */ - private void updateContentAndHighlightTextfields(final FileAnnotation annotation) { + private void updateContentAndHighlightTextAreas(final FileAnnotation annotation) { if (annotation.hasLinkedAnnotation()) { - String annotationText; - String highlightedText; + // isPresent() of the optional is already checked in annotation.hasLinkedAnnotation() + if (!annotation.getLinkedFileAnnotation().getContent().isEmpty()) { + contentTxtArea.setText(annotation.getLinkedFileAnnotation().getContent()); + contentTxtArea.setEnabled(true); + } else { + contentTxtArea.setText("N/A"); + contentTxtArea.setEnabled(false); + } - if (annotation.getAnnotationType().equals(FDFAnnotationHighlight.SUBTYPE)) { - highlightedText = annotation.getContent(); - annotationText = annotation.getLinkedFileAnnotation().getContent(); + if (annotation.getContent().isEmpty()) { + highlightTxtArea.setEnabled(false); + highlightTxtArea.setText("JabRef: The highlighted area does not contain any legible text!"); } else { - highlightedText = annotation.getLinkedFileAnnotation().getContent(); - annotationText = annotation.getContent(); + highlightTxtArea.setEnabled(true); + highlightTxtArea.setText(annotation.getContent()); } - highlightTxtArea.setEnabled(true); - contentTxtArea.setText(annotationText); - highlightTxtArea.setText(highlightedText); } else { contentTxtArea.setText(annotation.getContent()); @@ -345,7 +351,7 @@ public Component getListCellRendererComponent(JList list, Object value, int i FileAnnotation annotation = (FileAnnotation) value; //call the super method so that the cell selection is done as usual - label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //If more different annotation types should be reflected by icons in the list, add them here switch (annotation.getAnnotationType()) { diff --git a/src/main/java/org/jabref/gui/groups/GroupSelector.java b/src/main/java/org/jabref/gui/groups/GroupSelector.java index c6a1ed91392..168362833f2 100644 --- a/src/main/java/org/jabref/gui/groups/GroupSelector.java +++ b/src/main/java/org/jabref/gui/groups/GroupSelector.java @@ -68,9 +68,6 @@ import org.jabref.model.groups.event.GroupUpdatedEvent; import org.jabref.model.metadata.MetaData; import org.jabref.model.search.SearchMatcher; -import org.jabref.model.search.matchers.MatcherSet; -import org.jabref.model.search.matchers.MatcherSets; -import org.jabref.model.search.matchers.NotMatcher; import org.jabref.preferences.JabRefPreferences; import com.google.common.eventbus.Subscribe; @@ -470,6 +467,7 @@ public void valueChanged(TreeSelectionEvent e) { if (panel == null) { return; // ignore this event (happens for example if the file was closed) } + /* if (getLeafsOfSelection().stream().allMatch(GroupTreeNodeViewModel::isAllEntriesGroup)) { panel.getMainTable().getTableModel().updateGroupingState(MainTableDataModel.DisplayOption.DISABLED); if (showOverlappingGroups.isSelected()) { @@ -478,12 +476,13 @@ public void valueChanged(TreeSelectionEvent e) { frame.output(Localization.lang("Displaying no groups") + "."); return; } - + */ updateShownEntriesAccordingToSelectedGroups(); } private void updateShownEntriesAccordingToSelectedGroups() { - final MatcherSet searchRules = MatcherSets + updateShownEntriesAccordingToSelectedGroups(Globals.stateManager.activeGroupProperty().get()); + /*final MatcherSet searchRules = MatcherSets .build(andCb.isSelected() ? MatcherSets.MatcherType.AND : MatcherSets.MatcherType.OR); for (GroupTreeNodeViewModel node : getLeafsOfSelection()) { @@ -492,8 +491,9 @@ private void updateShownEntriesAccordingToSelectedGroups() { } SearchMatcher searchRule = invCb.isSelected() ? new NotMatcher(searchRules) : searchRules; GroupingWorker worker = new GroupingWorker(searchRule); - worker.run(); - worker.update(); + worker.getWorker().run(); + worker.getCallBack().update(); + */ } private void updateShownEntriesAccordingToSelectedGroups(Optional selectedGroup) { diff --git a/src/main/java/org/jabref/gui/help/AboutDialogController.java b/src/main/java/org/jabref/gui/help/AboutDialogController.java index 93805f640bd..21604a8f316 100644 --- a/src/main/java/org/jabref/gui/help/AboutDialogController.java +++ b/src/main/java/org/jabref/gui/help/AboutDialogController.java @@ -25,7 +25,7 @@ private void initialize() { viewModel = new AboutDialogViewModel(dialogService, clipBoardManager, buildInfo); SvgImageLoaderFactory.install(); - Image icon = new Image(this.getClass().getResourceAsStream("/images/icons/JabRef-icon.svg")); + Image icon = new Image(this.getClass().getResourceAsStream("/icons/jabref.svg")); iconImage.setImage(icon); } diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index d30cd4dd75c..e68a03d9c5d 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -27,7 +27,6 @@ import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; -import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JCheckBox; @@ -197,7 +196,7 @@ public ImportInspectionDialog(JabRefFrame frame, BasePanel panel, String undoNam this.bibDatabaseContext = (panel == null) ? null : panel.getBibDatabaseContext(); this.undoName = undoName; this.newDatabase = newDatabase; - setIconImage(new ImageIcon(IconTheme.getIconUrl("jabrefIcon48")).getImage()); + setIconImages(IconTheme.getLogoSet()); preview = new PreviewPanel(panel, bibDatabaseContext); duplLabel.setToolTipText(Localization.lang("Possible duplicate of existing entry. Click to resolve.")); diff --git a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java index 3cd3c914c86..417d01a0ab9 100644 --- a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java @@ -28,7 +28,7 @@ * This action checks whether any new custom entry types were loaded from this * BIB file. If so, an offer to remember these entry types is given. */ -public class CheckForNewEntryTypesAction implements PostOpenAction { +public class CheckForNewEntryTypesAction implements GUIPostOpenAction { @Override public boolean isActionNecessary(ParserResult parserResult) { diff --git a/src/main/java/org/jabref/gui/importer/actions/PostOpenAction.java b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java similarity index 97% rename from src/main/java/org/jabref/gui/importer/actions/PostOpenAction.java rename to src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java index 7cdd35a6508..e6015fbb593 100644 --- a/src/main/java/org/jabref/gui/importer/actions/PostOpenAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java @@ -12,7 +12,7 @@ * This interface is introduced in an attempt to add such functionality in a * flexible manner. */ -public interface PostOpenAction { +public interface GUIPostOpenAction { /** * This method is queried in order to find out whether the action needs to be diff --git a/src/main/java/org/jabref/gui/importer/actions/HandleDuplicateWarnings.java b/src/main/java/org/jabref/gui/importer/actions/HandleDuplicateWarnings.java index 8ed2187bd64..fb79d60ac8b 100644 --- a/src/main/java/org/jabref/gui/importer/actions/HandleDuplicateWarnings.java +++ b/src/main/java/org/jabref/gui/importer/actions/HandleDuplicateWarnings.java @@ -8,10 +8,10 @@ import org.jabref.logic.l10n.Localization; /** - * PostOpenAction that checks whether there are warnings about duplicate BibTeX keys, and + * GUIPostOpenAction that checks whether there are warnings about duplicate BibTeX keys, and * if so, offers to start the duplicate resolving process. */ -public class HandleDuplicateWarnings implements PostOpenAction { +public class HandleDuplicateWarnings implements GUIPostOpenAction { @Override public boolean isActionNecessary(ParserResult pr) { 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 051648ea632..a5d143a4a89 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -49,25 +49,22 @@ public class OpenDatabaseAction extends MnemonicAwareAction { public static final Log LOGGER = LogFactory.getLog(OpenDatabaseAction.class); - - private final boolean showDialog; - private final JabRefFrame frame; - // List of actions that may need to be called after opening the file. Such as // upgrade actions etc. that may depend on the JabRef version that wrote the file: - private static final List POST_OPEN_ACTIONS = new ArrayList<>(); + private static final List POST_OPEN_ACTIONS = new ArrayList<>(); static { // Add the action for checking for new custom entry types loaded from the BIB file: POST_OPEN_ACTIONS.add(new CheckForNewEntryTypesAction()); - // Add the action for converting legacy entries in ExplicitGroup - POST_OPEN_ACTIONS.add(new ConvertLegacyExplicitGroups()); // Add the action for the new external file handling system in version 2.3: POST_OPEN_ACTIONS.add(new FileLinksUpgradeWarning()); // Add the action for warning about and handling duplicate BibTeX keys: POST_OPEN_ACTIONS.add(new HandleDuplicateWarnings()); } + private final boolean showDialog; + private final JabRefFrame frame; + public OpenDatabaseAction(JabRefFrame frame, boolean showDialog) { super(IconTheme.JabRefIcon.OPEN.getIcon()); this.frame = frame; @@ -77,6 +74,21 @@ public OpenDatabaseAction(JabRefFrame frame, boolean showDialog) { putValue(Action.SHORT_DESCRIPTION, Localization.lang("Open BibTeX library")); } + /** + * Go through the list of post open actions, and perform those that need to be performed. + * + * @param panel The BasePanel where the database is shown. + * @param result The result of the BIB file parse operation. + */ + public static void performPostOpenActions(BasePanel panel, ParserResult result) { + for (GUIPostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { + if (action.isActionNecessary(result)) { + action.performAction(panel, result); + panel.frame().getTabbedPane().setSelectedComponent(panel); + } + } + } + @Override public void actionPerformed(ActionEvent e) { List filesToOpen = new ArrayList<>(); @@ -239,24 +251,7 @@ private void openTheFile(File file, boolean raisePanel) { // if the database contents should be modified due to new features // in this version of JabRef: final ParserResult finalReferenceToResult = result; - SwingUtilities.invokeLater(() -> OpenDatabaseAction.performPostOpenActions(panel, finalReferenceToResult, true)); - } - } - - /** - * Go through the list of post open actions, and perform those that need to be performed. - * - * @param panel The BasePanel where the database is shown. - * @param result The result of the BIB file parse operation. - */ - public static void performPostOpenActions(BasePanel panel, ParserResult result, boolean mustRaisePanel) { - for (PostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { - if (action.isActionNecessary(result)) { - if (mustRaisePanel) { - panel.frame().getTabbedPane().setSelectedComponent(panel); - } - action.performAction(panel, result); - } + SwingUtilities.invokeLater(() -> OpenDatabaseAction.performPostOpenActions(panel, finalReferenceToResult)); } } diff --git a/src/main/java/org/jabref/gui/search/SearchResultFrame.java b/src/main/java/org/jabref/gui/search/SearchResultFrame.java index cd293d9052c..ffb43514da6 100644 --- a/src/main/java/org/jabref/gui/search/SearchResultFrame.java +++ b/src/main/java/org/jabref/gui/search/SearchResultFrame.java @@ -123,7 +123,7 @@ public SearchResultFrame(JabRefFrame frame, String title, SearchQuery searchQuer private void init(String title) { searchResultFrame = new JFrame(); searchResultFrame.setTitle(title); - searchResultFrame.setIconImage(IconTheme.getImage("jabrefIcon48").getImage()); + searchResultFrame.setIconImages(IconTheme.getLogoSet()); preview = new PreviewPanel(null, null); diff --git a/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java b/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java index 1033a1c3502..b99197dc388 100644 --- a/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java +++ b/src/main/java/org/jabref/gui/util/ViewModelTreeTableCellFactory.java @@ -10,6 +10,8 @@ import javafx.scene.text.Text; import javafx.util.Callback; +import org.jabref.model.strings.StringUtil; + /** * Constructs a {@link TreeTableCell} based on the view model of the row and a bunch of specified converter methods. * @@ -76,7 +78,10 @@ protected void updateItem(T item, boolean empty) { setGraphic(toGraphic.call(viewModel)); } if (toTooltip != null) { - setTooltip(new Tooltip(toTooltip.call(viewModel))); + String tooltip = toTooltip.call(viewModel); + if (StringUtil.isNotBlank(tooltip)) { + setTooltip(new Tooltip(tooltip)); + } } if (toOnMouseClickedEvent != null) { setOnMouseClicked(toOnMouseClickedEvent.call(viewModel)); diff --git a/src/main/java/org/jabref/logic/exporter/FileSaveSession.java b/src/main/java/org/jabref/logic/exporter/FileSaveSession.java index 14514cd4ad7..60c1eb00d73 100644 --- a/src/main/java/org/jabref/logic/exporter/FileSaveSession.java +++ b/src/main/java/org/jabref/logic/exporter/FileSaveSession.java @@ -38,7 +38,6 @@ public class FileSaveSession extends SaveSession { private static final String TEMP_SUFFIX = "save.bib"; private final Path temporaryFile; - public FileSaveSession(Charset encoding, boolean backup) throws SaveException { this(encoding, backup, createTemporaryFile()); } @@ -86,8 +85,12 @@ public void commit(Path file) throws SaveException { LOGGER.error("Error when creating lock file.", ex); } - // Try to save file permissions to restore them later (by default: allow everything) - Set oldFilePermissions = EnumSet.allOf(PosixFilePermission.class); + // Try to save file permissions to restore them later (by default: 664) + Set oldFilePermissions = EnumSet.of(PosixFilePermission.OWNER_READ, + PosixFilePermission.OWNER_WRITE, + PosixFilePermission.GROUP_READ, + PosixFilePermission.GROUP_WRITE, + PosixFilePermission.OTHERS_READ); if (FileUtil.isPosixCompilant && Files.exists(file)) { try { oldFilePermissions = Files.getPosixFilePermissions(file); diff --git a/src/main/java/org/jabref/logic/importer/FulltextFetchers.java b/src/main/java/org/jabref/logic/importer/FulltextFetchers.java index 2a3a6f9b00a..e0c553f6be7 100644 --- a/src/main/java/org/jabref/logic/importer/FulltextFetchers.java +++ b/src/main/java/org/jabref/logic/importer/FulltextFetchers.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Optional; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.fetcher.ACS; import org.jabref.logic.importer.fetcher.ArXiv; import org.jabref.logic.importer.fetcher.CrossRef; @@ -15,7 +16,6 @@ import org.jabref.logic.importer.fetcher.ScienceDirect; import org.jabref.logic.importer.fetcher.SpringerLink; import org.jabref.logic.net.URLDownload; -import org.jabref.logic.identifier.DOI; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/OpenDatabase.java b/src/main/java/org/jabref/logic/importer/OpenDatabase.java index 9de364f7f75..6e037f2f666 100644 --- a/src/main/java/org/jabref/logic/importer/OpenDatabase.java +++ b/src/main/java/org/jabref/logic/importer/OpenDatabase.java @@ -2,8 +2,12 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.List; import org.jabref.logic.importer.fileformat.BibtexImporter; +import org.jabref.logic.importer.util.ConvertLegacyExplicitGroups; +import org.jabref.logic.importer.util.PostOpenAction; import org.jabref.logic.l10n.Localization; import org.jabref.logic.specialfields.SpecialFieldsUtils; import org.jabref.logic.util.io.FileBasedLock; @@ -71,6 +75,16 @@ public static ParserResult loadDatabase(File fileToOpen, ImportFormatPreferences LOGGER.debug("Synchronized special fields based on keywords"); } + applyPostActions(result); + return result; } + + private static void applyPostActions(ParserResult parserResult) { + List actions = Arrays.asList(new ConvertLegacyExplicitGroups()); + + for (PostOpenAction action : actions) { + action.performAction(parserResult); + } + } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ACS.java b/src/main/java/org/jabref/logic/importer/fetcher/ACS.java index 92ecfa513bf..54aa05f8f56 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ACS.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ACS.java @@ -5,8 +5,8 @@ import java.util.Objects; import java.util.Optional; -import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.importer.FulltextFetcher; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java index bafa1eed7b9..7e6bf10f539 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java @@ -1,13 +1,13 @@ package org.jabref.logic.importer.fetcher; import org.jabref.logic.help.HelpFile; +import org.jabref.logic.identifier.ISBN; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedParserFetcher; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.Parser; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.identifier.ISBN; public abstract class AbstractIsbnFetcher implements IdBasedParserFetcher { diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java index a5cf75724e7..ae8e3f1c3bd 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java @@ -17,13 +17,13 @@ import javax.xml.parsers.ParserConfigurationException; import org.jabref.logic.help.HelpFile; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.importer.IdBasedFetcher; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.SearchBasedFetcher; import org.jabref.logic.importer.util.OAI2Handler; -import org.jabref.logic.identifier.DOI; import org.jabref.logic.util.io.XMLUtil; import org.jabref.logic.util.strings.StringSimilarity; import org.jabref.model.entry.ArXivIdentifier; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java index 50c7838b3b8..90e163b6d4d 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java @@ -9,6 +9,7 @@ import org.jabref.logic.formatter.bibtexfields.ClearFormatter; import org.jabref.logic.formatter.bibtexfields.NormalizePagesFormatter; import org.jabref.logic.help.HelpFile; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.EntryBasedFetcher; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedFetcher; @@ -17,7 +18,6 @@ import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.URLDownload; -import org.jabref.logic.identifier.DOI; import org.jabref.model.cleanup.FieldFormatterCleanup; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DoiResolution.java b/src/main/java/org/jabref/logic/importer/fetcher/DoiResolution.java index 5511c0e6aa4..9b366ff96fb 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DoiResolution.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DoiResolution.java @@ -8,9 +8,9 @@ import java.util.Objects; import java.util.Optional; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.net.URLDownload; -import org.jabref.logic.identifier.DOI; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java index 0439203ef20..07f7d95b9d8 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java @@ -7,9 +7,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.net.URLDownload; -import org.jabref.logic.identifier.DOI; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java b/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java index 981fb87f68e..5636ef2805c 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ScienceDirect.java @@ -5,8 +5,8 @@ import java.util.Objects; import java.util.Optional; -import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.importer.FulltextFetcher; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java b/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java index 9ccb54a6c31..7c67e19c349 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/SpringerLink.java @@ -5,8 +5,8 @@ import java.util.Objects; import java.util.Optional; -import org.jabref.logic.importer.FulltextFetcher; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.importer.FulltextFetcher; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; diff --git a/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java index bb99f13153e..0b40327e337 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java @@ -3,16 +3,16 @@ import java.util.Optional; import org.jabref.logic.help.HelpFile; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedFetcher; import org.jabref.logic.importer.ImportFormatPreferences; -import org.jabref.logic.identifier.DOI; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.FieldName; public class TitleFetcher implements IdBasedFetcher { - private ImportFormatPreferences preferences; + private final ImportFormatPreferences preferences; public TitleFetcher(ImportFormatPreferences preferences) { this.preferences = preferences; diff --git a/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java index a3d8ed97b21..02a15f50e74 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java @@ -13,13 +13,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jabref.logic.identifier.DOI; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.Importer; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fetcher.DoiFetcher; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.identifier.DOI; import org.jabref.logic.util.FileExtensions; import org.jabref.logic.xmp.EncryptedPdfsNotSupportedException; import org.jabref.logic.xmp.XMPUtil; diff --git a/src/main/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroups.java b/src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java similarity index 68% rename from src/main/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroups.java rename to src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java index c4bf5cc3dbd..6cb4f839be3 100644 --- a/src/main/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroups.java +++ b/src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java @@ -1,10 +1,9 @@ -package org.jabref.gui.importer.actions; +package org.jabref.logic.importer.util; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import org.jabref.gui.BasePanel; import org.jabref.logic.importer.ParserResult; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.ExplicitGroup; @@ -17,23 +16,15 @@ public class ConvertLegacyExplicitGroups implements PostOpenAction { @Override - public boolean isActionNecessary(ParserResult pr) { - if (pr.getMetaData().getGroups().isPresent()) { - return !getExplicitGroupsWithLegacyKeys(pr.getMetaData().getGroups().orElse(null)).isEmpty(); - } - return false; - } - - @Override - public void performAction(BasePanel panel, ParserResult pr) { - Objects.requireNonNull(pr); - if (!pr.getMetaData().getGroups().isPresent()) { + public void performAction(ParserResult parserResult) { + Objects.requireNonNull(parserResult); + if (!parserResult.getMetaData().getGroups().isPresent()) { return; } - for (ExplicitGroup group : getExplicitGroupsWithLegacyKeys(pr.getMetaData().getGroups().get())) { + for (ExplicitGroup group : getExplicitGroupsWithLegacyKeys(parserResult.getMetaData().getGroups().get())) { for (String entryKey : group.getLegacyEntryKeys()) { - for (BibEntry entry : pr.getDatabase().getEntriesByKey(entryKey)) { + for (BibEntry entry : parserResult.getDatabase().getEntriesByKey(entryKey)) { group.add(entry); } } diff --git a/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java b/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java new file mode 100644 index 00000000000..7eadee68c88 --- /dev/null +++ b/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java @@ -0,0 +1,7 @@ +package org.jabref.logic.importer.util; + +import org.jabref.logic.importer.ParserResult; + +public interface PostOpenAction { + void performAction(ParserResult parserResult); +} diff --git a/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java b/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java index 15c134b9085..b5bf695d592 100644 --- a/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java +++ b/src/main/java/org/jabref/logic/integrity/DOIValidityChecker.java @@ -2,8 +2,8 @@ import java.util.Optional; -import org.jabref.logic.l10n.Localization; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.l10n.Localization; public class DOIValidityChecker implements ValueChecker { diff --git a/src/main/java/org/jabref/logic/integrity/ISBNChecker.java b/src/main/java/org/jabref/logic/integrity/ISBNChecker.java index cc208436c77..d19ed16c30b 100644 --- a/src/main/java/org/jabref/logic/integrity/ISBNChecker.java +++ b/src/main/java/org/jabref/logic/integrity/ISBNChecker.java @@ -2,8 +2,8 @@ import java.util.Optional; -import org.jabref.logic.l10n.Localization; import org.jabref.logic.identifier.ISBN; +import org.jabref.logic.l10n.Localization; public class ISBNChecker implements ValueChecker { diff --git a/src/main/java/org/jabref/logic/integrity/ISSNChecker.java b/src/main/java/org/jabref/logic/integrity/ISSNChecker.java index f15fc2f3d22..fe2ac1989f2 100644 --- a/src/main/java/org/jabref/logic/integrity/ISSNChecker.java +++ b/src/main/java/org/jabref/logic/integrity/ISSNChecker.java @@ -2,8 +2,8 @@ import java.util.Optional; -import org.jabref.logic.l10n.Localization; import org.jabref.logic.identifier.ISSN; +import org.jabref.logic.l10n.Localization; public class ISSNChecker implements ValueChecker { diff --git a/src/main/java/org/jabref/logic/layout/format/DOICheck.java b/src/main/java/org/jabref/logic/layout/format/DOICheck.java index d7bc0877cac..4bc8291f0e0 100644 --- a/src/main/java/org/jabref/logic/layout/format/DOICheck.java +++ b/src/main/java/org/jabref/logic/layout/format/DOICheck.java @@ -1,7 +1,7 @@ package org.jabref.logic.layout.format; -import org.jabref.logic.layout.LayoutFormatter; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.layout.LayoutFormatter; /** * Used to fix [ 1588028 ] export HTML table DOI URL. diff --git a/src/main/java/org/jabref/logic/layout/format/DOIStrip.java b/src/main/java/org/jabref/logic/layout/format/DOIStrip.java index 8ea85230499..e55fa920daf 100644 --- a/src/main/java/org/jabref/logic/layout/format/DOIStrip.java +++ b/src/main/java/org/jabref/logic/layout/format/DOIStrip.java @@ -1,7 +1,7 @@ package org.jabref.logic.layout.format; -import org.jabref.logic.layout.LayoutFormatter; import org.jabref.logic.identifier.DOI; +import org.jabref.logic.layout.LayoutFormatter; /** * Will strip any prefixes from the Doi field, in order to output only the Doi number diff --git a/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java b/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java index ac52e0edac3..996404c9fed 100644 --- a/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java +++ b/src/main/java/org/jabref/logic/pdf/AnnotationImporter.java @@ -1,5 +1,6 @@ package org.jabref.logic.pdf; +import java.nio.file.Path; import java.util.List; import org.jabref.model.database.BibDatabaseContext; @@ -7,5 +8,5 @@ public interface AnnotationImporter { - List importAnnotations(final String path, final BibDatabaseContext context); + List importAnnotations(final Path path, final BibDatabaseContext context); } diff --git a/src/main/java/org/jabref/logic/pdf/AnnotationImporterInterface.java b/src/main/java/org/jabref/logic/pdf/AnnotationImporterInterface.java deleted file mode 100644 index c2c6fca749d..00000000000 --- a/src/main/java/org/jabref/logic/pdf/AnnotationImporterInterface.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.jabref.logic.pdf; - -import java.util.List; - -import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.pdf.FileAnnotation; - -public interface AnnotationImporterInterface { - - List importAnnotations(final String path, final BibDatabaseContext context); -} diff --git a/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java b/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java index e268b136653..54782963a13 100644 --- a/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java +++ b/src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java @@ -1,5 +1,6 @@ package org.jabref.logic.pdf; +import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -49,7 +50,8 @@ public Map> importAnnotationsFromFiles(BibDatabaseC Map> annotations = new HashMap<>(); AnnotationImporter importer = new PdfAnnotationImporter(); //import annotationsOfFiles if the selected files are valid which is checked in getFilteredFileList() - this.getFilteredFileList().forEach(parsedFileField -> annotations.put(parsedFileField.getLink(), importer.importAnnotations(parsedFileField.getLink(), context))); + this.getFilteredFileList().forEach(parsedFileField -> annotations.put(parsedFileField.getLink(), + importer.importAnnotations(Paths.get(parsedFileField.getLink()), context))); return annotations; } } diff --git a/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java b/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java index b539d15b8fc..7cb4acabd6a 100644 --- a/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java +++ b/src/main/java/org/jabref/logic/pdf/PdfAnnotationImporter.java @@ -2,11 +2,15 @@ import java.awt.geom.Rectangle2D; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; -import java.util.ArrayList; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Optional; import org.jabref.logic.util.io.FileUtil; @@ -39,115 +43,119 @@ public class PdfAnnotationImporter implements AnnotationImporter { * @return a list with the all the annotations found in the file of the path */ @Override - public List importAnnotations(final String path, final BibDatabaseContext context) { + public List importAnnotations(final Path path, final BibDatabaseContext context) { - List annotationsList = new ArrayList<>(); + Optional validatePath = validatePath(path, context); + if (!validatePath.isPresent()) { + // Path could not be validated, return default result + return Collections.emptyList(); + } - PDDocument document = null; - try { - try{ - document = importPdfFile(path); - } catch (FileNotFoundException notFound) { - Optional importedFile = FileUtil.expandFilename(context, path, - JabRefPreferences.getInstance().getFileDirectoryPreferences()); - //Check if the file could be loaded - if(importedFile.isPresent()){ - String absolutePath = importedFile.get().getAbsolutePath(); - document = importPdfFile(absolutePath); - } else { - //return empty list to recognize invalid import - return annotationsList; + Path validPath = validatePath.get(); + + List annotationsList = new LinkedList<>(); + try (PDDocument document = PDDocument.load(validPath.toString())) { + List pdfPages = document.getDocumentCatalog().getAllPages(); + for (int pageIndex = 0; pageIndex < pdfPages.size(); pageIndex++) { + PDPage page = (PDPage) pdfPages.get(pageIndex); + for (PDAnnotation annotation : page.getAnnotations()) { + if (annotation.getSubtype().equals(FDFAnnotationHighlight.SUBTYPE)) { + annotationsList.add(createHighlightAnnotations(pageIndex, page, annotation)); + } else { + FileAnnotation fileAnnotation = new FileAnnotation(annotation, pageIndex + 1); + if (fileAnnotation.getContent() != null && !fileAnnotation.getContent().isEmpty()) { + annotationsList.add(fileAnnotation); + } + } } } - } catch (IOException e) { - LOGGER.error(String.format("Failed to read file %s.", path) , e); + LOGGER.error(String.format("Failed to read file '%s'.", validPath), e); } + return annotationsList; + } - List pdfPages = document.getDocumentCatalog().getAllPages(); - for (int i = 0; i < pdfPages.size(); i++) { - PDPage page = (PDPage) pdfPages.get(i); - try { - for (PDAnnotation annotation : page.getAnnotations()) { + private FileAnnotation createHighlightAnnotations(int pageIndex, PDPage page, PDAnnotation annotation) { + FileAnnotation annotationBelongingToHighlighting = new FileAnnotation( + annotation.getDictionary().getString(COSName.T), FileAnnotation.extractModifiedTime(annotation.getModifiedDate()), + pageIndex + 1, annotation.getContents(), FDFAnnotationText.SUBTYPE, Optional.empty()); - String subtype = annotation.getSubtype(); - //highlighted text has to be extracted by the rectangle calculated from the highlighting - if (subtype.equals(FDFAnnotationHighlight.SUBTYPE)) { - - FileAnnotation annotationBelongingToHighlighting = new FileAnnotation(annotation.getAnnotationName(), - annotation.getDictionary().getString(COSName.T), annotation.getModifiedDate(), - i + 1, annotation.getContents(), FDFAnnotationText.SUBTYPE); - - PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea(); - COSArray quadsArray = (COSArray) annotation.getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints")); - String highlightedText = null; - for (int j = 1, - k = 0; - j <= (quadsArray.size() / 8); - j++) { - - COSFloat upperLeftX = (COSFloat) quadsArray.get(k); - COSFloat upperLeftY = (COSFloat) quadsArray.get(1 + k); - COSFloat upperRightX = (COSFloat) quadsArray.get(2 + k); - COSFloat upperRightY = (COSFloat) quadsArray.get(3 + k); - COSFloat lowerLeftX = (COSFloat) quadsArray.get(4 + k); - COSFloat lowerLeftY = (COSFloat) quadsArray.get(5 + k); - - k += 8; - - float ulx = upperLeftX.floatValue() - 1; - float uly = upperLeftY.floatValue(); - float width = upperRightX.floatValue() - lowerLeftX.floatValue(); - float height = upperRightY.floatValue() - lowerLeftY.floatValue(); - - PDRectangle pageSize = page.getMediaBox(); - uly = pageSize.getHeight() - uly; - - Rectangle2D.Float rectangle = new Rectangle2D.Float(ulx, uly, width, height); - stripperByArea.addRegion("highlightedRegion", rectangle); - stripperByArea.extractRegions(page); - String highlightedTextInLine = stripperByArea.getTextForRegion("highlightedRegion"); - - if (j > 1) { - highlightedText = highlightedText.concat(highlightedTextInLine); - } else { - highlightedText = highlightedTextInLine; - } - } - annotation.setContents(highlightedText); + try { + annotation.setContents(extractHighlightedText(page, annotation)); + } catch (IOException e) { + annotation.setContents("JabRef: Could not extract any highlighted text!"); + } - FileAnnotation highlighting = new FileAnnotation(annotation, i + 1); - //highlighted text that has a sticky note on it should be linked to the sticky note - highlighting.linkComments(annotationBelongingToHighlighting); - annotationsList.add(annotationBelongingToHighlighting); - annotationsList.add(highlighting); + //highlighted text that has a sticky note on it should be linked to the sticky note + return new FileAnnotation(annotation, pageIndex + 1, annotationBelongingToHighlighting); + } - } else { - annotationsList.add(new FileAnnotation(annotation, i + 1)); - } - } - } catch (IOException e) { - LOGGER.error(String.format("Failed to read file %s.", path) , e); + private String extractHighlightedText(PDPage page, PDAnnotation annotation) throws IOException { + //highlighted text has to be extracted by the rectangle calculated from the highlighting + PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea(); + COSArray quadsArray = (COSArray) annotation.getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints")); + String highlightedText = ""; + for (int j = 1, + k = 0; + j <= (quadsArray.size() / 8); + j++) { + + COSFloat upperLeftX = (COSFloat) quadsArray.get(k); + COSFloat upperLeftY = (COSFloat) quadsArray.get(1 + k); + COSFloat upperRightX = (COSFloat) quadsArray.get(2 + k); + COSFloat upperRightY = (COSFloat) quadsArray.get(3 + k); + COSFloat lowerLeftX = (COSFloat) quadsArray.get(4 + k); + COSFloat lowerLeftY = (COSFloat) quadsArray.get(5 + k); + + k += 8; + + float ulx = upperLeftX.floatValue() - 1; + float uly = upperLeftY.floatValue(); + float width = upperRightX.floatValue() - lowerLeftX.floatValue(); + float height = upperRightY.floatValue() - lowerLeftY.floatValue(); + + PDRectangle pageSize = page.getMediaBox(); + uly = pageSize.getHeight() - uly; + + Rectangle2D.Float rectangle = new Rectangle2D.Float(ulx, uly, width, height); + stripperByArea.addRegion("highlightedRegion", rectangle); + stripperByArea.extractRegions(page); + String highlightedTextInLine = stripperByArea.getTextForRegion("highlightedRegion"); + + if (j > 1) { + highlightedText = highlightedText.concat(highlightedTextInLine); + } else { + highlightedText = highlightedTextInLine; } } - try { - document.close(); - } catch (IOException ignored) { - } - return annotationsList; + + return highlightedText.trim(); } - /** - * - * @param path the absolute path to the pdf file - * @return a PDDocument representing the pdf file - * @throws IOException if the document cannot be read from path - */ - private PDDocument importPdfFile(final String path) throws IOException { + private Optional validatePath(Path path, BibDatabaseContext context) { + Objects.requireNonNull(path); + + if (!path.toString().toLowerCase(Locale.ROOT).endsWith(".pdf")) { + LOGGER.warn(String.format("File %s does not end with .pdf!", path.toString())); + return Optional.empty(); + } - if(path.toLowerCase(Locale.ROOT).endsWith(".pdf")){ - return PDDocument.load("/"+ path); + if (!Files.exists(path)) { + Optional importedFile = FileUtil.expandFilename(context, path.toString(), + JabRefPreferences.getInstance().getFileDirectoryPreferences()); + if (importedFile.isPresent()) { + // No need to check file existence again, because it is done in FileUtil.expandFilename() + return Optional.of(Paths.get(importedFile.get().getAbsolutePath())); + } else { + //return empty list to recognize invalid import + return Optional.empty(); } - return null; + } + + if (!Files.isRegularFile(path) || !Files.isReadable(path)) { + LOGGER.warn(String.format("File %s is not readable!", path.toString())); + return Optional.empty(); + } + return Optional.of(path); } } diff --git a/src/main/java/org/jabref/logic/util/io/FileUtil.java b/src/main/java/org/jabref/logic/util/io/FileUtil.java index faa6610321d..964b0c9988e 100644 --- a/src/main/java/org/jabref/logic/util/io/FileUtil.java +++ b/src/main/java/org/jabref/logic/util/io/FileUtil.java @@ -199,8 +199,8 @@ public static boolean renameFile(Path fromFile, Path toFile, boolean replaceExis } /** - * Converts a relative filename to an absolute one, if necessary. Returns - * null if the file does not exist.
+ * Converts a relative filename to an absolute one, if necessary. Returns an empty optional if the file does not + * exist.
*

* Uses

    *
  • the default directory associated with the extension of the file
  • diff --git a/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java b/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java index 164408a7991..6134cf5e48a 100644 --- a/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java +++ b/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java @@ -13,7 +13,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.FileDialog; import org.jabref.gui.entryeditor.EntryEditorTabList; -import org.jabref.gui.importer.actions.PostOpenAction; +import org.jabref.gui.importer.actions.GUIPostOpenAction; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.logic.cleanup.UpgradePdfPsToFileCleanup; @@ -38,7 +38,7 @@ * * modify General fields to show "file" instead of "pdf" / "ps" * * modify table column settings to show "file" instead of "pdf" / "ps" */ -public class FileLinksUpgradeWarning implements PostOpenAction { +public class FileLinksUpgradeWarning implements GUIPostOpenAction { private static final String[] FIELDS_TO_LOOK_FOR = new String[] {FieldName.PDF, FieldName.PS}; @@ -48,6 +48,29 @@ public class FileLinksUpgradeWarning implements PostOpenAction { private boolean offerSetFileDir; + /** + * Collect file links from the given set of fields, and add them to the list contained in the field + * GUIGlobals.FILE_FIELD. + * + * @param database The database to modify. + * @param fields The fields to find links in. + * @return A CompoundEdit specifying the undo operation for the whole operation. + */ + private static NamedCompound upgradePdfPsToFile(BibDatabase database) { + NamedCompound ce = new NamedCompound(Localization.lang("Move external links to 'file' field")); + + UpgradePdfPsToFileCleanup cleanupJob = new UpgradePdfPsToFileCleanup(); + for (BibEntry entry : database.getEntries()) { + List changes = cleanupJob.cleanup(entry); + + for (FieldChange change : changes) { + ce.addEdit(new UndoableFieldChange(change)); + } + } + + ce.end(); + return ce; + } /** * This method should be performed if the major/minor versions recorded in the ParserResult @@ -226,28 +249,4 @@ private boolean showsFileInGenFields() { } return found; } - - /** - * Collect file links from the given set of fields, and add them to the list contained in the field - * GUIGlobals.FILE_FIELD. - * - * @param database The database to modify. - * @param fields The fields to find links in. - * @return A CompoundEdit specifying the undo operation for the whole operation. - */ - private static NamedCompound upgradePdfPsToFile(BibDatabase database) { - NamedCompound ce = new NamedCompound(Localization.lang("Move external links to 'file' field")); - - UpgradePdfPsToFileCleanup cleanupJob = new UpgradePdfPsToFileCleanup(); - for (BibEntry entry : database.getEntries()) { - List changes = cleanupJob.cleanup(entry); - - for (FieldChange change : changes) { - ce.addEdit(new UndoableFieldChange(change)); - } - } - - ce.end(); - return ce; - } } diff --git a/src/main/java/org/jabref/model/database/BibDatabaseContext.java b/src/main/java/org/jabref/model/database/BibDatabaseContext.java index ca7b82061d4..392584039a2 100644 --- a/src/main/java/org/jabref/model/database/BibDatabaseContext.java +++ b/src/main/java/org/jabref/model/database/BibDatabaseContext.java @@ -171,9 +171,9 @@ public Optional getFirstExistingFileDir(FileDirectoryPreferences preferenc * 3. preferences directory * 4. BIB file directory * - * @param * @param fieldName The field type - * @return The default directory for this field type. + * @param preferences The fileDirectory preferences + * @return The default directory for this field type. */ public List getFileDirectories(String fieldName, FileDirectoryPreferences preferences) { List fileDirs = new ArrayList<>(); diff --git a/src/main/java/org/jabref/model/pdf/FileAnnotation.java b/src/main/java/org/jabref/model/pdf/FileAnnotation.java index eb0c33dda5e..1e6e2db3323 100644 --- a/src/main/java/org/jabref/model/pdf/FileAnnotation.java +++ b/src/main/java/org/jabref/model/pdf/FileAnnotation.java @@ -1,127 +1,145 @@ package org.jabref.model.pdf; -import org.apache.pdfbox.cos.COSDictionary; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; -public class FileAnnotation { +public final class FileAnnotation { - private String commentId; - private String author; - private String date; - private int page; - private String content; - private String annotationType; - private FileAnnotation linkedFileAnnotation; private final static int ABBREVIATED_ANNOTATION_NAME_LENGTH = 45; + private final String author; + private final LocalDateTime timeModified; + private final int page; + private final String content; + private final String annotationType; + private final Optional linkedFileAnnotation; - private boolean linkedAnnotation; - public FileAnnotation(final String commentId, final String author, final String date, final int page, - final String content, final String annotationType) { + /** + * A flexible constructor, mainly used as dummy if there is actually no annotation. + * + * @param author The authors of the annotation + * @param timeModified The last time this annotation was modified + * @param pageNumber The page of the pdf where the annotation occurs + * @param content the actual content of the annotation + * @param annotationType the type of the annotation + */ + public FileAnnotation(final String author, final LocalDateTime timeModified, final int pageNumber, + final String content, final String annotationType, final Optional linkedFileAnnotation) { this.author = author; - this.date = date; - this.page = page; - this.content = content; - this.commentId = commentId; + this.timeModified = timeModified; + this.page = pageNumber; + this.content = parseContent(content); this.annotationType = annotationType; + this.linkedFileAnnotation = linkedFileAnnotation; } - public FileAnnotation(final PDAnnotation annotation, final int page ){ - COSDictionary dict = annotation.getDictionary(); - this.author = dict.getString(COSName.T); - this.commentId = annotation.getAnnotationName(); - this.date = annotation.getModifiedDate(); - this.page = page; - this.content = annotation.getContents(); - this.annotationType = annotation.getSubtype(); + /** + * Creating a normal FileAnnotation from a PDAnnotation. + * + * @param annotation The actual annotation that holds the information + * @param pageNumber The page of the pdf where the annotation occurs + */ + public FileAnnotation(final PDAnnotation annotation, final int pageNumber) { + this(annotation.getDictionary().getString(COSName.T), + extractModifiedTime(annotation.getModifiedDate()), + pageNumber, annotation.getContents(), annotation.getSubtype(), Optional.empty()); + } + /** + * For creating a FileAnnotation that has a connection to another FileAnnotation. Needed when creating a text + * highlight annotation with a sticky note. + * + * @param annotation The actual annotation that holds the information + * @param pageNumber The page of the pdf where the annotation occurs + * @param linkedFileAnnotation The corresponding note of a highlighted text area. + */ + public FileAnnotation(final PDAnnotation annotation, final int pageNumber, FileAnnotation linkedFileAnnotation) { + this(annotation.getDictionary().getString(COSName.T), extractModifiedTime(annotation.getModifiedDate()), + pageNumber, annotation.getContents(), annotation.getSubtype(), Optional.of(linkedFileAnnotation)); } /** - * Abbreviate annotation names when they are longer than {@code ABBREVIATED_ANNOTATION_NAME_LENGTH} chars - * @param annotationName - * @return the abbreviated name + * Parses a String into a LocalDateTime. + * + * @param dateTimeString In this case of format yyyyMMddHHmmss. + * @return a LocalDateTime parsed from the dateTimeString */ - private String abbreviateAnnotationName(final String annotationName ){ + public static LocalDateTime extractModifiedTime(String dateTimeString) { + if (dateTimeString == null) { + return LocalDateTime.now(); + } - int abbreviatedContentLengthForName = ABBREVIATED_ANNOTATION_NAME_LENGTH; - if (annotationName.length() > abbreviatedContentLengthForName) { - return annotationName.subSequence(0, abbreviatedContentLengthForName).toString() + "..."; - } - return annotationName; + return LocalDateTime.parse(dateTimeString.substring(2), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); } - public void linkComments(FileAnnotation commentToLinkTo){ - linkedFileAnnotation = commentToLinkTo; - commentToLinkTo.setLinkedFileAnnotation(this); - commentToLinkTo.setLinkedAnnotation(true); - linkedAnnotation = true; - } + private String parseContent(final String content) { + if (content == null) { + return ""; + } + if (content.trim().equals("þÿ")) { + return ""; + } - @Override - public String toString() { - return abbreviateAnnotationName(content); + return content.trim(); } - public FileAnnotation getLinkedFileAnnotation() { - return linkedFileAnnotation; + /** + * Abbreviate annotation names when they are longer than {@code ABBREVIATED_ANNOTATION_NAME_LENGTH} chars + * + * @param annotationName annotation to be shortened + * @return the abbreviated name + */ + private String abbreviateAnnotationName(final String annotationName) { + if (annotationName.length() > ABBREVIATED_ANNOTATION_NAME_LENGTH) { + return annotationName.subSequence(0, ABBREVIATED_ANNOTATION_NAME_LENGTH).toString() + "..."; + } + return annotationName; } - public void setLinkedFileAnnotation(FileAnnotation linkedFileAnnotation) { - this.linkedFileAnnotation = linkedFileAnnotation; - } - public String getCommentId() { - return commentId; - } + @Override + public String toString() { + if (this.hasLinkedAnnotation()) { + if (this.content.isEmpty()) { + return "Empty Highlight"; + } + return abbreviateAnnotationName("Highlight: " + content); + } - public void setCommentId(String commentId) { - this.commentId = commentId; + return abbreviateAnnotationName(content); } + public String getAuthor() { return author; } - public void setAuthor(String author) { - this.author = author; - } - - public String getDate() { - return date; - } - - public void setDate(String date) { - this.date = date; + public LocalDateTime getTimeModified() { + return timeModified; } public int getPage() { return page; } - public void setPage(int page) { - this.page = page; - } - public String getContent() { return content; } - public void setContent(String content) { - this.content = content; - } - public String getAnnotationType() { return annotationType; } public boolean hasLinkedAnnotation() { - return linkedAnnotation; + return this.linkedFileAnnotation.isPresent(); } - public void setLinkedAnnotation(boolean linkedAnnotation) { - this.linkedAnnotation = linkedAnnotation; + public FileAnnotation getLinkedFileAnnotation() { + return linkedFileAnnotation.get(); } } diff --git a/src/main/resources/icons/jabref.icns b/src/main/resources/icons/jabref.icns index fb71592d825..2c87ce06a5c 100755 Binary files a/src/main/resources/icons/jabref.icns and b/src/main/resources/icons/jabref.icns differ diff --git a/src/main/resources/icons/jabref.ico b/src/main/resources/icons/jabref.ico index 754a7c9ba4c..52d04280324 100644 Binary files a/src/main/resources/icons/jabref.ico and b/src/main/resources/icons/jabref.ico differ diff --git a/src/main/resources/icons/jabref.svg b/src/main/resources/icons/jabref.svg new file mode 100644 index 00000000000..35b4d563b8c --- /dev/null +++ b/src/main/resources/icons/jabref.svg @@ -0,0 +1,121 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/main/resources/images/Icons.properties b/src/main/resources/images/Icons.properties index 7632b07aa8b..3618d8fb943 100644 --- a/src/main/resources/images/Icons.properties +++ b/src/main/resources/images/Icons.properties @@ -1,6 +1,12 @@ -about=JabRef-icon.png +about=JabRef-icon-16.png +jabrefIcon16=JabRef-icon-16.png +jabrefIcon20=JabRef-icon-20.png +jabrefIcon32=JabRef-icon-32.png +jabrefIcon40=JabRef-icon-40.png jabrefIcon48=JabRef-icon-48.png -jabrefIcon=JabRef-icon.png +jabrefIcon64=JabRef-icon-64.png +jabrefIcon128=JabRef-icon-128.png + #external apps diff --git a/src/main/resources/images/external/JabRef-icon-128.png b/src/main/resources/images/external/JabRef-icon-128.png new file mode 100644 index 00000000000..84bb13b9845 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-128.png differ diff --git a/src/main/resources/images/external/JabRef-icon-16.png b/src/main/resources/images/external/JabRef-icon-16.png new file mode 100644 index 00000000000..677a3123224 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-16.png differ diff --git a/src/main/resources/images/external/JabRef-icon-20.png b/src/main/resources/images/external/JabRef-icon-20.png new file mode 100644 index 00000000000..45ad327b0d6 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-20.png differ diff --git a/src/main/resources/images/external/JabRef-icon-32.png b/src/main/resources/images/external/JabRef-icon-32.png new file mode 100644 index 00000000000..e38098e5909 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-32.png differ diff --git a/src/main/resources/images/external/JabRef-icon-40.png b/src/main/resources/images/external/JabRef-icon-40.png new file mode 100644 index 00000000000..00290293877 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-40.png differ diff --git a/src/main/resources/images/external/JabRef-icon-48.png b/src/main/resources/images/external/JabRef-icon-48.png index ed424d7d25c..7a6159acbe4 100644 Binary files a/src/main/resources/images/external/JabRef-icon-48.png and b/src/main/resources/images/external/JabRef-icon-48.png differ diff --git a/src/main/resources/images/external/JabRef-icon-64.png b/src/main/resources/images/external/JabRef-icon-64.png new file mode 100644 index 00000000000..e807e0448d3 Binary files /dev/null and b/src/main/resources/images/external/JabRef-icon-64.png differ diff --git a/src/main/resources/images/external/JabRef-icon.png b/src/main/resources/images/external/JabRef-icon.png deleted file mode 100644 index 6c5864181e7..00000000000 Binary files a/src/main/resources/images/external/JabRef-icon.png and /dev/null differ diff --git a/src/main/resources/images/icons/JabRef-icon-48.png b/src/main/resources/images/icons/JabRef-icon-48.png deleted file mode 100644 index ed424d7d25c..00000000000 Binary files a/src/main/resources/images/icons/JabRef-icon-48.png and /dev/null differ diff --git a/src/main/resources/images/icons/JabRef-icon-mac.svg b/src/main/resources/images/icons/JabRef-icon-mac.svg deleted file mode 100644 index 39f955f412c..00000000000 --- a/src/main/resources/images/icons/JabRef-icon-mac.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/main/resources/images/icons/JabRef-icon.png b/src/main/resources/images/icons/JabRef-icon.png deleted file mode 100644 index 6c5864181e7..00000000000 Binary files a/src/main/resources/images/icons/JabRef-icon.png and /dev/null differ diff --git a/src/main/resources/images/icons/JabRef-icon.svg b/src/main/resources/images/icons/JabRef-icon.svg deleted file mode 100644 index f14f3b46d38..00000000000 --- a/src/main/resources/images/icons/JabRef-icon.svg +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/test/java/org/jabref/logic/identifier/DOITest.java b/src/test/java/org/jabref/logic/identifier/DOITest.java index b05265a1515..4a66efbdc71 100644 --- a/src/test/java/org/jabref/logic/identifier/DOITest.java +++ b/src/test/java/org/jabref/logic/identifier/DOITest.java @@ -2,18 +2,17 @@ import java.util.Optional; -import org.jabref.logic.identifier.DOI; - import org.junit.Assert; import org.junit.Test; - public class DOITest { + @Test public void acceptPlainDoi() { Assert.assertEquals("10.1006/jmbi.1998.2354", new DOI("10.1006/jmbi.1998.2354").getDOI()); Assert.assertEquals("10.231/JIM.0b013e31820bab4c", new DOI("10.231/JIM.0b013e31820bab4c").getDOI()); - Assert.assertEquals("10.1002/(SICI)1522-2594(199911)42:5<952::AID-MRM16>3.0.CO;2-S", new DOI("10.1002/(SICI)1522-2594(199911)42:5<952::AID-MRM16>3.0.CO;2-S").getDOI()); + Assert.assertEquals("10.1002/(SICI)1522-2594(199911)42:5<952::AID-MRM16>3.0.CO;2-S", + new DOI("10.1002/(SICI)1522-2594(199911)42:5<952::AID-MRM16>3.0.CO;2-S").getDOI()); Assert.assertEquals("10.1126/sciadv.1500214", new DOI("10.1126/sciadv.1500214").getDOI()); } @@ -22,12 +21,12 @@ public void ignoreLeadingAndTrailingWhitespaces() { Assert.assertEquals("10.1006/jmbi.1998.2354", new DOI(" 10.1006/jmbi.1998.2354 ").getDOI()); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void rejectEmbeddedDoi() { new DOI("other stuff 10.1006/jmbi.1998.2354 end"); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void rejectInvalidDirectoryIndicator() { // wrong directory indicator new DOI("12.1006/jmbi.1998.2354 end"); @@ -38,7 +37,7 @@ public void rejectInvalidDoiUri() { new DOI("https://thisisnouri"); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void rejectMissingDivider() { // missing divider new DOI("10.1006jmbi.1998.2354 end"); @@ -70,12 +69,18 @@ public void acceptURLDoi() { Assert.assertEquals("10.1145/1294928.1294933", new DOI("http://doi.acm.net/10.1145/1294928.1294933").getDOI()); Assert.assertEquals("10.1145/1294928.1294933", new DOI("http://doi.acm.com/10.1145/1294928.1294933").getDOI()); Assert.assertEquals("10.1145/1294928.1294933", new DOI("http://doi.acm.de/10.1145/1294928.1294933").getDOI()); - Assert.assertEquals("10.1007/978-3-642-15618-2_19", new DOI("http://dx.doi.org/10.1007/978-3-642-15618-2_19").getDOI()); - Assert.assertEquals("10.1007/978-3-642-15618-2_19", new DOI("http://dx.doi.net/10.1007/978-3-642-15618-2_19").getDOI()); - Assert.assertEquals("10.1007/978-3-642-15618-2_19", new DOI("http://dx.doi.com/10.1007/978-3-642-15618-2_19").getDOI()); - Assert.assertEquals("10.1007/978-3-642-15618-2_19", new DOI("http://dx.doi.de/10.1007/978-3-642-15618-2_19").getDOI()); - Assert.assertEquals("10.4108/ICST.COLLABORATECOM2009.8275", new DOI("http://dx.doi.org/10.4108/ICST.COLLABORATECOM2009.8275").getDOI()); - Assert.assertEquals("10.1109/MIC.2012.43", new DOI("http://doi.ieeecomputersociety.org/10.1109/MIC.2012.43").getDOI()); + Assert.assertEquals("10.1007/978-3-642-15618-2_19", + new DOI("http://dx.doi.org/10.1007/978-3-642-15618-2_19").getDOI()); + Assert.assertEquals("10.1007/978-3-642-15618-2_19", + new DOI("http://dx.doi.net/10.1007/978-3-642-15618-2_19").getDOI()); + Assert.assertEquals("10.1007/978-3-642-15618-2_19", + new DOI("http://dx.doi.com/10.1007/978-3-642-15618-2_19").getDOI()); + Assert.assertEquals("10.1007/978-3-642-15618-2_19", + new DOI("http://dx.doi.de/10.1007/978-3-642-15618-2_19").getDOI()); + Assert.assertEquals("10.4108/ICST.COLLABORATECOM2009.8275", + new DOI("http://dx.doi.org/10.4108/ICST.COLLABORATECOM2009.8275").getDOI()); + Assert.assertEquals("10.1109/MIC.2012.43", + new DOI("http://doi.ieeecomputersociety.org/10.1109/MIC.2012.43").getDOI()); } @Test @@ -97,28 +102,37 @@ public void correctlyDecodeHttpDOIs() { public void correctlyEncodeDOIs() { // See http://www.doi.org/doi_handbook/2_Numbering.html#2.5.2.4 // % -> (%25) - Assert.assertEquals("http://doi.org/10.1006/rwei.1999%25.0001", new DOI("http://doi.org/10.1006/rwei.1999%25.0001").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/rwei.1999%25.0001", + new DOI("http://doi.org/10.1006/rwei.1999%25.0001").getURIAsASCIIString()); // " -> (%22) - Assert.assertEquals("http://doi.org/10.1006/rwei.1999%22.0001", new DOI("http://doi.org/10.1006/rwei.1999%22.0001").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/rwei.1999%22.0001", + new DOI("http://doi.org/10.1006/rwei.1999%22.0001").getURIAsASCIIString()); // # -> (%23) - Assert.assertEquals("http://doi.org/10.1006/rwei.1999%23.0001", new DOI("http://doi.org/10.1006/rwei.1999%23.0001").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/rwei.1999%23.0001", + new DOI("http://doi.org/10.1006/rwei.1999%23.0001").getURIAsASCIIString()); // SPACE -> (%20) - Assert.assertEquals("http://doi.org/10.1006/rwei.1999%20.0001", new DOI("http://doi.org/10.1006/rwei.1999%20.0001").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/rwei.1999%20.0001", + new DOI("http://doi.org/10.1006/rwei.1999%20.0001").getURIAsASCIIString()); // ? -> (%3F) - Assert.assertEquals("http://doi.org/10.1006/rwei.1999%3F.0001", new DOI("http://doi.org/10.1006/rwei.1999%3F.0001").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/rwei.1999%3F.0001", + new DOI("http://doi.org/10.1006/rwei.1999%3F.0001").getURIAsASCIIString()); } @Test public void constructCorrectURLForDoi() { // add / to RESOLVER url if missing - Assert.assertEquals("http://doi.org/10.1006/jmbi.1998.2354", new DOI("10.1006/jmbi.1998.2354").getURIAsASCIIString()); - Assert.assertEquals("http://doi.org/10.1006/jmbi.1998.2354", new DOI("http://doi.org/10.1006/jmbi.1998.2354").getURIAsASCIIString()); - Assert.assertEquals("http://doi.org/10.1109/VLHCC.2004.20", new DOI("doi:10.1109/VLHCC.2004.20").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/jmbi.1998.2354", + new DOI("10.1006/jmbi.1998.2354").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1006/jmbi.1998.2354", + new DOI("http://doi.org/10.1006/jmbi.1998.2354").getURIAsASCIIString()); + Assert.assertEquals("http://doi.org/10.1109/VLHCC.2004.20", + new DOI("doi:10.1109/VLHCC.2004.20").getURIAsASCIIString()); } @Test public void findDoiInsideArbitraryText() { - Assert.assertEquals("10.1006/jmbi.1998.2354", DOI.findInText("other stuff 10.1006/jmbi.1998.2354 end").get().getDOI()); + Assert.assertEquals("10.1006/jmbi.1998.2354", + DOI.findInText("other stuff 10.1006/jmbi.1998.2354 end").get().getDOI()); } @Test diff --git a/src/test/java/org/jabref/logic/identifier/EprintTest.java b/src/test/java/org/jabref/logic/identifier/EprintTest.java index f28c0841c5e..10e756dd49f 100644 --- a/src/test/java/org/jabref/logic/identifier/EprintTest.java +++ b/src/test/java/org/jabref/logic/identifier/EprintTest.java @@ -1,12 +1,10 @@ package org.jabref.logic.identifier; -import org.jabref.logic.identifier.Eprint; - import org.junit.Assert; import org.junit.Test; - public class EprintTest { + @Test public void acceptPlainEprint() { Assert.assertEquals("0706.0001", new Eprint("0706.0001").getEprint()); @@ -28,7 +26,7 @@ public void ignoreLeadingAndTrailingWhitespaces() { Assert.assertEquals("0706.0001v1", new Eprint(" 0706.0001v1 ").getEprint()); } - @Test(expected=IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) public void rejectEmbeddedEprint() { new Eprint("other stuff 0706.0001v1 end"); } diff --git a/src/test/java/org/jabref/logic/identifier/ISBNTest.java b/src/test/java/org/jabref/logic/identifier/ISBNTest.java index be7201fd48f..17afc9699af 100644 --- a/src/test/java/org/jabref/logic/identifier/ISBNTest.java +++ b/src/test/java/org/jabref/logic/identifier/ISBNTest.java @@ -1,16 +1,12 @@ package org.jabref.logic.identifier; -import org.jabref.logic.identifier.ISBN; - import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - public class ISBNTest { - @Test public void testIsValidFormat10Correct() { assertTrue(new ISBN("0-123456-47-9").isValidFormat()); diff --git a/src/test/java/org/jabref/logic/identifier/ISSNTest.java b/src/test/java/org/jabref/logic/identifier/ISSNTest.java index fe6daeb750b..82407067238 100644 --- a/src/test/java/org/jabref/logic/identifier/ISSNTest.java +++ b/src/test/java/org/jabref/logic/identifier/ISSNTest.java @@ -1,17 +1,13 @@ package org.jabref.logic.identifier; -import org.jabref.logic.identifier.ISSN; - import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - public class ISSNTest { - @Test public void testIsCanBeCleaned() { assertTrue(new ISSN("00279633").isCanBeCleaned()); diff --git a/src/test/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroupsTest.java b/src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java similarity index 72% rename from src/test/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroupsTest.java rename to src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java index 3dd549df44c..87af078b8c1 100644 --- a/src/test/java/org/jabref/gui/importer/actions/ConvertLegacyExplicitGroupsTest.java +++ b/src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java @@ -1,30 +1,23 @@ -package org.jabref.gui.importer.actions; +package org.jabref.logic.importer.util; import java.util.Collections; import java.util.Optional; -import org.jabref.gui.BasePanel; import org.jabref.logic.importer.ParserResult; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.AllEntriesGroup; import org.jabref.model.groups.ExplicitGroup; import org.jabref.model.groups.GroupHierarchyType; import org.jabref.model.groups.GroupTreeNode; -import org.jabref.testutils.category.GUITests; import org.junit.Before; import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mockito.Mock; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -@Category(GUITests.class) public class ConvertLegacyExplicitGroupsTest { - private ConvertLegacyExplicitGroups action; - @Mock private BasePanel basePanel; + private PostOpenAction action; private BibEntry entry; private ExplicitGroup group; @@ -42,7 +35,7 @@ public void setUp() throws Exception { public void performActionWritesGroupMembershipInEntry() throws Exception { ParserResult parserResult = generateParserResult(GroupTreeNode.fromGroup(group)); - action.performAction(basePanel, parserResult); + action.performAction(parserResult); assertEquals(Optional.of("TestGroup"), entry.getField("groups")); } @@ -51,7 +44,7 @@ public void performActionWritesGroupMembershipInEntry() throws Exception { public void performActionClearsLegacyKeys() throws Exception { ParserResult parserResult = generateParserResult(GroupTreeNode.fromGroup(group)); - action.performAction(basePanel, parserResult); + action.performAction(parserResult); assertEquals(Collections.emptyList(), group.getLegacyEntryKeys()); } @@ -63,18 +56,11 @@ public void performActionWritesGroupMembershipInEntryForComplexGroupTree() throw root.addSubgroup(group); ParserResult parserResult = generateParserResult(root); - action.performAction(basePanel, parserResult); + action.performAction(parserResult); assertEquals(Optional.of("TestGroup"), entry.getField("groups")); } - @Test - public void isActionNecessaryReturnsTrueIfGroupContainsLegacyKeys() throws Exception { - ParserResult parserResult = generateParserResult(GroupTreeNode.fromGroup(group)); - - assertTrue(action.isActionNecessary(parserResult)); - } - private ParserResult generateParserResult(GroupTreeNode groupRoot) { ParserResult parserResult = new ParserResult(Collections.singletonList(entry)); parserResult.getMetaData().setGroups(groupRoot);