diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba7ac2c2f03..2af5edc93d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We added reordering of file and link entries in the `General`-Tab [3165, comment](https://github.com/JabRef/jabref/issues/3165#issuecomment-326269715)
- We added autcompletion for the `crossref` field on basis of the BibTeX-key. To accept such an autcompleted key as new entry-link, you have to press Enter two times, otherwise the field data is not stored in the library file.[koppor#257](https://github.com/koppor/jabref/issues/257)
- We added drag and drop support for adding files directly in the `General`-Tab. The dragged files are currently only linked from their existing directory. For more advanced features use the `Add files` dialog. [#koppor#244](https://github.com/koppor/jabref/issues/244)
+- We added the file description filed back to the list of files in the `General`-Tab [#2930, comment](https://github.com/JabRef/jabref/issues/2930#issuecomment-328328172)
### Fixed
@@ -43,7 +44,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We fixed an issue where it was possible to leave the entry editor with an imbalance of braces. [#3167](https://github.com/JabRef/jabref/issues/3167)
- Renaming files now truncates the filename to not exceed the limit of 255 chars [#2622](https://github.com/JabRef/jabref/issues/2622)
- We improved the handling of hyphens in names. [#2775](https://github.com/JabRef/jabref/issues/2775)
-
+- We fixed an issue where an entered file description was not written to the bib-file [#3208](https://github.com/JabRef/jabref/issues/3208)
### Removed
- We removed support for LatexEditor, as it is not under active development. [#3199](https://github.com/JabRef/jabref/issues/3199)
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java
index 36e76077387..eb3df49b52f 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java
@@ -4,6 +4,8 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -108,7 +110,11 @@ public void acceptAsLinked() {
}
public Observable[] getObservables() {
- return new Observable[] {this.downloadProgress, this.isAutomaticallyFound};
+ List observables = new ArrayList<>(Arrays.asList(linkedFile.getObservables()));
+ observables.add(downloadOngoing);
+ observables.add(downloadProgress);
+ observables.add(isAutomaticallyFound);
+ return observables.toArray(new Observable[observables.size()]);
}
public void open() {
diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
index 27745013a06..f4f966dab0d 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java
@@ -148,7 +148,9 @@ private void handleOnDragDropped(LinkedFileViewModel originalItem, DragEvent eve
private static Node createFileDisplay(LinkedFileViewModel linkedFile) {
Text icon = MaterialDesignIconFactory.get().createIcon(linkedFile.getTypeIcon());
- Text text = new Text(linkedFile.getLink());
+ Text link = new Text(linkedFile.getLink());
+ Text desc = new Text(linkedFile.getDescription());
+
ProgressBar progressIndicator = new ProgressBar();
progressIndicator.progressProperty().bind(linkedFile.downloadProgressProperty());
progressIndicator.visibleProperty().bind(linkedFile.downloadOngoingProperty());
@@ -161,7 +163,9 @@ private static Node createFileDisplay(LinkedFileViewModel linkedFile) {
HBox container = new HBox(10);
container.setPrefHeight(Double.NEGATIVE_INFINITY);
- container.getChildren().addAll(icon, text, progressIndicator, acceptAutoLinkedFile);
+
+ container.getChildren().addAll(icon, desc, link, progressIndicator, acceptAutoLinkedFile);
+
return container;
}
diff --git a/src/main/java/org/jabref/model/entry/LinkedFile.java b/src/main/java/org/jabref/model/entry/LinkedFile.java
index 47c207f14b5..82d8321c53d 100644
--- a/src/main/java/org/jabref/model/entry/LinkedFile.java
+++ b/src/main/java/org/jabref/model/entry/LinkedFile.java
@@ -1,5 +1,8 @@
package org.jabref.model.entry;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URL;
import java.nio.file.Path;
@@ -8,6 +11,10 @@
import java.util.Objects;
import java.util.Optional;
+import javafx.beans.Observable;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.metadata.FileDirectoryPreferences;
import org.jabref.model.util.FileHelper;
@@ -19,14 +26,15 @@
public class LinkedFile implements Serializable {
private static final LinkedFile NULL_OBJECT = new LinkedFile("", "", "");
- private String description;
- private String link;
- private String fileType;
+ //We have to mark these properties as transient because they can't be serialized directly
+ private transient StringProperty description = new SimpleStringProperty();
+ private transient StringProperty link = new SimpleStringProperty();
+ private transient StringProperty fileType = new SimpleStringProperty();
public LinkedFile(String description, String link, String fileType) {
- this.description = Objects.requireNonNull(description);
- this.link = Objects.requireNonNull(link);
- this.fileType = Objects.requireNonNull(fileType);
+ this.description.setValue(Objects.requireNonNull(description));
+ this.link.setValue(Objects.requireNonNull(link));
+ this.fileType.setValue(Objects.requireNonNull(fileType));
}
public LinkedFile(String description, URL link, String fileType) {
@@ -34,27 +42,31 @@ public LinkedFile(String description, URL link, String fileType) {
}
public String getFileType() {
- return fileType;
+ return fileType.get();
}
public void setFileType(String fileType) {
- this.fileType = fileType;
+ this.fileType.setValue(fileType);
}
public String getDescription() {
- return description;
+ return description.get();
}
public void setDescription(String description) {
- this.description = description;
+ this.description.setValue(description);
}
public String getLink() {
- return link;
+ return link.get();
}
public void setLink(String link) {
- this.link = link;
+ this.link.setValue(link);
+ }
+
+ public Observable[] getObservables() {
+ return new Observable[] {this.link, this.description, this.fileType};
}
@Override
@@ -63,31 +75,48 @@ public boolean equals(Object o) {
return true;
}
if (o instanceof LinkedFile) {
-
LinkedFile that = (LinkedFile) o;
-
- if (!this.description.equals(that.description)) {
- return false;
- }
- if (!this.link.equals(that.link)) {
- return false;
- }
- return this.fileType.equals(that.fileType);
+ return Objects.equals(description.get(), that.description.get())
+ && Objects.equals(link.get(), that.link.get())
+ && Objects.equals(fileType.get(), that.fileType.get());
}
return false;
}
+ /**
+ * Writes serialized object to ObjectOutputStream, automatically called
+ * @param out {@link ObjectOutputStream}
+ * @throws IOException
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.writeUTF(getFileType());
+ out.writeUTF(getLink());
+ out.writeUTF(getDescription());
+ out.flush();
+ }
+
+ /**
+ * Reads serialized object from ObjectInputStreamm, automatically called
+ * @param in {@link ObjectInputStream}
+ * @throws IOException
+ */
+ private void readObject(ObjectInputStream in) throws IOException {
+ fileType = new SimpleStringProperty(in.readUTF());
+ link = new SimpleStringProperty(in.readUTF());
+ description = new SimpleStringProperty(in.readUTF());
+ }
+
@Override
public int hashCode() {
- return Objects.hash(description, link, fileType);
+ return Objects.hash(description.get(), link.get(), fileType.get());
}
@Override
public String toString() {
return "ParsedFileField{" +
- "description='" + description + '\'' +
- ", link='" + link + '\'' +
- ", fileType='" + fileType + '\'' +
+ "description='" + description.get() + '\'' +
+ ", link='" + link.get() + '\'' +
+ ", fileType='" + fileType.get() + '\'' +
'}';
}
@@ -96,7 +125,7 @@ public boolean isEmpty() {
}
public boolean isOnlineLink() {
- return link.startsWith("http://") || link.startsWith("https://") || link.contains("www.");
+ return link.get().startsWith("http://") || link.get().startsWith("https://") || link.get().contains("www.");
}
public Optional findIn(BibDatabaseContext databaseContext, FileDirectoryPreferences fileDirectoryPreferences) {
@@ -105,11 +134,11 @@ public Optional findIn(BibDatabaseContext databaseContext, FileDirectoryPr
}
public Optional findIn(List directories) {
- Path file = Paths.get(link);
+ Path file = Paths.get(link.get());
if (file.isAbsolute() || directories.isEmpty()) {
return Optional.of(file);
} else {
- return FileHelper.expandFilenameAsPath(link, directories);
+ return FileHelper.expandFilenameAsPath(link.get(), directories);
}
}
}
diff --git a/src/test/java/org/jabref/model/entry/FileFieldBibEntryTest.java b/src/test/java/org/jabref/model/entry/FileFieldBibEntryTest.java
new file mode 100644
index 00000000000..54699f411da
--- /dev/null
+++ b/src/test/java/org/jabref/model/entry/FileFieldBibEntryTest.java
@@ -0,0 +1,61 @@
+package org.jabref.model.entry;
+
+import org.jabref.logic.exporter.BibtexDatabaseWriter;
+import org.jabref.logic.exporter.SaveException;
+import org.jabref.logic.exporter.SavePreferences;
+import org.jabref.logic.exporter.StringSaveSession;
+import org.jabref.logic.util.OS;
+import org.jabref.model.Defaults;
+import org.jabref.model.database.BibDatabase;
+import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.metadata.MetaData;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class FileFieldBibEntryTest {
+
+ private BibEntry emptyEntry;
+
+ @Before
+ public void setUp() {
+ emptyEntry = new BibEntry();
+ emptyEntry.setType("article");
+ emptyEntry.setChanged(false);
+ }
+
+ @Test
+ public void testFileFieldSerialization() {
+ LinkedFile file = new LinkedFile("test", "/home/uers/test.pdf", "PDF");
+ emptyEntry.addFile(file);
+
+ assertEquals("@article{,\n" +
+ " file = {test:/home/uers/test.pdf:PDF}\n" +
+ "}", emptyEntry.toString());
+ }
+
+ @Test
+ public void testFileFieldSerializationDatabase() throws SaveException {
+ BibDatabase database = new BibDatabase();
+
+ LinkedFile file = new LinkedFile("test", "/home/uers/test.pdf", "PDF");
+ emptyEntry.addFile(file);
+ database.insertEntries(emptyEntry);
+
+ BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter<>(StringSaveSession::new);
+ StringSaveSession saveSession = databaseWriter.savePartOfDatabase(
+ new BibDatabaseContext(database, new MetaData(), new Defaults()), database.getEntries(),
+ new SavePreferences());
+
+ assertEquals(OS.NEWLINE +
+ "@Article{,"
+ + OS.NEWLINE
+ + " file = {test:/home/uers/test.pdf:PDF},"
+ + OS.NEWLINE
+ + "}" + OS.NEWLINE
+ + OS.NEWLINE
+ + "@Comment{jabref-meta: databaseType:bibtex;}" + OS.NEWLINE, saveSession.getStringValue());
+ }
+}
diff --git a/src/test/java/org/jabref/model/entry/FileFieldWriterTest.java b/src/test/java/org/jabref/model/entry/FileFieldWriterTest.java
index b507b7bebae..bce6908323c 100644
--- a/src/test/java/org/jabref/model/entry/FileFieldWriterTest.java
+++ b/src/test/java/org/jabref/model/entry/FileFieldWriterTest.java
@@ -103,9 +103,17 @@ public void testQuoteNull() {
@Test
public void testEncodeStringArray() {
- assertEquals("a:b;c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", "b"}, {"c", "d"}}));
- assertEquals("a:;c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", ""}, {"c", "d"}}));
- assertEquals("a:" + null + ";c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", null}, {"c", "d"}}));
- assertEquals("a:\\:b;c\\;:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", ":b"}, {"c;", "d"}}));
+ assertEquals("a:b;c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", "b"}, {"c", "d"}}));
+ assertEquals("a:;c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", ""}, {"c", "d"}}));
+ assertEquals("a:" + null + ";c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", null}, {"c", "d"}}));
+ assertEquals("a:\\:b;c\\;:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", ":b"}, {"c;", "d"}}));
}
+
+ @Test
+ public void testFileFieldWriterGetStringRepresentation() {
+ LinkedFile file = new LinkedFile("test", "X:\\Users\\abc.pdf", "PDF");
+ assertEquals("test:X\\:\\\\Users\\\\abc.pdf:PDF", FileFieldWriter.getStringRepresentation(file));
+ }
+
+
}