Skip to content

Commit c47d2a4

Browse files
authored
Add file description to gui and fix sync bug (#3210)
* Add file description to gui Add tests for identifying file descr bug * add properties to LinkedFiel * Fix observable Fix serializing * add tooltip again add changelog * add automatically found to observables Show description first then file link remove unnecesary separator * Remove some empty lines
1 parent a0e5529 commit c47d2a4

File tree

6 files changed

+145
-36
lines changed

6 files changed

+145
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
2121
- We added reordering of file and link entries in the `General`-Tab [3165, comment](https://github.com/JabRef/jabref/issues/3165#issuecomment-326269715)
2222
- 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 <kbd>Enter</kbd> two times, otherwise the field data is not stored in the library file.[koppor#257](https://github.com/koppor/jabref/issues/257)
2323
- 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)
24+
- 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)
2425

2526
### Fixed
2627

@@ -43,7 +44,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
4344
- 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)
4445
- Renaming files now truncates the filename to not exceed the limit of 255 chars [#2622](https://github.com/JabRef/jabref/issues/2622)
4546
- We improved the handling of hyphens in names. [#2775](https://github.com/JabRef/jabref/issues/2775)
46-
47+
- We fixed an issue where an entered file description was not written to the bib-file [#3208](https://github.com/JabRef/jabref/issues/3208)
4748
### Removed
4849
- We removed support for LatexEditor, as it is not under active development. [#3199](https://github.com/JabRef/jabref/issues/3199)
4950

src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.nio.file.Files;
55
import java.nio.file.Path;
66
import java.nio.file.Paths;
7+
import java.util.ArrayList;
8+
import java.util.Arrays;
79
import java.util.List;
810
import java.util.Optional;
911

@@ -108,7 +110,11 @@ public void acceptAsLinked() {
108110
}
109111

110112
public Observable[] getObservables() {
111-
return new Observable[] {this.downloadProgress, this.isAutomaticallyFound};
113+
List<Observable> observables = new ArrayList<>(Arrays.asList(linkedFile.getObservables()));
114+
observables.add(downloadOngoing);
115+
observables.add(downloadProgress);
116+
observables.add(isAutomaticallyFound);
117+
return observables.toArray(new Observable[observables.size()]);
112118
}
113119

114120
public void open() {

src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ private void handleOnDragDropped(LinkedFileViewModel originalItem, DragEvent eve
148148

149149
private static Node createFileDisplay(LinkedFileViewModel linkedFile) {
150150
Text icon = MaterialDesignIconFactory.get().createIcon(linkedFile.getTypeIcon());
151-
Text text = new Text(linkedFile.getLink());
151+
Text link = new Text(linkedFile.getLink());
152+
Text desc = new Text(linkedFile.getDescription());
153+
152154
ProgressBar progressIndicator = new ProgressBar();
153155
progressIndicator.progressProperty().bind(linkedFile.downloadProgressProperty());
154156
progressIndicator.visibleProperty().bind(linkedFile.downloadOngoingProperty());
@@ -161,7 +163,9 @@ private static Node createFileDisplay(LinkedFileViewModel linkedFile) {
161163

162164
HBox container = new HBox(10);
163165
container.setPrefHeight(Double.NEGATIVE_INFINITY);
164-
container.getChildren().addAll(icon, text, progressIndicator, acceptAutoLinkedFile);
166+
167+
container.getChildren().addAll(icon, desc, link, progressIndicator, acceptAutoLinkedFile);
168+
165169
return container;
166170
}
167171

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.jabref.model.entry;
22

3+
import java.io.IOException;
4+
import java.io.ObjectInputStream;
5+
import java.io.ObjectOutputStream;
36
import java.io.Serializable;
47
import java.net.URL;
58
import java.nio.file.Path;
@@ -8,6 +11,10 @@
811
import java.util.Objects;
912
import java.util.Optional;
1013

14+
import javafx.beans.Observable;
15+
import javafx.beans.property.SimpleStringProperty;
16+
import javafx.beans.property.StringProperty;
17+
1118
import org.jabref.model.database.BibDatabaseContext;
1219
import org.jabref.model.metadata.FileDirectoryPreferences;
1320
import org.jabref.model.util.FileHelper;
@@ -19,42 +26,47 @@
1926
public class LinkedFile implements Serializable {
2027

2128
private static final LinkedFile NULL_OBJECT = new LinkedFile("", "", "");
22-
private String description;
23-
private String link;
24-
private String fileType;
29+
//We have to mark these properties as transient because they can't be serialized directly
30+
private transient StringProperty description = new SimpleStringProperty();
31+
private transient StringProperty link = new SimpleStringProperty();
32+
private transient StringProperty fileType = new SimpleStringProperty();
2533

2634
public LinkedFile(String description, String link, String fileType) {
27-
this.description = Objects.requireNonNull(description);
28-
this.link = Objects.requireNonNull(link);
29-
this.fileType = Objects.requireNonNull(fileType);
35+
this.description.setValue(Objects.requireNonNull(description));
36+
this.link.setValue(Objects.requireNonNull(link));
37+
this.fileType.setValue(Objects.requireNonNull(fileType));
3038
}
3139

3240
public LinkedFile(String description, URL link, String fileType) {
3341
this(description, Objects.requireNonNull(link).toString(), fileType);
3442
}
3543

3644
public String getFileType() {
37-
return fileType;
45+
return fileType.get();
3846
}
3947

4048
public void setFileType(String fileType) {
41-
this.fileType = fileType;
49+
this.fileType.setValue(fileType);
4250
}
4351

4452
public String getDescription() {
45-
return description;
53+
return description.get();
4654
}
4755

4856
public void setDescription(String description) {
49-
this.description = description;
57+
this.description.setValue(description);
5058
}
5159

5260
public String getLink() {
53-
return link;
61+
return link.get();
5462
}
5563

5664
public void setLink(String link) {
57-
this.link = link;
65+
this.link.setValue(link);
66+
}
67+
68+
public Observable[] getObservables() {
69+
return new Observable[] {this.link, this.description, this.fileType};
5870
}
5971

6072
@Override
@@ -63,31 +75,48 @@ public boolean equals(Object o) {
6375
return true;
6476
}
6577
if (o instanceof LinkedFile) {
66-
6778
LinkedFile that = (LinkedFile) o;
68-
69-
if (!this.description.equals(that.description)) {
70-
return false;
71-
}
72-
if (!this.link.equals(that.link)) {
73-
return false;
74-
}
75-
return this.fileType.equals(that.fileType);
79+
return Objects.equals(description.get(), that.description.get())
80+
&& Objects.equals(link.get(), that.link.get())
81+
&& Objects.equals(fileType.get(), that.fileType.get());
7682
}
7783
return false;
7884
}
7985

86+
/**
87+
* Writes serialized object to ObjectOutputStream, automatically called
88+
* @param out {@link ObjectOutputStream}
89+
* @throws IOException
90+
*/
91+
private void writeObject(ObjectOutputStream out) throws IOException {
92+
out.writeUTF(getFileType());
93+
out.writeUTF(getLink());
94+
out.writeUTF(getDescription());
95+
out.flush();
96+
}
97+
98+
/**
99+
* Reads serialized object from ObjectInputStreamm, automatically called
100+
* @param in {@link ObjectInputStream}
101+
* @throws IOException
102+
*/
103+
private void readObject(ObjectInputStream in) throws IOException {
104+
fileType = new SimpleStringProperty(in.readUTF());
105+
link = new SimpleStringProperty(in.readUTF());
106+
description = new SimpleStringProperty(in.readUTF());
107+
}
108+
80109
@Override
81110
public int hashCode() {
82-
return Objects.hash(description, link, fileType);
111+
return Objects.hash(description.get(), link.get(), fileType.get());
83112
}
84113

85114
@Override
86115
public String toString() {
87116
return "ParsedFileField{" +
88-
"description='" + description + '\'' +
89-
", link='" + link + '\'' +
90-
", fileType='" + fileType + '\'' +
117+
"description='" + description.get() + '\'' +
118+
", link='" + link.get() + '\'' +
119+
", fileType='" + fileType.get() + '\'' +
91120
'}';
92121
}
93122

@@ -96,7 +125,7 @@ public boolean isEmpty() {
96125
}
97126

98127
public boolean isOnlineLink() {
99-
return link.startsWith("http://") || link.startsWith("https://") || link.contains("www.");
128+
return link.get().startsWith("http://") || link.get().startsWith("https://") || link.get().contains("www.");
100129
}
101130

102131
public Optional<Path> findIn(BibDatabaseContext databaseContext, FileDirectoryPreferences fileDirectoryPreferences) {
@@ -105,11 +134,11 @@ public Optional<Path> findIn(BibDatabaseContext databaseContext, FileDirectoryPr
105134
}
106135

107136
public Optional<Path> findIn(List<Path> directories) {
108-
Path file = Paths.get(link);
137+
Path file = Paths.get(link.get());
109138
if (file.isAbsolute() || directories.isEmpty()) {
110139
return Optional.of(file);
111140
} else {
112-
return FileHelper.expandFilenameAsPath(link, directories);
141+
return FileHelper.expandFilenameAsPath(link.get(), directories);
113142
}
114143
}
115144
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.jabref.model.entry;
2+
3+
import org.jabref.logic.exporter.BibtexDatabaseWriter;
4+
import org.jabref.logic.exporter.SaveException;
5+
import org.jabref.logic.exporter.SavePreferences;
6+
import org.jabref.logic.exporter.StringSaveSession;
7+
import org.jabref.logic.util.OS;
8+
import org.jabref.model.Defaults;
9+
import org.jabref.model.database.BibDatabase;
10+
import org.jabref.model.database.BibDatabaseContext;
11+
import org.jabref.model.metadata.MetaData;
12+
13+
import org.junit.Before;
14+
import org.junit.Test;
15+
16+
import static org.junit.Assert.assertEquals;
17+
18+
public class FileFieldBibEntryTest {
19+
20+
private BibEntry emptyEntry;
21+
22+
@Before
23+
public void setUp() {
24+
emptyEntry = new BibEntry();
25+
emptyEntry.setType("article");
26+
emptyEntry.setChanged(false);
27+
}
28+
29+
@Test
30+
public void testFileFieldSerialization() {
31+
LinkedFile file = new LinkedFile("test", "/home/uers/test.pdf", "PDF");
32+
emptyEntry.addFile(file);
33+
34+
assertEquals("@article{,\n" +
35+
" file = {test:/home/uers/test.pdf:PDF}\n" +
36+
"}", emptyEntry.toString());
37+
}
38+
39+
@Test
40+
public void testFileFieldSerializationDatabase() throws SaveException {
41+
BibDatabase database = new BibDatabase();
42+
43+
LinkedFile file = new LinkedFile("test", "/home/uers/test.pdf", "PDF");
44+
emptyEntry.addFile(file);
45+
database.insertEntries(emptyEntry);
46+
47+
BibtexDatabaseWriter<StringSaveSession> databaseWriter = new BibtexDatabaseWriter<>(StringSaveSession::new);
48+
StringSaveSession saveSession = databaseWriter.savePartOfDatabase(
49+
new BibDatabaseContext(database, new MetaData(), new Defaults()), database.getEntries(),
50+
new SavePreferences());
51+
52+
assertEquals(OS.NEWLINE +
53+
"@Article{,"
54+
+ OS.NEWLINE
55+
+ " file = {test:/home/uers/test.pdf:PDF},"
56+
+ OS.NEWLINE
57+
+ "}" + OS.NEWLINE
58+
+ OS.NEWLINE
59+
+ "@Comment{jabref-meta: databaseType:bibtex;}" + OS.NEWLINE, saveSession.getStringValue());
60+
}
61+
}

src/test/java/org/jabref/model/entry/FileFieldWriterTest.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,17 @@ public void testQuoteNull() {
103103

104104
@Test
105105
public void testEncodeStringArray() {
106-
assertEquals("a:b;c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", "b"}, {"c", "d"}}));
107-
assertEquals("a:;c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", ""}, {"c", "d"}}));
108-
assertEquals("a:" + null + ";c:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", null}, {"c", "d"}}));
109-
assertEquals("a:\\:b;c\\;:d", FileFieldWriter.encodeStringArray(new String[][]{{"a", ":b"}, {"c;", "d"}}));
106+
assertEquals("a:b;c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", "b"}, {"c", "d"}}));
107+
assertEquals("a:;c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", ""}, {"c", "d"}}));
108+
assertEquals("a:" + null + ";c:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", null}, {"c", "d"}}));
109+
assertEquals("a:\\:b;c\\;:d", FileFieldWriter.encodeStringArray(new String[][] {{"a", ":b"}, {"c;", "d"}}));
110110
}
111+
112+
@Test
113+
public void testFileFieldWriterGetStringRepresentation() {
114+
LinkedFile file = new LinkedFile("test", "X:\\Users\\abc.pdf", "PDF");
115+
assertEquals("test:X\\:\\\\Users\\\\abc.pdf:PDF", FileFieldWriter.getStringRepresentation(file));
116+
}
117+
118+
111119
}

0 commit comments

Comments
 (0)