1
1
package org .jabref .gui .groups ;
2
2
3
+ import java .util .List ;
3
4
import java .util .Map ;
4
5
import java .util .Objects ;
6
+ import java .util .Optional ;
5
7
import java .util .concurrent .ConcurrentHashMap ;
6
8
import java .util .function .Function ;
7
9
import java .util .function .Predicate ;
15
17
import javafx .beans .property .SimpleIntegerProperty ;
16
18
import javafx .collections .FXCollections ;
17
19
import javafx .collections .ObservableList ;
20
+ import javafx .scene .input .Dragboard ;
18
21
import javafx .scene .paint .Color ;
19
22
23
+ import org .jabref .gui .DragAndDropDataFormats ;
20
24
import org .jabref .gui .IconTheme ;
21
25
import org .jabref .gui .StateManager ;
22
26
import org .jabref .gui .util .BindingsHelper ;
23
27
import org .jabref .logic .groups .DefaultGroupsFactory ;
24
28
import org .jabref .logic .layout .format .LatexToUnicodeFormatter ;
29
+ import org .jabref .model .FieldChange ;
25
30
import org .jabref .model .database .BibDatabaseContext ;
26
31
import org .jabref .model .entry .BibEntry ;
27
32
import org .jabref .model .entry .event .EntryEvent ;
28
33
import org .jabref .model .groups .AbstractGroup ;
29
34
import org .jabref .model .groups .AutomaticGroup ;
35
+ import org .jabref .model .groups .GroupEntryChanger ;
30
36
import org .jabref .model .groups .GroupTreeNode ;
31
37
import org .jabref .model .strings .StringUtil ;
32
38
@@ -39,6 +45,7 @@ public class GroupNodeViewModel {
39
45
private final boolean isRoot ;
40
46
private final ObservableList <GroupNodeViewModel > children ;
41
47
private final BibDatabaseContext databaseContext ;
48
+ private final StateManager stateManager ;
42
49
private final GroupTreeNode groupNode ;
43
50
private final SimpleIntegerProperty hits ;
44
51
private final SimpleBooleanProperty hasChildren ;
@@ -47,6 +54,7 @@ public class GroupNodeViewModel {
47
54
private final BooleanBinding allSelectedEntriesMatched ;
48
55
public GroupNodeViewModel (BibDatabaseContext databaseContext , StateManager stateManager , GroupTreeNode groupNode ) {
49
56
this .databaseContext = Objects .requireNonNull (databaseContext );
57
+ this .stateManager = Objects .requireNonNull (stateManager );
50
58
this .groupNode = Objects .requireNonNull (groupNode );
51
59
52
60
LatexToUnicodeFormatter formatter = new LatexToUnicodeFormatter ();
@@ -58,7 +66,7 @@ public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager state
58
66
// TODO: Update on changes to entry list (however: there is no flatMap and filter as observable TransformationLists)
59
67
children = databaseContext .getDatabase ()
60
68
.getEntries ().stream ()
61
- .flatMap (stream -> createSubgroups (databaseContext , stateManager , automaticGroup , stream ))
69
+ .flatMap (stream -> createSubgroups (automaticGroup , stream ))
62
70
.filter (distinctByKey (group -> group .getGroupNode ().getName ()))
63
71
.sorted ((group1 , group2 ) -> group1 .getDisplayName ().compareToIgnoreCase (group2 .getDisplayName ()))
64
72
.collect (Collectors .toCollection (FXCollections ::observableArrayList ));
@@ -94,11 +102,25 @@ static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase, Sta
94
102
return new GroupNodeViewModel (newDatabase , stateManager , DefaultGroupsFactory .getAllEntriesGroup ());
95
103
}
96
104
97
- private Stream <GroupNodeViewModel > createSubgroups (BibDatabaseContext databaseContext , StateManager stateManager , AutomaticGroup automaticGroup , BibEntry entry ) {
105
+ private Stream <GroupNodeViewModel > createSubgroups (AutomaticGroup automaticGroup , BibEntry entry ) {
98
106
return automaticGroup .createSubgroups (entry ).stream ()
99
107
.map (child -> new GroupNodeViewModel (databaseContext , stateManager , child ));
100
108
}
101
109
110
+ public List <FieldChange > addEntriesToGroup (List <BibEntry > entries ) {
111
+ // TODO: warn if assignment has undesired side effects (modifies a field != keywords)
112
+ //if (!WarnAssignmentSideEffects.warnAssignmentSideEffects(group, groupSelector.frame))
113
+ //{
114
+ // return; // user aborted operation
115
+ //}
116
+
117
+ return groupNode .addEntriesToGroup (entries );
118
+
119
+ // TODO: Store undo
120
+ // if (!undo.isEmpty()) {
121
+ // groupSelector.concludeAssignment(UndoableChangeEntriesOfGroup.getUndoableEdit(target, undo), target.getNode(), assignedEntries);
122
+ }
123
+
102
124
public SimpleBooleanProperty expandedProperty () {
103
125
return expandedProperty ;
104
126
}
@@ -133,12 +155,18 @@ public SimpleIntegerProperty getHits() {
133
155
134
156
@ Override
135
157
public boolean equals (Object o ) {
136
- if (this == o ) return true ;
137
- if (o == null || getClass () != o .getClass ()) return false ;
158
+ if (this == o ) {
159
+ return true ;
160
+ }
161
+ if ((o == null ) || (getClass () != o .getClass ())) {
162
+ return false ;
163
+ }
138
164
139
165
GroupNodeViewModel that = (GroupNodeViewModel ) o ;
140
166
141
- if (!groupNode .equals (that .groupNode )) return false ;
167
+ if (!groupNode .equals (that .groupNode )) {
168
+ return false ;
169
+ }
142
170
return true ;
143
171
}
144
172
@@ -205,4 +233,38 @@ boolean isMatchedBy(String searchString) {
205
233
public Color getColor () {
206
234
return groupNode .getGroup ().getColor ().orElse (IconTheme .getDefaultColor ());
207
235
}
236
+
237
+ public String getPath () {
238
+ return groupNode .getPath ();
239
+ }
240
+
241
+ public Optional <GroupNodeViewModel > getChildByPath (String pathToSource ) {
242
+ return groupNode .getChildByPath (pathToSource ).map (child -> new GroupNodeViewModel (databaseContext , stateManager , child ));
243
+ }
244
+
245
+ /**
246
+ * Decides if the content stored in the given {@link Dragboard} can be droped on the given target row.
247
+ * Currently, the following sources are allowed:
248
+ * - another group (will be added as subgroup on drop)
249
+ * - entries if the group implements {@link GroupEntryChanger} (will be assigned to group on drop)
250
+ */
251
+ public boolean acceptableDrop (Dragboard dragboard ) {
252
+ // TODO: we should also check isNodeDescendant
253
+ boolean canDropOtherGroup = dragboard .hasContent (DragAndDropDataFormats .GROUP );
254
+ boolean canDropEntries = dragboard .hasContent (DragAndDropDataFormats .ENTRIES )
255
+ && groupNode .getGroup () instanceof GroupEntryChanger ;
256
+ return canDropOtherGroup || canDropEntries ;
257
+ }
258
+
259
+ public void moveTo (GroupNodeViewModel target ) {
260
+ // TODO: Add undo and display message
261
+ //MoveGroupChange undo = new MoveGroupChange(((GroupTreeNodeViewModel)source.getParent()).getNode(),
262
+ // source.getNode().getPositionInParent(), target.getNode(), target.getChildCount());
263
+
264
+ getGroupNode ().moveTo (target .getGroupNode ());
265
+ //panel.getUndoManager().addEdit(new UndoableMoveGroup(this.groupsRoot, moveChange));
266
+ //panel.markBaseChanged();
267
+ //frame.output(Localization.lang("Moved group \"%0\".", node.getNode().getGroup().getName()));
268
+
269
+ }
208
270
}
0 commit comments