Revision 6b8fbb9a
Added by Patrick Plitzner over 6 years ago
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CategoricalDataCellEditor.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.editor.workingSet.matrix; |
|
10 |
|
|
11 |
import java.util.List; |
|
12 |
|
|
13 |
import org.eclipse.nebula.widgets.nattable.edit.editor.IComboBoxDataProvider; |
|
14 |
import org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboBoxCellEditor; |
|
15 |
|
|
16 |
import eu.etaxonomy.cdm.model.description.CategoricalData; |
|
17 |
import eu.etaxonomy.cdm.model.description.State; |
|
18 |
|
|
19 |
/** |
|
20 |
* @author pplitzner |
|
21 |
* @since Dec 7, 2017 |
|
22 |
* |
|
23 |
*/ |
|
24 |
public class CategoricalDataCellEditor extends FilterRowComboBoxCellEditor{ |
|
25 |
|
|
26 |
public CategoricalDataCellEditor(IComboBoxDataProvider dataProvider, int maxVisibleItems) { |
|
27 |
super(dataProvider, maxVisibleItems); |
|
28 |
} |
|
29 |
|
|
30 |
@Override |
|
31 |
public void setCanonicalValue(Object canonicalValue) { |
|
32 |
if (canonicalValue instanceof CategoricalData) { |
|
33 |
CategoricalData data = (CategoricalData)canonicalValue; |
|
34 |
List<State> states = data.getStatesOnly(); |
|
35 |
String[] result = new String[states.size()]; |
|
36 |
for (int i = 0; i < states.size(); i++) { |
|
37 |
result[i] = (String) this.displayConverter.canonicalToDisplayValue( |
|
38 |
this.layerCell, this.configRegistry, states.get(i)); |
|
39 |
} |
|
40 |
setEditorValue(result); |
|
41 |
} |
|
42 |
} |
|
43 |
|
|
44 |
} |
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CategoricalDataDisplayConverter.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.editor.workingSet.matrix; |
|
10 |
|
|
11 |
import org.eclipse.nebula.widgets.nattable.data.convert.DisplayConverter; |
|
12 |
|
|
13 |
import eu.etaxonomy.cdm.model.description.CategoricalData; |
|
14 |
import eu.etaxonomy.cdm.model.description.State; |
|
15 |
import eu.etaxonomy.taxeditor.model.DescriptionHelper; |
|
16 |
|
|
17 |
/** |
|
18 |
* @author pplitzner |
|
19 |
* @since Dec 1, 2017 |
|
20 |
* |
|
21 |
*/ |
|
22 |
public class CategoricalDataDisplayConverter extends DisplayConverter { |
|
23 |
|
|
24 |
/** |
|
25 |
* {@inheritDoc} |
|
26 |
*/ |
|
27 |
@Override |
|
28 |
public Object canonicalToDisplayValue(Object canonicalValue) { |
|
29 |
if(canonicalValue instanceof CategoricalData){ |
|
30 |
return DescriptionHelper.getLabel(canonicalValue); |
|
31 |
} |
|
32 |
else if(canonicalValue instanceof State){ |
|
33 |
return ((State) canonicalValue).getLabel(); |
|
34 |
} |
|
35 |
return canonicalValue.toString(); |
|
36 |
} |
|
37 |
|
|
38 |
/** |
|
39 |
* {@inheritDoc} |
|
40 |
*/ |
|
41 |
@Override |
|
42 |
public Object displayToCanonicalValue(Object displayValue) { |
|
43 |
return null; |
|
44 |
} |
|
45 |
|
|
46 |
} |
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java | ||
---|---|---|
10 | 10 |
|
11 | 11 |
import java.util.ArrayList; |
12 | 12 |
import java.util.Collection; |
13 |
import java.util.Collections; |
|
13 | 14 |
import java.util.List; |
14 | 15 |
import java.util.Set; |
15 | 16 |
|
... | ... | |
30 | 31 |
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry; |
31 | 32 |
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration; |
32 | 33 |
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; |
34 |
import org.eclipse.nebula.widgets.nattable.config.IEditableRule; |
|
33 | 35 |
import org.eclipse.nebula.widgets.nattable.data.IDataProvider; |
34 | 36 |
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider; |
37 |
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; |
|
38 |
import org.eclipse.nebula.widgets.nattable.edit.editor.IComboBoxDataProvider; |
|
35 | 39 |
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommand; |
36 | 40 |
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommandHandler; |
37 | 41 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer; |
38 | 42 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel; |
39 |
import org.eclipse.nebula.widgets.nattable.grid.GridRegion; |
|
40 | 43 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; |
41 | 44 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; |
42 | 45 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; |
... | ... | |
47 | 50 |
import org.eclipse.nebula.widgets.nattable.layer.DataLayer; |
48 | 51 |
import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
49 | 52 |
import org.eclipse.nebula.widgets.nattable.layer.ILayerListener; |
53 |
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator; |
|
50 | 54 |
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
51 | 55 |
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent; |
52 | 56 |
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer; |
... | ... | |
70 | 74 |
import eu.etaxonomy.cdm.api.conversation.ConversationHolder; |
71 | 75 |
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled; |
72 | 76 |
import eu.etaxonomy.cdm.api.service.IWorkingSetService; |
77 |
import eu.etaxonomy.cdm.model.common.TermVocabulary; |
|
73 | 78 |
import eu.etaxonomy.cdm.model.description.DescriptionBase; |
79 |
import eu.etaxonomy.cdm.model.description.Feature; |
|
80 |
import eu.etaxonomy.cdm.model.description.FeatureTree; |
|
74 | 81 |
import eu.etaxonomy.cdm.model.description.SpecimenDescription; |
82 |
import eu.etaxonomy.cdm.model.description.State; |
|
75 | 83 |
import eu.etaxonomy.cdm.model.description.WorkingSet; |
76 | 84 |
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap; |
77 | 85 |
import eu.etaxonomy.taxeditor.model.IDirtyMarkable; |
... | ... | |
103 | 111 |
|
104 | 112 |
private NatTable natTable; |
105 | 113 |
|
114 |
private List<Feature> features; |
|
115 |
|
|
106 | 116 |
@PostConstruct |
107 | 117 |
public void create(Composite parent) { |
108 | 118 |
if(CdmStore.isActive() && conversation==null){ |
... | ... | |
120 | 130 |
this.workingSet = workingSet; |
121 | 131 |
thisPart.setLabel(workingSet.getLabel()); |
122 | 132 |
|
133 |
//get features/columns stored in working set |
|
134 |
FeatureTree tree = workingSet.getDescriptiveSystem(); |
|
135 |
features = new ArrayList<>(tree.getDistinctFeatures()); |
|
136 |
Collections.sort(features); |
|
137 |
|
|
138 |
|
|
123 | 139 |
EventList<SpecimenDescription> descriptions = GlazedLists.eventList(getDescriptions(workingSet)); |
124 | 140 |
SortedList<SpecimenDescription> sortedList = new SortedList<>(descriptions, null); |
125 | 141 |
|
126 |
// create the data provider |
|
127 |
SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(workingSet); |
|
142 |
/** |
|
143 |
* data provider |
|
144 |
*/ |
|
145 |
SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(features); |
|
128 | 146 |
IDataProvider bodyDataProvider = new ListDataProvider<SpecimenDescription>(sortedList, columnPropertyAccessor); |
129 | 147 |
|
148 |
/** |
|
149 |
* BODY layer |
|
150 |
*/ |
|
130 | 151 |
DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); |
152 |
final ColumnOverrideLabelAccumulator columnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer); |
|
153 |
bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator); |
|
154 |
registerColumnLabels(columnLabelAccumulator); |
|
131 | 155 |
GlazedListsEventLayer<SpecimenDescription> eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, sortedList); |
132 | 156 |
|
133 | 157 |
RowReorderLayer rowReorderLayer = new RowReorderLayer(eventLayer); |
... | ... | |
135 | 159 |
SelectionLayer selectionLayer = new SelectionLayer(columnReorderLayer); |
136 | 160 |
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer); |
137 | 161 |
|
138 |
// build the column header layer stack |
|
162 |
/** |
|
163 |
* column header layer |
|
164 |
*/ |
|
139 | 165 |
IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider( |
140 | 166 |
columnPropertyAccessor.getPropertyToLabelMap().values().toArray(new String[] {}), columnPropertyAccessor.getPropertyToLabelMap()); |
141 | 167 |
DataLayer columnHeaderDataLayer = new DataLayer(columnHeaderDataProvider); |
... | ... | |
146 | 172 |
// add the SortHeaderLayer to the column header layer stack |
147 | 173 |
// as we use GlazedLists, we use the GlazedListsSortModel which |
148 | 174 |
// delegates the sorting to the SortedList |
149 |
final SortHeaderLayer sortHeaderLayer = |
|
150 |
new SortHeaderLayer<>( |
|
175 |
final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>( |
|
151 | 176 |
columnHeaderLayer, |
152 | 177 |
new GlazedListsSortModel<>( |
153 | 178 |
sortedList, |
... | ... | |
155 | 180 |
configRegistry, |
156 | 181 |
columnHeaderDataLayer)); |
157 | 182 |
|
158 |
// build the row header layer stack |
|
183 |
|
|
184 |
/** |
|
185 |
* row header layer |
|
186 |
*/ |
|
159 | 187 |
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider); |
160 | 188 |
DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider, 40, 20); |
161 | 189 |
ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer); |
162 | 190 |
|
163 |
// build the corner layer stack |
|
191 |
|
|
192 |
/** |
|
193 |
* corner layer |
|
194 |
*/ |
|
164 | 195 |
ILayer cornerLayer = new CornerLayer( |
165 | 196 |
new DataLayer(new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)), |
166 | 197 |
rowHeaderLayer, sortHeaderLayer); |
167 | 198 |
|
168 |
// create the grid layer composed with the prior created layer stacks |
|
199 |
|
|
200 |
/** |
|
201 |
* GRID layer (composition of all other layers) |
|
202 |
*/ |
|
169 | 203 |
GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer); |
170 | 204 |
|
171 | 205 |
|
... | ... | |
181 | 215 |
// to sort on a single click |
182 | 216 |
natTable.addConfiguration(new SingleClickSortConfiguration()); |
183 | 217 |
|
218 |
|
|
184 | 219 |
// add custom configuration for data conversion |
185 | 220 |
viewportLayer.addConfiguration(new AbstractRegistryConfiguration() { |
186 |
|
|
187 | 221 |
@Override |
188 | 222 |
public void configureRegistry(IConfigRegistry configRegistry) { |
189 |
|
|
190 |
// apply for all columns of the data body region |
|
191 |
configRegistry.registerConfigAttribute( |
|
192 |
// attribute to apply |
|
193 |
CellConfigAttributes.DISPLAY_CONVERTER, |
|
194 |
// value of the attribute |
|
195 |
new DescriptionDisplayConverter(), |
|
196 |
// apply during normal rendering i.e not |
|
197 |
// during selection or edit |
|
198 |
DisplayMode.NORMAL, |
|
199 |
// apply the above for all cells with this label |
|
200 |
GridRegion.BODY); |
|
201 |
|
|
223 |
features.forEach(feature -> registerColumnConfiguration(feature, configRegistry)); |
|
224 |
} |
|
202 | 225 |
} |
203 |
});
|
|
226 |
); |
|
204 | 227 |
|
205 | 228 |
// add the ExportCommandHandler to the ViewportLayer in order to make |
206 | 229 |
// exporting work |
... | ... | |
208 | 231 |
|
209 | 232 |
//propagate single cell selection |
210 | 233 |
natTable.addLayerListener(new ILayerListener() { |
211 |
|
|
212 | 234 |
@Override |
213 | 235 |
public void handleLayerEvent(ILayerEvent event) { |
214 | 236 |
if(event instanceof CellSelectionEvent){ |
... | ... | |
242 | 264 |
parent.layout(); |
243 | 265 |
} |
244 | 266 |
|
267 |
private void registerColumnLabels(ColumnOverrideLabelAccumulator columnLabelAccumulator) { |
|
268 |
for(int i=0;i<features.size();i++){ |
|
269 |
columnLabelAccumulator.registerColumnOverrides(i, getProperty(features.get(i))); |
|
270 |
} |
|
271 |
} |
|
272 |
|
|
273 |
private void registerColumnConfiguration(Feature feature, IConfigRegistry configRegistry) { |
|
274 |
//make cell editable |
|
275 |
configRegistry.registerConfigAttribute( |
|
276 |
EditConfigAttributes.CELL_EDITABLE_RULE, |
|
277 |
IEditableRule.ALWAYS_EDITABLE, |
|
278 |
DisplayMode.EDIT, |
|
279 |
getProperty(feature) |
|
280 |
); |
|
281 |
if(feature.isSupportsQuantitativeData()){ |
|
282 |
//add display converter for string representation |
|
283 |
configRegistry.registerConfigAttribute( |
|
284 |
CellConfigAttributes.DISPLAY_CONVERTER, |
|
285 |
new QuantitativeDataDisplayConverter(), |
|
286 |
DisplayMode.NORMAL, |
|
287 |
getProperty(feature)); |
|
288 |
} |
|
289 |
else if(feature.isSupportsCategoricalData()){ |
|
290 |
//add display converter for string representation |
|
291 |
configRegistry.registerConfigAttribute( |
|
292 |
CellConfigAttributes.DISPLAY_CONVERTER, |
|
293 |
new CategoricalDataDisplayConverter(), |
|
294 |
DisplayMode.NORMAL, |
|
295 |
getProperty(feature)); |
|
296 |
|
|
297 |
//add combo box cell editor |
|
298 |
CategoricalDataCellEditor comboBoxCellEditor = new CategoricalDataCellEditor(new IComboBoxDataProvider() { |
|
299 |
|
|
300 |
@Override |
|
301 |
public List<?> getValues(int columnIndex, int rowIndex) { |
|
302 |
List<State> states = new ArrayList<>(); |
|
303 |
Feature feature = features.get(columnIndex); |
|
304 |
if(feature.isSupportsCategoricalData()){ |
|
305 |
Set<TermVocabulary<State>> stateVocs = feature.getSupportedCategoricalEnumerations(); |
|
306 |
for (TermVocabulary<State> voc : stateVocs) { |
|
307 |
states.addAll(voc.getTerms()); |
|
308 |
} |
|
309 |
} |
|
310 |
return states; |
|
311 |
} |
|
312 |
}, 5); |
|
313 |
//register editor |
|
314 |
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, |
|
315 |
comboBoxCellEditor, |
|
316 |
DisplayMode.EDIT, |
|
317 |
getProperty(feature)); |
|
318 |
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, |
|
319 |
comboBoxCellEditor, |
|
320 |
DisplayMode.NORMAL, |
|
321 |
getProperty(feature)); |
|
322 |
|
|
323 |
} |
|
324 |
|
|
325 |
} |
|
326 |
|
|
245 | 327 |
private List<SpecimenDescription> getDescriptions(WorkingSet workingSet) { |
246 | 328 |
List<SpecimenDescription> descriptions = new ArrayList<>(); |
247 | 329 |
Set<DescriptionBase> wsDescriptions = workingSet.getDescriptions(); |
... | ... | |
253 | 335 |
return descriptions; |
254 | 336 |
} |
255 | 337 |
|
338 |
public List<Feature> getFeatures() { |
|
339 |
return features; |
|
340 |
} |
|
341 |
|
|
342 |
private String getProperty(Feature feature){ |
|
343 |
return feature.getLabel(); |
|
344 |
} |
|
345 |
|
|
256 | 346 |
@Persist |
257 | 347 |
@Override |
258 | 348 |
public void save(IProgressMonitor monitor) { |
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/DescriptionDisplayConverter.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 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.editor.workingSet.matrix; |
|
10 |
|
|
11 |
import org.eclipse.nebula.widgets.nattable.data.convert.DisplayConverter; |
|
12 |
|
|
13 |
import eu.etaxonomy.cdm.model.description.DescriptionElementBase; |
|
14 |
import eu.etaxonomy.taxeditor.model.DescriptionHelper; |
|
15 |
|
|
16 |
/** |
|
17 |
* @author pplitzner |
|
18 |
* @since Dec 1, 2017 |
|
19 |
* |
|
20 |
*/ |
|
21 |
public class DescriptionDisplayConverter extends DisplayConverter { |
|
22 |
|
|
23 |
/** |
|
24 |
* {@inheritDoc} |
|
25 |
*/ |
|
26 |
@Override |
|
27 |
public Object canonicalToDisplayValue(Object canonicalValue) { |
|
28 |
if(canonicalValue instanceof DescriptionElementBase){ |
|
29 |
return DescriptionHelper.getLabel(canonicalValue); |
|
30 |
} |
|
31 |
return null; |
|
32 |
} |
|
33 |
|
|
34 |
/** |
|
35 |
* {@inheritDoc} |
|
36 |
*/ |
|
37 |
@Override |
|
38 |
public Object displayToCanonicalValue(Object displayValue) { |
|
39 |
return null; |
|
40 |
} |
|
41 |
|
|
42 |
|
|
43 |
} |
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenColumnPropertyAccessor.java | ||
---|---|---|
9 | 9 |
package eu.etaxonomy.taxeditor.editor.workingSet.matrix; |
10 | 10 |
|
11 | 11 |
import java.util.ArrayList; |
12 |
import java.util.Collection; |
|
12 | 13 |
import java.util.List; |
13 | 14 |
import java.util.Map; |
14 | 15 |
import java.util.Set; |
... | ... | |
16 | 17 |
import org.apache.commons.collections4.map.LinkedMap; |
17 | 18 |
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor; |
18 | 19 |
|
20 |
import eu.etaxonomy.cdm.model.description.CategoricalData; |
|
19 | 21 |
import eu.etaxonomy.cdm.model.description.DescriptionElementBase; |
20 | 22 |
import eu.etaxonomy.cdm.model.description.Feature; |
21 |
import eu.etaxonomy.cdm.model.description.FeatureTree; |
|
22 | 23 |
import eu.etaxonomy.cdm.model.description.SpecimenDescription; |
23 |
import eu.etaxonomy.cdm.model.description.WorkingSet; |
|
24 |
import eu.etaxonomy.cdm.model.description.State; |
|
25 |
import eu.etaxonomy.cdm.model.description.StateData; |
|
24 | 26 |
|
25 | 27 |
/** |
26 | 28 |
* @author pplitzner |
... | ... | |
29 | 31 |
*/ |
30 | 32 |
public class SpecimenColumnPropertyAccessor implements IColumnPropertyAccessor<SpecimenDescription>{ |
31 | 33 |
|
32 |
private List<Feature> features = new ArrayList<>();
|
|
34 |
private final List<Feature> features;
|
|
33 | 35 |
private LinkedMap<String, String> propertyToLabelMap = new LinkedMap<>(); |
34 | 36 |
|
35 | 37 |
|
36 |
public SpecimenColumnPropertyAccessor(WorkingSet workingSet) { |
|
37 |
FeatureTree tree = workingSet.getDescriptiveSystem(); |
|
38 |
Set<Feature> distinctFeatures = tree.getDistinctFeatures(); |
|
39 |
for (Feature feature : distinctFeatures) { |
|
40 |
if(feature!=null){ |
|
41 |
features.add(feature); |
|
42 |
propertyToLabelMap.put(feature.getLabel(), feature.getLabel()); |
|
43 |
} |
|
38 |
public SpecimenColumnPropertyAccessor(final List<Feature> features) { |
|
39 |
this.features = features; |
|
40 |
for (Feature feature : features) { |
|
41 |
propertyToLabelMap.put(feature.getLabel(), feature.getLabel()); |
|
44 | 42 |
} |
45 | 43 |
} |
46 | 44 |
|
... | ... | |
68 | 66 |
*/ |
69 | 67 |
@Override |
70 | 68 |
public void setDataValue(SpecimenDescription rowObject, int columnIndex, Object newValue) { |
71 |
features.remove(columnIndex); |
|
72 |
features.add(columnIndex, (Feature) newValue); |
|
69 |
Feature feature = features.get(columnIndex); |
|
70 |
Set<DescriptionElementBase> elements = rowObject.getElements(); |
|
71 |
for (DescriptionElementBase descriptionElementBase : elements) { |
|
72 |
if(descriptionElementBase.getFeature().equals(feature)){ |
|
73 |
setDescriptionElement(rowObject, descriptionElementBase, feature, newValue); |
|
74 |
} |
|
75 |
} |
|
76 |
} |
|
77 |
|
|
78 |
|
|
79 |
private void setDescriptionElement(SpecimenDescription description, DescriptionElementBase descriptionElementBase, Feature feature, Object newValue) { |
|
80 |
//FIXME move this to cdmlib service layer |
|
81 |
if(feature.isSupportsCategoricalData() && descriptionElementBase instanceof CategoricalData && newValue instanceof Collection){ |
|
82 |
CategoricalData categoricalData = (CategoricalData)descriptionElementBase; |
|
83 |
List<StateData> stateData = new ArrayList<>(categoricalData.getStateData()); |
|
84 |
for (StateData stateData2 : stateData) { |
|
85 |
categoricalData.removeStateData(stateData2); |
|
86 |
} |
|
87 |
Collection<State> states = (Collection<State>) newValue; |
|
88 |
for (State state : states) { |
|
89 |
categoricalData.addStateData(state); |
|
90 |
} |
|
91 |
} |
|
73 | 92 |
} |
74 | 93 |
|
75 | 94 |
/** |
Also available in: Unified diff
ref #7095 Implement combo box editor for categorical data