1
|
/**
|
2
|
* Copyright (C) 2019 EDIT
|
3
|
* European Distributed Institute of Taxonomy
|
4
|
* http://www.e-taxonomy.eu
|
5
|
*
|
6
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
7
|
* See LICENSE.TXT at the top of this package for the full license terms.
|
8
|
*/
|
9
|
package eu.etaxonomy.taxeditor.view.search.facet;
|
10
|
|
11
|
import java.util.ArrayList;
|
12
|
import java.util.Collections;
|
13
|
import java.util.Comparator;
|
14
|
import java.util.HashSet;
|
15
|
import java.util.List;
|
16
|
import java.util.Map;
|
17
|
import java.util.Map.Entry;
|
18
|
import java.util.Set;
|
19
|
import java.util.TreeMap;
|
20
|
|
21
|
import org.eclipse.jface.layout.GridDataFactory;
|
22
|
import org.eclipse.swt.SWT;
|
23
|
import org.eclipse.swt.events.KeyEvent;
|
24
|
import org.eclipse.swt.events.KeyListener;
|
25
|
import org.eclipse.swt.events.SelectionEvent;
|
26
|
import org.eclipse.swt.events.SelectionListener;
|
27
|
import org.eclipse.swt.layout.GridLayout;
|
28
|
import org.eclipse.swt.widgets.Composite;
|
29
|
import org.eclipse.swt.widgets.Group;
|
30
|
|
31
|
import eu.etaxonomy.taxeditor.model.MessagingUtils;
|
32
|
|
33
|
/**
|
34
|
* @author pplitzner
|
35
|
* @since Jan 22, 2019
|
36
|
*
|
37
|
*/
|
38
|
public abstract class SearchController<S extends SearchResult<T>, T> implements KeyListener, SelectionListener{
|
39
|
|
40
|
private SearchComposite composite;
|
41
|
private List<S> searchResults = new ArrayList<>();
|
42
|
private Set<Facet> appliedFacets = new HashSet<>();
|
43
|
private List<CheckBoxSearchResultComposite<T, S>> searchResultComposites = new ArrayList<>();
|
44
|
|
45
|
public List<CheckBoxSearchResultComposite<T, S>> getSearchResultComposites() {
|
46
|
return searchResultComposites;
|
47
|
}
|
48
|
|
49
|
public SearchController(SearchComposite composite) {
|
50
|
this.composite = composite;
|
51
|
composite.getTxtSearch().addKeyListener(this);
|
52
|
composite.getBtnSearchButton().addSelectionListener(this);
|
53
|
}
|
54
|
|
55
|
protected abstract List<S> searchResults(String searchString);
|
56
|
|
57
|
protected abstract CheckBoxSearchResultComposite<T, S> createResultComposite(S result, Composite parent);
|
58
|
|
59
|
protected abstract Comparator<S> getResultComparator(String searchString);
|
60
|
|
61
|
protected abstract List<S> getSelectedResults();
|
62
|
|
63
|
private void search(String searchString){
|
64
|
searchResults.clear();
|
65
|
searchResultComposites.clear();
|
66
|
|
67
|
searchResults = searchResults(searchString);
|
68
|
if(searchResults.size()>500){
|
69
|
MessagingUtils.warningDialog("Specify your search", this, "The following search has too many results. Please enter a more specific search query.");
|
70
|
return;
|
71
|
}
|
72
|
|
73
|
Collections.sort(searchResults, getResultComparator(searchString));
|
74
|
|
75
|
Set<Facet> facets = createResults(searchResults);
|
76
|
|
77
|
createFilterButtons(facets);
|
78
|
|
79
|
composite.refresh();
|
80
|
}
|
81
|
|
82
|
private void createFilterButtons(Set<Facet> facets) {
|
83
|
Map<String, List<Facet>> categoryToFacetsMap = new TreeMap<>();//(String o1, String o2)->o1.compareTo(o2));
|
84
|
for (Facet facet : facets) {
|
85
|
String category = facet.getCategory();
|
86
|
if(category==null){
|
87
|
category = "None";
|
88
|
}
|
89
|
List<Facet> categoryFacets = categoryToFacetsMap.get(category);
|
90
|
if(categoryFacets==null){
|
91
|
categoryFacets = new ArrayList<>();
|
92
|
}
|
93
|
categoryFacets.add(facet);
|
94
|
categoryToFacetsMap.put(category, categoryFacets);
|
95
|
}
|
96
|
for (Entry<String, List<Facet>> entry: categoryToFacetsMap.entrySet()) {
|
97
|
String category = entry.getKey();
|
98
|
// create group
|
99
|
Group group = new Group(composite.getFilterListComposite(), SWT.NONE);
|
100
|
group.setLayout(new GridLayout());
|
101
|
GridDataFactory.fillDefaults().applyTo(group);
|
102
|
group.setText(category!=null?category:"None");
|
103
|
// fill group with facet filters
|
104
|
List<Facet> categoryFacets = entry.getValue();
|
105
|
for (Facet facet : categoryFacets) {
|
106
|
if(facet.getFacet()!=null){
|
107
|
FilterComposite filterComposite = new FilterComposite(facet, this, group, SWT.NONE);
|
108
|
appliedFacets.add(facet);
|
109
|
}
|
110
|
}
|
111
|
}
|
112
|
|
113
|
}
|
114
|
|
115
|
private Set<Facet> createResults(List<S> results) {
|
116
|
Set<Facet> facets = new HashSet<>();
|
117
|
searchResultComposites.clear();
|
118
|
for (S result : results) {
|
119
|
|
120
|
CheckBoxSearchResultComposite checkComp = createResultComposite(result, composite.getSearchResultComposite());
|
121
|
|
122
|
searchResultComposites.add(checkComp);
|
123
|
facets.addAll(result.getFacets());
|
124
|
}
|
125
|
return facets;
|
126
|
}
|
127
|
|
128
|
public void applyFilter(FilterComposite filterComposite) {
|
129
|
|
130
|
composite.clearResults();
|
131
|
|
132
|
Facet facet = filterComposite.getFacet();
|
133
|
if(filterComposite.isFilterActive()){
|
134
|
appliedFacets.add(facet);
|
135
|
}
|
136
|
else{
|
137
|
appliedFacets.remove(facet);
|
138
|
}
|
139
|
|
140
|
searchResultComposites.clear();
|
141
|
for (S searchResult : searchResults) {
|
142
|
if(searchResult.hasAnyFacet(appliedFacets)){
|
143
|
searchResultComposites.add(createResultComposite(searchResult, composite.getSearchResultComposite()));
|
144
|
}
|
145
|
}
|
146
|
|
147
|
composite.refresh();
|
148
|
}
|
149
|
|
150
|
protected void search(){
|
151
|
composite.clear();
|
152
|
search(composite.getTxtSearch().getText());
|
153
|
|
154
|
}
|
155
|
|
156
|
public List<S> getSelectedSearchResults(){
|
157
|
List<S> selectedSearchResults = new ArrayList<>();
|
158
|
searchResultComposites.stream()
|
159
|
.filter(resultComposite->resultComposite.getBtnCheck().getSelection())
|
160
|
.forEach(selected->selectedSearchResults.add(selected.getResult()));
|
161
|
return selectedSearchResults;
|
162
|
}
|
163
|
|
164
|
@Override
|
165
|
public void keyPressed(KeyEvent e) {
|
166
|
if(e.keyCode==SWT.CR && e.widget==composite.getTxtSearch()){
|
167
|
search();
|
168
|
return;
|
169
|
}
|
170
|
|
171
|
}
|
172
|
|
173
|
@Override
|
174
|
public void keyReleased(KeyEvent e) {
|
175
|
}
|
176
|
|
177
|
@Override
|
178
|
public void widgetSelected(SelectionEvent e) {
|
179
|
if(e.widget==composite.getBtnSearchButton()){
|
180
|
search();
|
181
|
}
|
182
|
}
|
183
|
|
184
|
@Override
|
185
|
public void widgetDefaultSelected(SelectionEvent e) {
|
186
|
}
|
187
|
|
188
|
}
|