Revision 85326264
Added by Katja Luther almost 3 years ago
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditor.java | ||
---|---|---|
94 | 94 |
|
95 | 95 |
private BulkEditorQuery lastQuery = null; |
96 | 96 |
|
97 |
private BulkEditorE4Composite bulkEditorComposite;
|
|
97 |
private BulkEditorComposite bulkEditorComposite; |
|
98 | 98 |
|
99 | 99 |
@Inject |
100 | 100 |
public BulkEditor() { |
... | ... | |
110 | 110 |
|
111 | 111 |
@PostConstruct |
112 | 112 |
public void createPartControl(Composite parent, IEclipseContext context) { |
113 |
bulkEditorComposite = new BulkEditorE4Composite(this, parent, SWT.NONE);
|
|
113 |
bulkEditorComposite = new BulkEditorComposite(this, parent, SWT.NONE); |
|
114 | 114 |
ContextInjectionFactory.inject(bulkEditorComposite, context); |
115 | 115 |
} |
116 | 116 |
|
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorComposite.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2007 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.bulkeditor.e4; |
|
10 |
|
|
11 |
import java.io.File; |
|
12 |
import java.util.ArrayList; |
|
13 |
import java.util.Collection; |
|
14 |
import java.util.HashMap; |
|
15 |
import java.util.List; |
|
16 |
import java.util.Map; |
|
17 |
import java.util.Properties; |
|
18 |
import java.util.Set; |
|
19 |
|
|
20 |
import javax.inject.Inject; |
|
21 |
|
|
22 |
import org.eclipse.e4.core.services.events.IEventBroker; |
|
23 |
import org.eclipse.e4.ui.services.EMenuService; |
|
24 |
import org.eclipse.e4.ui.workbench.modeling.ESelectionService; |
|
25 |
import org.eclipse.jface.layout.GridDataFactory; |
|
26 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
27 |
import org.eclipse.jface.viewers.IStructuredSelection; |
|
28 |
import org.eclipse.jface.viewers.StructuredSelection; |
|
29 |
import org.eclipse.nebula.widgets.nattable.NatTable; |
|
30 |
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand; |
|
31 |
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler; |
|
32 |
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration; |
|
33 |
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration; |
|
34 |
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes; |
|
35 |
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry; |
|
36 |
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration; |
|
37 |
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; |
|
38 |
import org.eclipse.nebula.widgets.nattable.config.IEditableRule; |
|
39 |
import org.eclipse.nebula.widgets.nattable.coordinate.Range; |
|
40 |
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider; |
|
41 |
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter; |
|
42 |
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; |
|
43 |
import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction; |
|
44 |
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration; |
|
45 |
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor; |
|
46 |
import org.eclipse.nebula.widgets.nattable.extension.e4.selection.E4SelectionListener; |
|
47 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer; |
|
48 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel; |
|
49 |
import org.eclipse.nebula.widgets.nattable.grid.GridRegion; |
|
50 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; |
|
51 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; |
|
52 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; |
|
53 |
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; |
|
54 |
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; |
|
55 |
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; |
|
56 |
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; |
|
57 |
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer; |
|
58 |
import org.eclipse.nebula.widgets.nattable.layer.DataLayer; |
|
59 |
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
|
60 |
import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack; |
|
61 |
import org.eclipse.nebula.widgets.nattable.painter.cell.CheckBoxPainter; |
|
62 |
import org.eclipse.nebula.widgets.nattable.painter.cell.ImagePainter; |
|
63 |
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer; |
|
64 |
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration; |
|
65 |
import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
|
66 |
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration; |
|
67 |
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; |
|
68 |
import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher; |
|
69 |
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher; |
|
70 |
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction; |
|
71 |
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder; |
|
72 |
import org.eclipse.swt.SWT; |
|
73 |
import org.eclipse.swt.dnd.Clipboard; |
|
74 |
import org.eclipse.swt.dnd.TextTransfer; |
|
75 |
import org.eclipse.swt.dnd.Transfer; |
|
76 |
import org.eclipse.swt.layout.GridData; |
|
77 |
import org.eclipse.swt.layout.GridLayout; |
|
78 |
import org.eclipse.swt.widgets.Composite; |
|
79 |
import org.eclipse.swt.widgets.Display; |
|
80 |
import org.eclipse.swt.widgets.Menu; |
|
81 |
|
|
82 |
import ca.odell.glazedlists.SortedList; |
|
83 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
84 |
import eu.etaxonomy.cdm.model.description.SpecimenDescription; |
|
85 |
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery; |
|
86 |
import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput; |
|
87 |
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants; |
|
88 |
import eu.etaxonomy.taxeditor.model.ImageResources; |
|
89 |
import eu.etaxonomy.taxeditor.store.StoreUtil; |
|
90 |
|
|
91 |
/** |
|
92 |
* @author pplitzner |
|
93 |
* @since Sep 8, 2017 |
|
94 |
*/ |
|
95 |
public class BulkEditorComposite extends Composite { |
|
96 |
|
|
97 |
public static final String LABEL_CANDIDATE = "LABEL_CANDIDATE"; //$NON-NLS-1$ |
|
98 |
public static final String LABEL_CANDIDATE_ICON = "LABEL_CANDIDATE_ICON"; //$NON-NLS-1$ |
|
99 |
|
|
100 |
public static final String LABEL_TARGET = "LABEL_TARGET"; //$NON-NLS-1$ |
|
101 |
public static final String LABEL_TARGET_ICON = "LABEL_TARGET_ICON"; //$NON-NLS-1$ |
|
102 |
|
|
103 |
private final List<String> columnList = new ArrayList<>(); |
|
104 |
|
|
105 |
private Composite topComposite; |
|
106 |
|
|
107 |
@Inject |
|
108 |
private ESelectionService selService; |
|
109 |
|
|
110 |
private ISelectionChangedListener selectionChangedListener; |
|
111 |
|
|
112 |
private Composite bottomComposite; |
|
113 |
|
|
114 |
@Inject |
|
115 |
private EMenuService menuService; |
|
116 |
|
|
117 |
private NatTable natTable; |
|
118 |
|
|
119 |
private DefaultBodyLayerStack bodyLayer; |
|
120 |
|
|
121 |
private ListDataProvider<CdmBase> bodyDataProvider; |
|
122 |
|
|
123 |
private BulkEditor bulkEditor; |
|
124 |
private BulkEditorSearch bulkEditorSearch; |
|
125 |
|
|
126 |
@Inject |
|
127 |
private IEventBroker eventBroker; |
|
128 |
|
|
129 |
|
|
130 |
public BulkEditorComposite(BulkEditor bulkEditor, Composite parent, int style) { |
|
131 |
super(parent, style); |
|
132 |
parent.setLayout(new GridLayout()); |
|
133 |
this.bulkEditor = bulkEditor; |
|
134 |
|
|
135 |
this.setLayout(new GridLayout()); |
|
136 |
|
|
137 |
topComposite = new Composite(parent, SWT.NONE); |
|
138 |
topComposite.setLayout(new GridLayout()); |
|
139 |
|
|
140 |
GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); |
|
141 |
topComposite.setLayoutData(gridData); |
|
142 |
|
|
143 |
bottomComposite = new Composite(parent, SWT.NONE); |
|
144 |
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
|
145 |
bottomComposite.setLayout(new GridLayout()); |
|
146 |
} |
|
147 |
|
|
148 |
public void init(AbstractBulkEditorInput<?> input){ |
|
149 |
|
|
150 |
input.getPropertyKeys().forEach(key->columnList.add(key)); |
|
151 |
|
|
152 |
bulkEditorSearch = new BulkEditorSearch(this, topComposite, SWT.NONE); |
|
153 |
//layout needed because the search bar is added after @PostConstuct method |
|
154 |
topComposite.getParent().layout(); |
|
155 |
|
|
156 |
if(input.getEntityUuid()!=null){ |
|
157 |
performSearch(new BulkEditorQuery(input.getEntityUuid().toString())); |
|
158 |
} |
|
159 |
|
|
160 |
createTable(); |
|
161 |
|
|
162 |
configureTable(); |
|
163 |
|
|
164 |
styleTable(); |
|
165 |
|
|
166 |
GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable); |
|
167 |
|
|
168 |
//propagate selection |
|
169 |
// selection listener |
|
170 |
E4SelectionListener<CdmBase> selectionListener = new CellSelectionListener(selService, bodyLayer.getSelectionLayer(), bodyDataProvider, this); |
|
171 |
bodyLayer.getSelectionLayer().addLayerListener(selectionListener); |
|
172 |
selectionListener.setFullySelectedRowsOnly(false); |
|
173 |
|
|
174 |
bottomComposite.layout(); |
|
175 |
} |
|
176 |
|
|
177 |
private void createTable(){ |
|
178 |
ConfigRegistry configRegistry = new ConfigRegistry(); |
|
179 |
//property map |
|
180 |
Map<String, String> propertyToLabels = new HashMap<>(); |
|
181 |
columnList.forEach(columnLabel->propertyToLabels.put(columnLabel, columnLabel)); |
|
182 |
|
|
183 |
String[] propertyNames = columnList.toArray(columnList.toArray(new String[columnList.size()])); |
|
184 |
//sorted list |
|
185 |
SortedList<CdmBase> sortedList = new SortedList<>(bulkEditor.getEditorInput().getModel(), bulkEditor.getEditorInput().getTitleComparator()); |
|
186 |
//data provider |
|
187 |
BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(this, bulkEditor.getEditorInput()); |
|
188 |
bodyDataProvider = new ListDataProvider<CdmBase>(sortedList, |
|
189 |
columnPropertyAccessor); |
|
190 |
DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider( |
|
191 |
propertyNames, propertyToLabels); |
|
192 |
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider( |
|
193 |
bodyDataProvider); |
|
194 |
//body |
|
195 |
DataLayer dataLayer = new DataLayer(bodyDataProvider); |
|
196 |
dataLayer.registerCommandHandler(new VisualRefreshCommandHandler()); |
|
197 |
GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, bulkEditor.getEditorInput().getModel()); |
|
198 |
bodyLayer = new DefaultBodyLayerStack(eventLayer); |
|
199 |
|
|
200 |
dataLayer.setColumnPercentageSizing(0, true); |
|
201 |
dataLayer.setColumnWidthPercentageByPosition(0, 45); |
|
202 |
for(int i=1;i<columnList.size();i++){ |
|
203 |
if(bulkEditor.getEditorInput().isCacheProperty(columnList.get(i))){ |
|
204 |
dataLayer.setColumnWidthByPosition(i, 16); |
|
205 |
} |
|
206 |
else{ |
|
207 |
dataLayer.setColumnWidthByPosition(i, 100); |
|
208 |
} |
|
209 |
} |
|
210 |
|
|
211 |
//column |
|
212 |
DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider); |
|
213 |
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer( |
|
214 |
columnHeaderDataLayer, |
|
215 |
bodyLayer, bodyLayer.getSelectionLayer()); |
|
216 |
// add the SortHeaderLayer to the column header layer stack |
|
217 |
// as we use GlazedLists, we use the GlazedListsSortModel which |
|
218 |
// delegates the sorting to the SortedList |
|
219 |
final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>( |
|
220 |
columnHeaderLayer, |
|
221 |
new GlazedListsSortModel<>( |
|
222 |
sortedList, |
|
223 |
columnPropertyAccessor, |
|
224 |
configRegistry, |
|
225 |
columnHeaderDataLayer)); |
|
226 |
columnHeaderDataLayer.setConfigLabelAccumulator( |
|
227 |
new BulkEditorConfigLabelAccumulatorHeader(colHeaderDataProvider, bulkEditor.getEditorInput())); |
|
228 |
//row |
|
229 |
DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider); |
|
230 |
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, |
|
231 |
bodyLayer, bodyLayer.getSelectionLayer()); |
|
232 |
rowHeaderDataLayer.setColumnWidthByPosition(0, 50); |
|
233 |
|
|
234 |
//corner |
|
235 |
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider( |
|
236 |
colHeaderDataProvider, rowHeaderDataProvider); |
|
237 |
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider); |
|
238 |
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer); |
|
239 |
//grid |
|
240 |
GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer, |
|
241 |
rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing |
|
242 |
natTable = new NatTable(bottomComposite, gridLayer, false); |
|
243 |
|
|
244 |
dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, colHeaderDataProvider, |
|
245 |
bulkEditor.getEditorInput())); |
|
246 |
|
|
247 |
natTable.setConfigRegistry(configRegistry); |
|
248 |
|
|
249 |
//add tooltip to table |
|
250 |
new BulkEditorTooltip(natTable, colHeaderDataProvider); |
|
251 |
} |
|
252 |
|
|
253 |
private void configureTable(){ |
|
254 |
|
|
255 |
//this configuration enables cell to be editable in general |
|
256 |
//necessary because we disabled this beforehand by setting autoconfigure=false |
|
257 |
//in the GridLayer constructor |
|
258 |
((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration()); |
|
259 |
|
|
260 |
natTable.addConfiguration(new AbstractUiBindingConfiguration() { |
|
261 |
@Override |
|
262 |
public void configureUiBindings(UiBindingRegistry uiBindingRegistry) { |
|
263 |
uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY), |
|
264 |
new MouseEditAction()); |
|
265 |
} |
|
266 |
}); |
|
267 |
|
|
268 |
//make cells editable to allow selecting the text |
|
269 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
270 |
@Override |
|
271 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
272 |
//make cell editable |
|
273 |
configRegistry.registerConfigAttribute( |
|
274 |
EditConfigAttributes.CELL_EDITABLE_RULE, |
|
275 |
IEditableRule.ALWAYS_EDITABLE, |
|
276 |
DisplayMode.EDIT); |
|
277 |
//register editor |
|
278 |
TextCellEditor editor = new TextCellEditor(); |
|
279 |
editor.setEditable(false); |
|
280 |
configRegistry.registerConfigAttribute( |
|
281 |
EditConfigAttributes.CELL_EDITOR, |
|
282 |
editor, |
|
283 |
DisplayMode.NORMAL); |
|
284 |
} |
|
285 |
}); |
|
286 |
|
|
287 |
//+++CONTEXT MENU+++ |
|
288 |
menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$ |
|
289 |
// get the menu registered by EMenuService |
|
290 |
final Menu e4Menu = natTable.getMenu(); |
|
291 |
// remove the menu reference from NatTable instance |
|
292 |
natTable.setMenu(null); |
|
293 |
natTable.addConfiguration( |
|
294 |
new AbstractUiBindingConfiguration() { |
|
295 |
@Override |
|
296 |
public void configureUiBindings( |
|
297 |
UiBindingRegistry uiBindingRegistry) { |
|
298 |
// add e4 menu to NatTable |
|
299 |
new PopupMenuBuilder(natTable, e4Menu) |
|
300 |
.withHideColumnMenuItem() |
|
301 |
.withShowAllColumnsMenuItem() |
|
302 |
.build(); |
|
303 |
|
|
304 |
// register the UI binding for header, corner and body region |
|
305 |
uiBindingRegistry.registerMouseDownBinding( |
|
306 |
new MouseEventMatcher( |
|
307 |
SWT.NONE, |
|
308 |
null, |
|
309 |
MouseEventMatcher.RIGHT_BUTTON), |
|
310 |
new PopupMenuAction(e4Menu)); |
|
311 |
} |
|
312 |
}); |
|
313 |
|
|
314 |
//enable sorting |
|
315 |
natTable.addConfiguration(new SingleClickSortConfiguration()); |
|
316 |
|
|
317 |
// Custom style for deduplication labels |
|
318 |
natTable.addConfiguration(new BulkEditorLabelStyleConfiguration()); |
|
319 |
|
|
320 |
//add default configuration because autoconfigure is set to false in constructor |
|
321 |
natTable.addConfiguration(new DefaultNatTableStyleConfiguration()); |
|
322 |
|
|
323 |
//show boolean values as check boxes |
|
324 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
325 |
@Override |
|
326 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
327 |
configRegistry.registerConfigAttribute( |
|
328 |
CellConfigAttributes.CELL_PAINTER, |
|
329 |
new CheckBoxPainter(), |
|
330 |
DisplayMode.NORMAL, |
|
331 |
BulkEditorConfigLabelAccumulatorHeader.BOOLEAN_COLUMN); |
|
332 |
|
|
333 |
configRegistry.registerConfigAttribute( |
|
334 |
CellConfigAttributes.DISPLAY_CONVERTER, |
|
335 |
new DefaultBooleanDisplayConverter(), |
|
336 |
DisplayMode.NORMAL, |
|
337 |
BulkEditorConfigLabelAccumulatorHeader.BOOLEAN_COLUMN); |
|
338 |
} |
|
339 |
}); |
|
340 |
|
|
341 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
342 |
@Override |
|
343 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
344 |
configRegistry.registerConfigAttribute( |
|
345 |
CellConfigAttributes.CELL_PAINTER, |
|
346 |
new ImagePainter(ImageResources.getImage(ImageResources.LOCK_ICON)), |
|
347 |
DisplayMode.NORMAL, |
|
348 |
BulkEditorConfigLabelAccumulatorHeader.CACHE_COLUMN); |
|
349 |
} |
|
350 |
}); |
|
351 |
|
|
352 |
//register handler for view configuration menu |
|
353 |
natTable.registerCommandHandler(bulkEditorSearch.getDisplayPersistenceDialogCommandHandler()); |
|
354 |
|
|
355 |
natTable.configure(); |
|
356 |
} |
|
357 |
|
|
358 |
private void styleTable(){ |
|
359 |
natTable.setTheme(new ModernNatTableThemeConfiguration()); |
|
360 |
} |
|
361 |
|
|
362 |
public void performSearch(BulkEditorQuery query) { |
|
363 |
eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null); |
|
364 |
performSearch(query, null); |
|
365 |
|
|
366 |
} |
|
367 |
|
|
368 |
public void performSearch(BulkEditorQuery query, IStructuredSelection selection) { |
|
369 |
if (query != null) { |
|
370 |
if(StoreUtil.promptCheckIsDirty(bulkEditor)){ |
|
371 |
return; |
|
372 |
} |
|
373 |
bulkEditor.getEditorInput().performSearch(query, selection); |
|
374 |
bulkEditor.setLastQuery(query); |
|
375 |
} |
|
376 |
} |
|
377 |
|
|
378 |
public void refresh(){ |
|
379 |
natTable.doCommand(new VisualRefreshCommand()); |
|
380 |
} |
|
381 |
|
|
382 |
public List<String> getColumnList() { |
|
383 |
return columnList; |
|
384 |
} |
|
385 |
|
|
386 |
public IStructuredSelection getCellSelection(){ |
|
387 |
|
|
388 |
Set<Range> selectedRowPositions = bodyLayer.getSelectionLayer().getSelectedRowPositions(); |
|
389 |
Collection<ILayerCell> cells = bodyLayer.getSelectionLayer().getSelectedCells(); |
|
390 |
if (cells.size() == 1){ |
|
391 |
return new StructuredSelection(cells.iterator().next().getDataValue()); |
|
392 |
} |
|
393 |
List<Object> selectedObjects = new ArrayList<>(); |
|
394 |
for (Range range : selectedRowPositions) { |
|
395 |
for(int i=range.start;i<range.end;i++){ |
|
396 |
if (i>=0){ |
|
397 |
selectedObjects.add(bodyDataProvider.getRowObject(i)); |
|
398 |
} |
|
399 |
} |
|
400 |
} |
|
401 |
return new StructuredSelection(selectedObjects); |
|
402 |
} |
|
403 |
|
|
404 |
public IStructuredSelection getSelection(){ |
|
405 |
|
|
406 |
Set<Range> selectedRowPositions = bodyLayer.getSelectionLayer().getSelectedRowPositions(); |
|
407 |
List<Object> selectedObjects = new ArrayList<>(); |
|
408 |
for (Range range : selectedRowPositions) { |
|
409 |
for(int i=range.start;i<range.end;i++){ |
|
410 |
if (i>=0){ |
|
411 |
selectedObjects.add(bodyDataProvider.getRowObject(i)); |
|
412 |
} |
|
413 |
} |
|
414 |
} |
|
415 |
return new StructuredSelection(selectedObjects); |
|
416 |
} |
|
417 |
|
|
418 |
public void setSelection(IStructuredSelection selection){ |
|
419 |
Object[] objects = selection.toArray(); |
|
420 |
for (Object object : objects) { |
|
421 |
|
|
422 |
if(object instanceof CdmBase && bulkEditor.getEditorInput().getModel().contains(object)){ |
|
423 |
object = bulkEditor.getEditorInput().getModel().get(bulkEditor.getEditorInput().getModel().indexOf(object)); |
|
424 |
bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false); |
|
425 |
} |
|
426 |
} |
|
427 |
} |
|
428 |
|
|
429 |
public void copyDataToClipboard() { |
|
430 |
String textData = ""; //$NON-NLS-1$ |
|
431 |
IStructuredSelection selection = getCellSelection(); |
|
432 |
Object[] objects = selection.toArray(); |
|
433 |
for (Object object : objects) { |
|
434 |
if(object instanceof CdmBase){ |
|
435 |
textData += bulkEditor.getEditorInput().getText((CdmBase)object); |
|
436 |
}else if (object instanceof String){ |
|
437 |
textData += (String)object; |
|
438 |
}else { |
|
439 |
textData += object.toString(); |
|
440 |
} |
|
441 |
} |
|
442 |
final TextTransfer textTransfer = TextTransfer.getInstance(); |
|
443 |
final Clipboard clipboard = new Clipboard(Display.getDefault()); |
|
444 |
try { |
|
445 |
clipboard.setContents(new Object[] { textData.toString() }, |
|
446 |
new Transfer[] { textTransfer }); |
|
447 |
} finally { |
|
448 |
clipboard.dispose(); |
|
449 |
} |
|
450 |
} |
|
451 |
|
|
452 |
protected ListDataProvider<CdmBase> getBodyDataProvider() { |
|
453 |
return bodyDataProvider; |
|
454 |
} |
|
455 |
|
|
456 |
protected ESelectionService getSelService() { |
|
457 |
return selService; |
|
458 |
} |
|
459 |
|
|
460 |
protected NatTable getNatTable() { |
|
461 |
return natTable; |
|
462 |
} |
|
463 |
|
|
464 |
protected Properties getNatTableState() { |
|
465 |
return bulkEditorSearch.getNatTableState(); |
|
466 |
} |
|
467 |
|
|
468 |
protected File getStatePropertiesFile() { |
|
469 |
return bulkEditorSearch.getStatePropertiesFile(); |
|
470 |
} |
|
471 |
} |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java | ||
---|---|---|
45 | 45 |
} |
46 | 46 |
CdmBase rowObject = dataProvider.getRowObject(rowPosition); |
47 | 47 |
if(input.getMergeCandidates().contains(rowObject)){ |
48 |
configLabels.addLabel(BulkEditorE4Composite.LABEL_CANDIDATE);
|
|
48 |
configLabels.addLabel(BulkEditorComposite.LABEL_CANDIDATE); |
|
49 | 49 |
if(columnPosition==0){ |
50 |
configLabels.addLabel(BulkEditorE4Composite.LABEL_CANDIDATE_ICON);
|
|
50 |
configLabels.addLabel(BulkEditorComposite.LABEL_CANDIDATE_ICON); |
|
51 | 51 |
} |
52 | 52 |
} |
53 | 53 |
else if(input.getMergeTarget()==rowObject){ |
54 |
configLabels.addLabel(BulkEditorE4Composite.LABEL_TARGET);
|
|
54 |
configLabels.addLabel(BulkEditorComposite.LABEL_TARGET); |
|
55 | 55 |
if(columnPosition==0){ |
56 |
configLabels.addLabel(BulkEditorE4Composite.LABEL_TARGET_ICON);
|
|
56 |
configLabels.addLabel(BulkEditorComposite.LABEL_TARGET_ICON); |
|
57 | 57 |
} |
58 | 58 |
} |
59 | 59 |
} |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4Composite.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2007 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.bulkeditor.e4; |
|
10 |
|
|
11 |
import java.io.File; |
|
12 |
import java.util.ArrayList; |
|
13 |
import java.util.Collection; |
|
14 |
import java.util.HashMap; |
|
15 |
import java.util.List; |
|
16 |
import java.util.Map; |
|
17 |
import java.util.Properties; |
|
18 |
import java.util.Set; |
|
19 |
|
|
20 |
import javax.inject.Inject; |
|
21 |
|
|
22 |
import org.eclipse.e4.core.services.events.IEventBroker; |
|
23 |
import org.eclipse.e4.ui.services.EMenuService; |
|
24 |
import org.eclipse.e4.ui.workbench.modeling.ESelectionService; |
|
25 |
import org.eclipse.jface.layout.GridDataFactory; |
|
26 |
import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
27 |
import org.eclipse.jface.viewers.IStructuredSelection; |
|
28 |
import org.eclipse.jface.viewers.StructuredSelection; |
|
29 |
import org.eclipse.nebula.widgets.nattable.NatTable; |
|
30 |
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand; |
|
31 |
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler; |
|
32 |
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration; |
|
33 |
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration; |
|
34 |
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes; |
|
35 |
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry; |
|
36 |
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration; |
|
37 |
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; |
|
38 |
import org.eclipse.nebula.widgets.nattable.config.IEditableRule; |
|
39 |
import org.eclipse.nebula.widgets.nattable.coordinate.Range; |
|
40 |
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider; |
|
41 |
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultBooleanDisplayConverter; |
|
42 |
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes; |
|
43 |
import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction; |
|
44 |
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration; |
|
45 |
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor; |
|
46 |
import org.eclipse.nebula.widgets.nattable.extension.e4.selection.E4SelectionListener; |
|
47 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer; |
|
48 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel; |
|
49 |
import org.eclipse.nebula.widgets.nattable.grid.GridRegion; |
|
50 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; |
|
51 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; |
|
52 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; |
|
53 |
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; |
|
54 |
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; |
|
55 |
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; |
|
56 |
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; |
|
57 |
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer; |
|
58 |
import org.eclipse.nebula.widgets.nattable.layer.DataLayer; |
|
59 |
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
|
60 |
import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack; |
|
61 |
import org.eclipse.nebula.widgets.nattable.painter.cell.CheckBoxPainter; |
|
62 |
import org.eclipse.nebula.widgets.nattable.painter.cell.ImagePainter; |
|
63 |
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer; |
|
64 |
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration; |
|
65 |
import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
|
66 |
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration; |
|
67 |
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; |
|
68 |
import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher; |
|
69 |
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher; |
|
70 |
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction; |
|
71 |
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder; |
|
72 |
import org.eclipse.swt.SWT; |
|
73 |
import org.eclipse.swt.dnd.Clipboard; |
|
74 |
import org.eclipse.swt.dnd.TextTransfer; |
|
75 |
import org.eclipse.swt.dnd.Transfer; |
|
76 |
import org.eclipse.swt.layout.GridData; |
|
77 |
import org.eclipse.swt.layout.GridLayout; |
|
78 |
import org.eclipse.swt.widgets.Composite; |
|
79 |
import org.eclipse.swt.widgets.Display; |
|
80 |
import org.eclipse.swt.widgets.Menu; |
|
81 |
|
|
82 |
import ca.odell.glazedlists.SortedList; |
|
83 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
84 |
import eu.etaxonomy.cdm.model.description.SpecimenDescription; |
|
85 |
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery; |
|
86 |
import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput; |
|
87 |
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants; |
|
88 |
import eu.etaxonomy.taxeditor.model.ImageResources; |
|
89 |
import eu.etaxonomy.taxeditor.store.StoreUtil; |
|
90 |
|
|
91 |
/** |
|
92 |
* @author pplitzner |
|
93 |
* @since Sep 8, 2017 |
|
94 |
*/ |
|
95 |
public class BulkEditorE4Composite extends Composite { |
|
96 |
|
|
97 |
public static final String LABEL_CANDIDATE = "LABEL_CANDIDATE"; //$NON-NLS-1$ |
|
98 |
public static final String LABEL_CANDIDATE_ICON = "LABEL_CANDIDATE_ICON"; //$NON-NLS-1$ |
|
99 |
|
|
100 |
public static final String LABEL_TARGET = "LABEL_TARGET"; //$NON-NLS-1$ |
|
101 |
public static final String LABEL_TARGET_ICON = "LABEL_TARGET_ICON"; //$NON-NLS-1$ |
|
102 |
|
|
103 |
private final List<String> columnList = new ArrayList<>(); |
|
104 |
|
|
105 |
private Composite topComposite; |
|
106 |
|
|
107 |
@Inject |
|
108 |
private ESelectionService selService; |
|
109 |
|
|
110 |
private ISelectionChangedListener selectionChangedListener; |
|
111 |
|
|
112 |
private Composite bottomComposite; |
|
113 |
|
|
114 |
@Inject |
|
115 |
private EMenuService menuService; |
|
116 |
|
|
117 |
private NatTable natTable; |
|
118 |
|
|
119 |
private DefaultBodyLayerStack bodyLayer; |
|
120 |
|
|
121 |
private ListDataProvider<CdmBase> bodyDataProvider; |
|
122 |
|
|
123 |
private BulkEditor bulkEditor; |
|
124 |
private BulkEditorSearch bulkEditorSearch; |
|
125 |
|
|
126 |
@Inject |
|
127 |
private IEventBroker eventBroker; |
|
128 |
|
|
129 |
|
|
130 |
public BulkEditorE4Composite(BulkEditor bulkEditor, Composite parent, int style) { |
|
131 |
super(parent, style); |
|
132 |
parent.setLayout(new GridLayout()); |
|
133 |
this.bulkEditor = bulkEditor; |
|
134 |
|
|
135 |
this.setLayout(new GridLayout()); |
|
136 |
|
|
137 |
topComposite = new Composite(parent, SWT.NONE); |
|
138 |
topComposite.setLayout(new GridLayout()); |
|
139 |
|
|
140 |
GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); |
|
141 |
topComposite.setLayoutData(gridData); |
|
142 |
|
|
143 |
bottomComposite = new Composite(parent, SWT.NONE); |
|
144 |
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
|
145 |
bottomComposite.setLayout(new GridLayout()); |
|
146 |
} |
|
147 |
|
|
148 |
public void init(AbstractBulkEditorInput<?> input){ |
|
149 |
|
|
150 |
input.getPropertyKeys().forEach(key->columnList.add(key)); |
|
151 |
|
|
152 |
bulkEditorSearch = new BulkEditorSearch(this, topComposite, SWT.NONE); |
|
153 |
//layout needed because the search bar is added after @PostConstuct method |
|
154 |
topComposite.getParent().layout(); |
|
155 |
|
|
156 |
if(input.getEntityUuid()!=null){ |
|
157 |
performSearch(new BulkEditorQuery(input.getEntityUuid().toString())); |
|
158 |
} |
|
159 |
|
|
160 |
createTable(); |
|
161 |
|
|
162 |
configureTable(); |
|
163 |
|
|
164 |
styleTable(); |
|
165 |
|
|
166 |
GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable); |
|
167 |
|
|
168 |
//propagate selection |
|
169 |
// selection listener |
|
170 |
E4SelectionListener<CdmBase> selectionListener = new CellSelectionListener(selService, bodyLayer.getSelectionLayer(), bodyDataProvider, this); |
|
171 |
bodyLayer.getSelectionLayer().addLayerListener(selectionListener); |
|
172 |
selectionListener.setFullySelectedRowsOnly(false); |
|
173 |
|
|
174 |
bottomComposite.layout(); |
|
175 |
} |
|
176 |
|
|
177 |
private void createTable(){ |
|
178 |
ConfigRegistry configRegistry = new ConfigRegistry(); |
|
179 |
//property map |
|
180 |
Map<String, String> propertyToLabels = new HashMap<>(); |
|
181 |
columnList.forEach(columnLabel->propertyToLabels.put(columnLabel, columnLabel)); |
|
182 |
|
|
183 |
String[] propertyNames = columnList.toArray(columnList.toArray(new String[columnList.size()])); |
|
184 |
//sorted list |
|
185 |
SortedList<CdmBase> sortedList = new SortedList<>(bulkEditor.getEditorInput().getModel(), bulkEditor.getEditorInput().getTitleComparator()); |
|
186 |
//data provider |
|
187 |
BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(this, bulkEditor.getEditorInput()); |
|
188 |
bodyDataProvider = new ListDataProvider<CdmBase>(sortedList, |
|
189 |
columnPropertyAccessor); |
|
190 |
DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider( |
|
191 |
propertyNames, propertyToLabels); |
|
192 |
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider( |
|
193 |
bodyDataProvider); |
|
194 |
//body |
|
195 |
DataLayer dataLayer = new DataLayer(bodyDataProvider); |
|
196 |
dataLayer.registerCommandHandler(new VisualRefreshCommandHandler()); |
|
197 |
GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, bulkEditor.getEditorInput().getModel()); |
|
198 |
bodyLayer = new DefaultBodyLayerStack(eventLayer); |
|
199 |
|
|
200 |
dataLayer.setColumnPercentageSizing(0, true); |
|
201 |
dataLayer.setColumnWidthPercentageByPosition(0, 45); |
|
202 |
for(int i=1;i<columnList.size();i++){ |
|
203 |
if(bulkEditor.getEditorInput().isCacheProperty(columnList.get(i))){ |
|
204 |
dataLayer.setColumnWidthByPosition(i, 16); |
|
205 |
} |
|
206 |
else{ |
|
207 |
dataLayer.setColumnWidthByPosition(i, 100); |
|
208 |
} |
|
209 |
} |
|
210 |
|
|
211 |
//column |
|
212 |
DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider); |
|
213 |
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer( |
|
214 |
columnHeaderDataLayer, |
|
215 |
bodyLayer, bodyLayer.getSelectionLayer()); |
|
216 |
// add the SortHeaderLayer to the column header layer stack |
|
217 |
// as we use GlazedLists, we use the GlazedListsSortModel which |
|
218 |
// delegates the sorting to the SortedList |
|
219 |
final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>( |
|
220 |
columnHeaderLayer, |
|
221 |
new GlazedListsSortModel<>( |
|
222 |
sortedList, |
|
223 |
columnPropertyAccessor, |
|
224 |
configRegistry, |
|
225 |
columnHeaderDataLayer)); |
|
226 |
columnHeaderDataLayer.setConfigLabelAccumulator( |
|
227 |
new BulkEditorConfigLabelAccumulatorHeader(colHeaderDataProvider, bulkEditor.getEditorInput())); |
|
228 |
//row |
|
229 |
DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider); |
|
230 |
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, |
|
231 |
bodyLayer, bodyLayer.getSelectionLayer()); |
|
232 |
rowHeaderDataLayer.setColumnWidthByPosition(0, 50); |
|
233 |
|
|
234 |
//corner |
|
235 |
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider( |
|
236 |
colHeaderDataProvider, rowHeaderDataProvider); |
|
237 |
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider); |
|
238 |
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer); |
|
239 |
//grid |
|
240 |
GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer, |
|
241 |
rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing |
|
242 |
natTable = new NatTable(bottomComposite, gridLayer, false); |
|
243 |
|
|
244 |
dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, colHeaderDataProvider, |
|
245 |
bulkEditor.getEditorInput())); |
|
246 |
|
|
247 |
natTable.setConfigRegistry(configRegistry); |
|
248 |
|
|
249 |
//add tooltip to table |
|
250 |
new BulkEditorTooltip(natTable, colHeaderDataProvider); |
|
251 |
} |
|
252 |
|
|
253 |
private void configureTable(){ |
|
254 |
|
|
255 |
//this configuration enables cell to be editable in general |
|
256 |
//necessary because we disabled this beforehand by setting autoconfigure=false |
|
257 |
//in the GridLayer constructor |
|
258 |
((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration()); |
|
259 |
|
|
260 |
natTable.addConfiguration(new AbstractUiBindingConfiguration() { |
|
261 |
@Override |
|
262 |
public void configureUiBindings(UiBindingRegistry uiBindingRegistry) { |
|
263 |
uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY), |
|
264 |
new MouseEditAction()); |
|
265 |
} |
|
266 |
}); |
|
267 |
|
|
268 |
//make cells editable to allow selecting the text |
|
269 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
270 |
@Override |
|
271 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
272 |
//make cell editable |
|
273 |
configRegistry.registerConfigAttribute( |
|
274 |
EditConfigAttributes.CELL_EDITABLE_RULE, |
|
275 |
IEditableRule.ALWAYS_EDITABLE, |
|
276 |
DisplayMode.EDIT); |
|
277 |
//register editor |
|
278 |
TextCellEditor editor = new TextCellEditor(); |
|
279 |
editor.setEditable(false); |
|
280 |
configRegistry.registerConfigAttribute( |
|
281 |
EditConfigAttributes.CELL_EDITOR, |
|
282 |
editor, |
|
283 |
DisplayMode.NORMAL); |
|
284 |
} |
|
285 |
}); |
|
286 |
|
|
287 |
//+++CONTEXT MENU+++ |
|
288 |
menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$ |
|
289 |
// get the menu registered by EMenuService |
|
290 |
final Menu e4Menu = natTable.getMenu(); |
|
291 |
// remove the menu reference from NatTable instance |
|
292 |
natTable.setMenu(null); |
|
293 |
natTable.addConfiguration( |
|
294 |
new AbstractUiBindingConfiguration() { |
|
295 |
@Override |
|
296 |
public void configureUiBindings( |
|
297 |
UiBindingRegistry uiBindingRegistry) { |
|
298 |
// add e4 menu to NatTable |
|
299 |
new PopupMenuBuilder(natTable, e4Menu) |
|
300 |
.withHideColumnMenuItem() |
|
301 |
.withShowAllColumnsMenuItem() |
|
302 |
.build(); |
|
303 |
|
|
304 |
// register the UI binding for header, corner and body region |
|
305 |
uiBindingRegistry.registerMouseDownBinding( |
|
306 |
new MouseEventMatcher( |
|
307 |
SWT.NONE, |
|
308 |
null, |
|
309 |
MouseEventMatcher.RIGHT_BUTTON), |
|
310 |
new PopupMenuAction(e4Menu)); |
|
311 |
} |
|
312 |
}); |
|
313 |
|
|
314 |
//enable sorting |
|
315 |
natTable.addConfiguration(new SingleClickSortConfiguration()); |
|
316 |
|
|
317 |
// Custom style for deduplication labels |
|
318 |
natTable.addConfiguration(new BulkEditorLabelStyleConfiguration()); |
|
319 |
|
|
320 |
//add default configuration because autoconfigure is set to false in constructor |
|
321 |
natTable.addConfiguration(new DefaultNatTableStyleConfiguration()); |
|
322 |
|
|
323 |
//show boolean values as check boxes |
|
324 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
325 |
@Override |
|
326 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
327 |
configRegistry.registerConfigAttribute( |
|
328 |
CellConfigAttributes.CELL_PAINTER, |
|
329 |
new CheckBoxPainter(), |
|
330 |
DisplayMode.NORMAL, |
|
331 |
BulkEditorConfigLabelAccumulatorHeader.BOOLEAN_COLUMN); |
|
332 |
|
|
333 |
configRegistry.registerConfigAttribute( |
|
334 |
CellConfigAttributes.DISPLAY_CONVERTER, |
|
335 |
new DefaultBooleanDisplayConverter(), |
|
336 |
DisplayMode.NORMAL, |
|
337 |
BulkEditorConfigLabelAccumulatorHeader.BOOLEAN_COLUMN); |
|
338 |
} |
|
339 |
}); |
|
340 |
|
|
341 |
natTable.addConfiguration(new AbstractRegistryConfiguration() { |
|
342 |
@Override |
|
343 |
public void configureRegistry(IConfigRegistry configRegistry) { |
|
344 |
configRegistry.registerConfigAttribute( |
|
345 |
CellConfigAttributes.CELL_PAINTER, |
|
346 |
new ImagePainter(ImageResources.getImage(ImageResources.LOCK_ICON)), |
|
347 |
DisplayMode.NORMAL, |
|
348 |
BulkEditorConfigLabelAccumulatorHeader.CACHE_COLUMN); |
|
349 |
} |
|
350 |
}); |
|
351 |
|
|
352 |
//register handler for view configuration menu |
|
353 |
natTable.registerCommandHandler(bulkEditorSearch.getDisplayPersistenceDialogCommandHandler()); |
|
354 |
|
|
355 |
natTable.configure(); |
|
356 |
} |
|
357 |
|
|
358 |
private void styleTable(){ |
|
359 |
natTable.setTheme(new ModernNatTableThemeConfiguration()); |
|
360 |
} |
|
361 |
|
|
362 |
public void performSearch(BulkEditorQuery query) { |
|
363 |
eventBroker.post(WorkbenchEventConstants.CURRENT_ACTIVE_EDITOR, null); |
|
364 |
performSearch(query, null); |
|
365 |
|
|
366 |
} |
|
367 |
|
|
368 |
public void performSearch(BulkEditorQuery query, IStructuredSelection selection) { |
|
369 |
if (query != null) { |
|
370 |
if(StoreUtil.promptCheckIsDirty(bulkEditor)){ |
|
371 |
return; |
|
372 |
} |
|
373 |
bulkEditor.getEditorInput().performSearch(query, selection); |
|
374 |
bulkEditor.setLastQuery(query); |
|
375 |
} |
|
376 |
} |
|
377 |
|
|
378 |
public void refresh(){ |
|
379 |
natTable.doCommand(new VisualRefreshCommand()); |
|
380 |
} |
|
381 |
|
|
382 |
public List<String> getColumnList() { |
|
383 |
return columnList; |
|
384 |
} |
|
385 |
|
|
386 |
public IStructuredSelection getCellSelection(){ |
|
387 |
|
|
388 |
Set<Range> selectedRowPositions = bodyLayer.getSelectionLayer().getSelectedRowPositions(); |
|
389 |
Collection<ILayerCell> cells = bodyLayer.getSelectionLayer().getSelectedCells(); |
|
390 |
if (cells.size() == 1){ |
|
391 |
return new StructuredSelection(cells.iterator().next().getDataValue()); |
|
392 |
} |
|
393 |
List<Object> selectedObjects = new ArrayList<>(); |
|
394 |
for (Range range : selectedRowPositions) { |
|
395 |
for(int i=range.start;i<range.end;i++){ |
|
396 |
if (i>=0){ |
|
397 |
selectedObjects.add(bodyDataProvider.getRowObject(i)); |
|
398 |
} |
|
399 |
} |
|
400 |
} |
|
401 |
return new StructuredSelection(selectedObjects); |
|
402 |
} |
|
403 |
|
|
404 |
public IStructuredSelection getSelection(){ |
|
405 |
|
|
406 |
Set<Range> selectedRowPositions = bodyLayer.getSelectionLayer().getSelectedRowPositions(); |
|
407 |
List<Object> selectedObjects = new ArrayList<>(); |
|
408 |
for (Range range : selectedRowPositions) { |
|
409 |
for(int i=range.start;i<range.end;i++){ |
|
410 |
if (i>=0){ |
|
411 |
selectedObjects.add(bodyDataProvider.getRowObject(i)); |
|
412 |
} |
|
413 |
} |
|
414 |
} |
|
415 |
return new StructuredSelection(selectedObjects); |
|
416 |
} |
|
417 |
|
|
418 |
public void setSelection(IStructuredSelection selection){ |
|
419 |
Object[] objects = selection.toArray(); |
|
420 |
for (Object object : objects) { |
|
421 |
|
|
422 |
if(object instanceof CdmBase && bulkEditor.getEditorInput().getModel().contains(object)){ |
|
423 |
object = bulkEditor.getEditorInput().getModel().get(bulkEditor.getEditorInput().getModel().indexOf(object)); |
|
424 |
bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false); |
|
425 |
} |
|
426 |
} |
|
427 |
} |
|
428 |
|
|
429 |
public void copyDataToClipboard() { |
|
430 |
String textData = ""; //$NON-NLS-1$ |
|
431 |
IStructuredSelection selection = getCellSelection(); |
|
432 |
Object[] objects = selection.toArray(); |
|
433 |
for (Object object : objects) { |
|
434 |
if(object instanceof CdmBase){ |
|
435 |
textData += bulkEditor.getEditorInput().getText((CdmBase)object); |
|
436 |
}else if (object instanceof String){ |
|
437 |
textData += (String)object; |
|
438 |
}else { |
|
439 |
textData += object.toString(); |
|
440 |
} |
|
441 |
} |
|
442 |
final TextTransfer textTransfer = TextTransfer.getInstance(); |
|
443 |
final Clipboard clipboard = new Clipboard(Display.getDefault()); |
|
444 |
try { |
|
445 |
clipboard.setContents(new Object[] { textData.toString() }, |
|
446 |
new Transfer[] { textTransfer }); |
|
447 |
} finally { |
|
448 |
clipboard.dispose(); |
|
449 |
} |
|
450 |
} |
|
451 |
|
|
452 |
protected ListDataProvider<CdmBase> getBodyDataProvider() { |
|
453 |
return bodyDataProvider; |
|
454 |
} |
|
455 |
|
|
456 |
protected ESelectionService getSelService() { |
|
457 |
return selService; |
|
458 |
} |
|
459 |
|
|
460 |
protected NatTable getNatTable() { |
|
461 |
return natTable; |
|
462 |
} |
|
463 |
|
|
464 |
protected Properties getNatTableState() { |
|
465 |
return bulkEditorSearch.getNatTableState(); |
|
466 |
} |
|
467 |
|
|
468 |
protected File getStatePropertiesFile() { |
|
469 |
return bulkEditorSearch.getStatePropertiesFile(); |
|
470 |
} |
|
471 |
} |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelStyleConfiguration.java | ||
---|---|---|
40 | 40 |
CellConfigAttributes.CELL_STYLE, |
41 | 41 |
candidateCellStyle, |
42 | 42 |
DisplayMode.NORMAL, |
43 |
BulkEditorE4Composite.LABEL_CANDIDATE);
|
|
43 |
BulkEditorComposite.LABEL_CANDIDATE); |
|
44 | 44 |
configRegistry.registerConfigAttribute( |
45 | 45 |
CellConfigAttributes.CELL_PAINTER, |
46 | 46 |
new CellPainterDecorator( |
... | ... | |
49 | 49 |
new ImagePainter(ImageResources.getImage(ImageResources.ACTIVE_DELETE_ICON)), |
50 | 50 |
false), |
51 | 51 |
DisplayMode.NORMAL, |
52 |
BulkEditorE4Composite.LABEL_CANDIDATE_ICON);
|
|
52 |
BulkEditorComposite.LABEL_CANDIDATE_ICON); |
|
53 | 53 |
|
54 | 54 |
//deduplication target style |
55 | 55 |
Style targetCellStyle = new Style(); |
... | ... | |
58 | 58 |
ColorResources.getColor(Resources.COLOR_BULK_EDITOR_TARGET)); |
59 | 59 |
configRegistry.registerConfigAttribute( |
60 | 60 |
CellConfigAttributes.CELL_STYLE, targetCellStyle, |
61 |
DisplayMode.NORMAL, BulkEditorE4Composite.LABEL_TARGET);
|
|
61 |
DisplayMode.NORMAL, BulkEditorComposite.LABEL_TARGET); |
|
62 | 62 |
configRegistry.registerConfigAttribute( |
63 | 63 |
CellConfigAttributes.CELL_PAINTER, |
64 | 64 |
new CellPainterDecorator( |
... | ... | |
67 | 67 |
new ImagePainter(ImageResources.getImage(ImageResources.IMPORT)), |
68 | 68 |
false), |
69 | 69 |
DisplayMode.NORMAL, |
70 |
BulkEditorE4Composite.LABEL_TARGET_ICON);
|
|
70 |
BulkEditorComposite.LABEL_TARGET_ICON); |
|
71 | 71 |
|
72 | 72 |
} |
73 | 73 |
} |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java | ||
---|---|---|
21 | 21 |
public class BulkEditorPropertyAccessor implements IColumnPropertyAccessor<CdmBase> { |
22 | 22 |
|
23 | 23 |
private AbstractBulkEditorInput<CdmBase> input; |
24 |
private BulkEditorE4Composite bulkEditorComposite;
|
|
24 |
private BulkEditorComposite bulkEditorComposite; |
|
25 | 25 |
|
26 |
public BulkEditorPropertyAccessor(BulkEditorE4Composite bulkEditorComposite, AbstractBulkEditorInput<CdmBase> input) {
|
|
26 |
public BulkEditorPropertyAccessor(BulkEditorComposite bulkEditorComposite, AbstractBulkEditorInput<CdmBase> input) { |
|
27 | 27 |
super(); |
28 | 28 |
this.input = input; |
29 | 29 |
this.bulkEditorComposite = bulkEditorComposite; |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearch.java | ||
---|---|---|
53 | 53 |
|
54 | 54 |
private static final String DEFAULT_TEXT = String.format(Messages.BulkEditorSearchE4_WILDCARD, SearchManager.WILDCARD); |
55 | 55 |
|
56 |
private final BulkEditorE4Composite editor;
|
|
56 |
private final BulkEditorComposite editor; |
|
57 | 57 |
|
58 | 58 |
private DisplayPersistenceDialogCommandHandler displayPersistenceDialogCommandHandler; |
59 | 59 |
|
... | ... | |
67 | 67 |
|
68 | 68 |
public Object ORDER_BY = new Object(); |
69 | 69 |
|
70 |
public BulkEditorSearch(BulkEditorE4Composite editor, Composite parent, int style) {
|
|
70 |
public BulkEditorSearch(BulkEditorComposite editor, Composite parent, int style) { |
|
71 | 71 |
this.editor = editor; |
72 | 72 |
|
73 | 73 |
createControl(parent, style); |
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java | ||
---|---|---|
49 | 49 |
int row = this.natTable.getRowPositionByY(event.y); |
50 | 50 |
|
51 | 51 |
LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row); |
52 |
if(configLabels.hasLabel(BulkEditorE4Composite.LABEL_TARGET)){
|
|
52 |
if(configLabels.hasLabel(BulkEditorComposite.LABEL_TARGET)){ |
|
53 | 53 |
return Messages.BulkEditorTooltip_TARGET; |
54 | 54 |
} |
55 |
else if(configLabels.hasLabel(BulkEditorE4Composite.LABEL_CANDIDATE)){
|
|
55 |
else if(configLabels.hasLabel(BulkEditorComposite.LABEL_CANDIDATE)){ |
|
56 | 56 |
return Messages.BulkEditorTooltip_CANDIDATE; |
57 | 57 |
} |
58 | 58 |
int colIndex = this.natTable.getColumnIndexByPosition(col); |
... | ... | |
75 | 75 |
int row = this.natTable.getRowPositionByY(event.y); |
76 | 76 |
|
77 | 77 |
LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row); |
78 |
if(configLabels.hasLabel(BulkEditorE4Composite.LABEL_CANDIDATE)
|
|
79 |
|| configLabels.hasLabel(BulkEditorE4Composite.LABEL_TARGET)){
|
|
78 |
if(configLabels.hasLabel(BulkEditorComposite.LABEL_CANDIDATE) |
|
79 |
|| configLabels.hasLabel(BulkEditorComposite.LABEL_TARGET)){ |
|
80 | 80 |
return true; |
81 | 81 |
} |
82 | 82 |
|
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/CellSelectionListener.java | ||
---|---|---|
28 | 28 |
*/ |
29 | 29 |
final class CellSelectionListener extends E4SelectionListener<CdmBase> { |
30 | 30 |
|
31 |
private BulkEditorE4Composite bulkEditor;
|
|
31 |
private BulkEditorComposite bulkEditor; |
|
32 | 32 |
|
33 | 33 |
public CellSelectionListener( |
34 | 34 |
ESelectionService service, |
35 | 35 |
SelectionLayer selectionLayer, |
36 | 36 |
IRowDataProvider<CdmBase> rowDataProvider, |
37 |
BulkEditorE4Composite bulkEditor) {
|
|
37 |
BulkEditorComposite bulkEditor) { |
|
38 | 38 |
super(service, selectionLayer, rowDataProvider); |
39 | 39 |
this.bulkEditor = bulkEditor; |
40 | 40 |
} |
Also available in: Unified diff
ref #9448: remove E4 from file names - bulkeditor continue