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 @@
+
+
+
+
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 @@
-
-
-
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 @@
-
-
-
-
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);