Project

General

Profile

« Previous | Next » 

Revision 96e043f8

Added by Patrick Plitzner almost 6 years ago

ref #7439 Split BulkEditorE4 in E4 part and Composite

  • clean up code

View differences:

eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java
36 36
    public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
37 37
        CdmBase rowObject = dataProvider.getRowObject(rowPosition);
38 38
        if(input.getMergeCandidates().contains(rowObject)){
39
            configLabels.addLabel(BulkEditorE4.CANDIDATE_LABEL);
39
            configLabels.addLabel(BulkEditorE4Composite.CANDIDATE_LABEL);
40 40
        }
41 41
        else if(input.getMergeTarget()==rowObject){
42
            configLabels.addLabel(BulkEditorE4.TARGET_LABEL);
42
            configLabels.addLabel(BulkEditorE4Composite.TARGET_LABEL);
43 43
        }
44 44
    }
45 45
}
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4.java
9 9

  
10 10
package eu.etaxonomy.taxeditor.bulkeditor.e4;
11 11

  
12
import java.io.Serializable;
13
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17

  
18 12
import javax.annotation.PostConstruct;
19 13
import javax.annotation.PreDestroy;
20 14
import javax.inject.Inject;
21 15

  
22 16
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.NullProgressMonitor;
17
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
24 18
import org.eclipse.e4.core.contexts.IEclipseContext;
25 19
import org.eclipse.e4.core.di.annotations.Optional;
26 20
import org.eclipse.e4.core.services.events.IEventBroker;
......
29 23
import org.eclipse.e4.ui.di.UIEventTopic;
30 24
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
31 25
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
32
import org.eclipse.e4.ui.services.EMenuService;
33
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
34
import org.eclipse.jface.dialogs.MessageDialog;
35
import org.eclipse.jface.layout.GridDataFactory;
36
import org.eclipse.jface.viewers.ISelectionChangedListener;
37 26
import org.eclipse.jface.viewers.IStructuredSelection;
38 27
import org.eclipse.jface.viewers.StructuredSelection;
39
import org.eclipse.nebula.widgets.nattable.NatTable;
40
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
41
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler;
42
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
43
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
44
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
45
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
46
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
47
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
48
import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
49
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
50
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
51
import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction;
52
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;
53
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
54
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
55
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
56
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
57
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
58
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
59
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
60
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
61
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
62
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
63
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
64
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
65
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
66
import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack;
67
import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
68
import org.eclipse.nebula.widgets.nattable.selection.RowSelectionProvider;
69
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
70
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
71
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
72
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
73
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
74
import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher;
75
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
76
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction;
77
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
78 28
import org.eclipse.swt.SWT;
79
import org.eclipse.swt.dnd.Clipboard;
80
import org.eclipse.swt.dnd.TextTransfer;
81
import org.eclipse.swt.dnd.Transfer;
82
import org.eclipse.swt.layout.GridData;
83
import org.eclipse.swt.layout.GridLayout;
84 29
import org.eclipse.swt.widgets.Composite;
85
import org.eclipse.swt.widgets.Display;
86
import org.eclipse.swt.widgets.Menu;
87 30

  
88
import ca.odell.glazedlists.SortedList;
89 31
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
90 32
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
91 33
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
92 34
import eu.etaxonomy.cdm.model.common.CdmBase;
93
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
94 35
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
95 36
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
96 37
import eu.etaxonomy.cdm.model.taxon.Taxon;
......
99 40
import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
100 41
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
101 42
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
102
import eu.etaxonomy.taxeditor.l10n.Messages;
103 43
import eu.etaxonomy.taxeditor.model.IDerivedUnitFacadePart;
104 44
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
105 45
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
......
119 59
        IDirtyMarkable, IDerivedUnitFacadePart, IPartContentHasFactualData,
120 60
        IPartContentHasSupplementalData, IPartContentHasMedia, IE4SavablePart, ITaxonEditor {
121 61

  
122
    public static final String TARGET_LABEL = "target";
123
    public static final String CANDIDATE_LABEL = "candidate";
124

  
125
    public static final String TYPE_PROPERTY = Messages.BulkEditorE4_TYPE;
126

  
127 62
    @Inject
128 63
	private MDirtyable dirty;
129 64

  
130 65
    private AbstractBulkEditorInput input;
131 66

  
132
    private Composite topComposite;
133

  
134 67
    private ConversationHolder conversation;
135 68

  
136
    @Inject
137
    private ESelectionService selService;
138

  
139 69
    @Inject
140 70
    private IEventBroker eventBroker;
141 71

  
142
    private ISelectionChangedListener selectionChangedListener;
143

  
144 72
    @Inject
145 73
    IEclipseContext context;
146 74

  
......
149 77

  
150 78
    private BulkEditorQuery lastQuery = null;
151 79

  
152
    private Composite bottomComposite;
153

  
154
    @Inject
155
    private EMenuService menuService;
156

  
157
    private NatTable natTable;
158

  
159
    private DefaultBodyLayerStack bodyLayer;
160

  
161
    private ListDataProvider<CdmBase> bodyDataProvider;
80
    private BulkEditorE4Composite bulkEditorComposite;
162 81

  
163 82
    @Inject
164 83
    public BulkEditorE4() {
......
168 87
    public void init(AbstractBulkEditorInput<?> input){
169 88
	    this.input = input;
170 89
	    this.conversation = input.getConversation();
171

  
172
	    new BulkEditorSearchE4(this, topComposite, SWT.NONE);
173
	    //layout needed because the search bar is added after @PostConstuct method
174
	    topComposite.getParent().layout();
175

  
176 90
	    thisPart.setLabel(input.getEditorName());
177 91

  
178
        if(input.getEntityUuid()!=null){
179
            performSearch(new BulkEditorQuery(input.getEntityUuid().toString()));
180
        }
181

  
182
        createTable();
183

  
184
        configureTable();
185

  
186
        styleTable();
187

  
188
        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
189

  
190
        //propagate selection
191
        selectionChangedListener = (event -> selService.setSelection(getSelection()));
192
        RowSelectionProvider<CdmBase> selectionProvider = new RowSelectionProvider<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, true);
193
        selectionProvider.addSelectionChangedListener(selectionChangedListener);
194

  
195
        bottomComposite.layout();
196
	}
197

  
198
	private void createTable(){
199
	    ConfigRegistry configRegistry = new ConfigRegistry();
200
	    //property map
201
        Map<String, String> propertyToLabels = new HashMap<>();
202
        propertyToLabels.put(getEditorInput().getName(), getEditorInput().getName());
203
        propertyToLabels.put(TYPE_PROPERTY, TYPE_PROPERTY);
204
        String[] propertyNames = new String[] { input.getName(), TYPE_PROPERTY };
205
        //sorted list
206
        SortedList<CdmBase> sortedList = new SortedList<>(input.getModel(), input.getTitleComparator());
207
        //data provider
208
        BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(input);
209
        bodyDataProvider = new ListDataProvider<CdmBase>(sortedList,
210
                columnPropertyAccessor);
211
        DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(
212
                propertyNames, propertyToLabels);
213
        DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
214
                bodyDataProvider);
215
        //body
216
        DataLayer dataLayer = new DataLayer(bodyDataProvider);
217
        dataLayer.registerCommandHandler(new VisualRefreshCommandHandler());
218
        GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, input.getModel());
219
        bodyLayer = new DefaultBodyLayerStack(eventLayer);
220

  
221
        dataLayer.setColumnPercentageSizing(true);
222
        dataLayer.setColumnWidthPercentageByPosition(0, 80);
223
        dataLayer.setColumnWidthPercentageByPosition(1, 20);
224

  
225
        //column
226
        DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider);
227
        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
228
                columnHeaderDataLayer,
229
                bodyLayer, bodyLayer.getSelectionLayer());
230
        // add the SortHeaderLayer to the column header layer stack
231
        // as we use GlazedLists, we use the GlazedListsSortModel which
232
        // delegates the sorting to the SortedList
233
        final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>(
234
                columnHeaderLayer,
235
                new GlazedListsSortModel<>(
236
                        sortedList,
237
                        columnPropertyAccessor,
238
                        configRegistry,
239
                        columnHeaderDataLayer));
240
        //row
241
        DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
242
        RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
243
                bodyLayer, bodyLayer.getSelectionLayer());
244

  
245
        //corner
246
        DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
247
                colHeaderDataProvider, rowHeaderDataProvider);
248
        DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
249
        CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer);
250
        //grid
251
        GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer,
252
                rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing
253
        natTable = new NatTable(bottomComposite, gridLayer, false);
254
        natTable.setConfigRegistry(configRegistry);
255

  
256
        //full row selection
257
        bodyLayer.getSelectionLayer().setSelectionModel(new RowSelectionModel<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, new IRowIdAccessor<CdmBase>() {
258
            @Override
259
            public Serializable getRowId(CdmBase rowObject) {
260
                return input.getModel().indexOf(rowObject);
261
            }
262
        }));
263

  
264
        //add label to deduplication rows
265
        dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, input));
266

  
267
        //add tooltip to table
268
        new BulkEditorTooltip(natTable);
269
	}
270

  
271
	private void configureTable(){
272

  
273
	    //this configuration enables cell to be editable in general
274
	    //necessary because we disabled this beforehand by setting autoconfigure=false
275
	    //in the GridLayer constructor
276
	    ((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration());
277

  
278
        natTable.addConfiguration(new AbstractUiBindingConfiguration() {
279
            @Override
280
            public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
281
                uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY),
282
                        new MouseEditAction());
283
            }
284
        });
285

  
286
        //make cells editable to allow selecting the text
287
        natTable.addConfiguration(new AbstractRegistryConfiguration() {
288
            @Override
289
            public void configureRegistry(IConfigRegistry configRegistry) {
290
                //make cell editable
291
                configRegistry.registerConfigAttribute(
292
                        EditConfigAttributes.CELL_EDITABLE_RULE,
293
                        IEditableRule.ALWAYS_EDITABLE,
294
                        DisplayMode.EDIT);
295
                //register editor
296
                TextCellEditor editor = new TextCellEditor();
297
                editor.setEditable(false);
298
                configRegistry.registerConfigAttribute(
299
                        EditConfigAttributes.CELL_EDITOR,
300
                        editor,
301
                        DisplayMode.NORMAL);
302
            }
303
        });
304

  
305
        //+++CONTEXT MENU+++
306
        menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
307
        // get the menu registered by EMenuService
308
        final Menu e4Menu = natTable.getMenu();
309
        // remove the menu reference from NatTable instance
310
        natTable.setMenu(null);
311
        natTable.addConfiguration(
312
                new AbstractUiBindingConfiguration() {
313
            @Override
314
            public void configureUiBindings(
315
                    UiBindingRegistry uiBindingRegistry) {
316
                // add e4 menu to NatTable
317
                new PopupMenuBuilder(natTable, e4Menu)
318
                    .build();
319

  
320
                // register the UI binding for header, corner and body region
321
                uiBindingRegistry.registerMouseDownBinding(
322
                        new MouseEventMatcher(
323
                                SWT.NONE,
324
                                null,
325
                                MouseEventMatcher.RIGHT_BUTTON),
326
                        new PopupMenuAction(e4Menu));
327
            }
328
        });
329

  
330

  
331
        //enable sorting
332
        natTable.addConfiguration(new SingleClickSortConfiguration());
333

  
334
        // Custom style for deduplication labels
335
        natTable.addConfiguration(new LabelStyleConfiguration());
336

  
337
        //add default configuration because autoconfigure is set to false in constructor
338
        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
339
        natTable.configure();
340
	}
341

  
342
	private void styleTable(){
343
	    natTable.setTheme(new ModernNatTableThemeConfiguration());
92
	    bulkEditorComposite.init(input);
344 93
	}
345 94

  
346 95
	/** {@inheritDoc} */
347 96
	@PostConstruct
348
	public void createPartControl(Composite parent) {
349
		parent.setLayout(new GridLayout());
350

  
351
		topComposite = new Composite(parent, SWT.NONE);
352
		topComposite.setLayout(new GridLayout());
353

  
354
		GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
355
		topComposite.setLayoutData(gridData);
356

  
357
		bottomComposite = new Composite(parent, SWT.NONE);
358
		bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
359
		bottomComposite.setLayout(new GridLayout());
97
	public void createPartControl(Composite parent, IEclipseContext context) {
98
	    bulkEditorComposite = new BulkEditorE4Composite(this, parent, SWT.NONE);
99
	    ContextInjectionFactory.inject(bulkEditorComposite, context);
360 100
	}
361 101

  
362 102
	@Override
......
365 105
	    save(monitor, true);
366 106
	}
367 107

  
108
    public void save(IProgressMonitor monitor, boolean resetMerge) {
109
        if (!input.getCdmEntitySession().isActive()){
110
            input.getCdmEntitySession().bind();
111
        }
112
        input.saveModel(resetMerge);
113

  
114
        IStructuredSelection selection = getSelection();
115

  
116
        dirty.setDirty(false);
117
        input.dispose();
118
        input.bind();
119
        conversation.commit(true);
120

  
121
        if (lastQuery != null){
122
            bulkEditorComposite.performSearch(lastQuery, selection);
123
        }
124
    }
125

  
368 126
	@Focus
369 127
	public void setFocus() {
370 128
        //make sure to bind again if maybe in another view the conversation was unbound
......
391 149
	    dirty.setDirty(false);
392 150
	}
393 151

  
394
	public void save(IProgressMonitor monitor, boolean resetMerge) {
395
	    if (!input.getCdmEntitySession().isActive()){
396
            input.getCdmEntitySession().bind();
397
        }
398
	    input.saveModel(resetMerge);
399

  
400
	    IStructuredSelection selection = getSelection();
401

  
402
        dirty.setDirty(false);
403
        input.dispose();
404
        input.bind();
405
        conversation.commit(true);
406

  
407
        if (lastQuery != null){
408
            performSearch(lastQuery, selection);
409
        }
410
	}
411

  
412
	public void performSearch(BulkEditorQuery query) {
413
	    performSearch(query, null);
414
	}
415

  
416
	/** {@inheritDoc}
417
	 * @param selection */
418
    public void performSearch(BulkEditorQuery query, IStructuredSelection selection) {
419
        if (query != null) {
420
            // TODO check if dirty, prompt save
421
            if (isDirty()) {
422
                String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
423
                MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
424
                int result = dialog.open();
425
                if (result == 0) {
426
                    save(new NullProgressMonitor());
427
                } else if (result == 2){
428
                    return;
429
                }
430
            }
431
            dirty.setDirty(false);
432
            input.performSearch(query, selection);
433
            lastQuery = query;
434
        }
435
    }
436

  
437 152
    @Optional
438 153
    @Inject
439 154
    private void updateAfterSearch(@UIEventTopic(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED)IStructuredSelection selection){
......
443 158
    }
444 159

  
445 160
    public void refresh(){
446
        natTable.doCommand(new VisualRefreshCommand());
161
        bulkEditorComposite.refresh();
447 162
    }
448 163

  
449 164
    public IStructuredSelection getSelection(){
450
        List<CdmBase> selection = new ArrayList<>();
451
        int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
452
        for (int i : fullySelectedRowPositions) {
453
            Object rowObject = bodyDataProvider.getRowObject(i);
454
            if(rowObject instanceof CdmBase){
455
                selection.add((CdmBase) rowObject);
456
            }
457
        }
458
        return new StructuredSelection(selection);
165
        return bulkEditorComposite.getSelection();
459 166
    }
460 167

  
461 168
    public void setSelection(IStructuredSelection selection){
462
        Object[] objects = selection.toArray();
463
        for (Object object : objects) {
169
        bulkEditorComposite.setSelection(selection);
170
    }
464 171

  
465
            if(object instanceof CdmBase &&  input.getModel().contains(object)){
466
                bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false);
467
            }
468
        }
172
    public void setDirty(boolean isDirty){
173
        dirty.setDirty(isDirty);
469 174
    }
470 175

  
471 176
    public void setDirty(){
472
        dirty.setDirty(true);
177
        setDirty(true);
473 178
    }
474 179

  
475 180
    public boolean isDirty() {
......
481 186
    }
482 187

  
483 188
    public void copyDataToClipboard() {
484
        String textData = "";
485
        IStructuredSelection selection = getSelection();
486
        Object[] objects = selection.toArray();
487
        for (Object object : objects) {
488
            if(object instanceof CdmBase){
489
                textData += getEditorInput().getText((CdmBase)object);
490
            }
491
        }
492
        final TextTransfer textTransfer = TextTransfer.getInstance();
493
        final Clipboard clipboard = new Clipboard(Display.getDefault());
494
        try {
495
            clipboard.setContents(new Object[] { textData.toString() },
496
                    new Transfer[] { textTransfer });
497
        } finally {
498
            clipboard.dispose();
499
        }
189
        bulkEditorComposite.copyDataToClipboard();
500 190
    }
501 191

  
502 192
    @Override
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

  
10
package eu.etaxonomy.taxeditor.bulkeditor.e4;
11

  
12
import java.io.Serializable;
13
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17

  
18
import javax.inject.Inject;
19

  
20
import org.eclipse.core.runtime.NullProgressMonitor;
21
import org.eclipse.e4.ui.services.EMenuService;
22
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
23
import org.eclipse.jface.dialogs.MessageDialog;
24
import org.eclipse.jface.layout.GridDataFactory;
25
import org.eclipse.jface.viewers.ISelectionChangedListener;
26
import org.eclipse.jface.viewers.IStructuredSelection;
27
import org.eclipse.jface.viewers.StructuredSelection;
28
import org.eclipse.nebula.widgets.nattable.NatTable;
29
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
30
import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler;
31
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
32
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
33
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
34
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
35
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
36
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
37
import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
38
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
39
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
40
import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction;
41
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;
42
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
43
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
44
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
45
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
46
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
47
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
48
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
49
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
50
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
51
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
52
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
53
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
54
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
55
import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack;
56
import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
57
import org.eclipse.nebula.widgets.nattable.selection.RowSelectionProvider;
58
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
59
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
60
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
61
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
62
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
63
import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher;
64
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
65
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction;
66
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
67
import org.eclipse.swt.SWT;
68
import org.eclipse.swt.dnd.Clipboard;
69
import org.eclipse.swt.dnd.TextTransfer;
70
import org.eclipse.swt.dnd.Transfer;
71
import org.eclipse.swt.layout.GridData;
72
import org.eclipse.swt.layout.GridLayout;
73
import org.eclipse.swt.widgets.Composite;
74
import org.eclipse.swt.widgets.Display;
75
import org.eclipse.swt.widgets.Menu;
76

  
77
import ca.odell.glazedlists.SortedList;
78
import eu.etaxonomy.cdm.model.common.CdmBase;
79
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
80
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
81
import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
82
import eu.etaxonomy.taxeditor.l10n.Messages;
83

  
84
/**
85
 *
86
 * @author pplitzner
87
 * @since Sep 8, 2017
88
 *
89
 */
90
public class BulkEditorE4Composite extends Composite {
91

  
92
    public static final String TYPE_PROPERTY = Messages.BulkEditorE4_TYPE;
93

  
94
    public static final String CANDIDATE_LABEL = "candidate";
95

  
96
    public static final String TARGET_LABEL = "target";
97

  
98
    private Composite topComposite;
99

  
100
    @Inject
101
    private ESelectionService selService;
102

  
103
    private ISelectionChangedListener selectionChangedListener;
104

  
105
    private Composite bottomComposite;
106

  
107
    @Inject
108
    private EMenuService menuService;
109

  
110
    private NatTable natTable;
111

  
112
    private DefaultBodyLayerStack bodyLayer;
113

  
114
    private ListDataProvider<CdmBase> bodyDataProvider;
115

  
116
    private BulkEditorE4 bulkEditor;
117

  
118

  
119
    public BulkEditorE4Composite(BulkEditorE4 bulkEditor, Composite parent, int style) {
120
        super(parent, style);
121
        parent.setLayout(new GridLayout());
122
        this.bulkEditor = bulkEditor;
123

  
124
        this.setLayout(new GridLayout());
125

  
126
        topComposite = new Composite(parent, SWT.NONE);
127
        topComposite.setLayout(new GridLayout());
128

  
129
        GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
130
        topComposite.setLayoutData(gridData);
131

  
132
        bottomComposite = new Composite(parent, SWT.NONE);
133
        bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
134
        bottomComposite.setLayout(new GridLayout());
135
	}
136

  
137
	@SuppressWarnings("unused")
138
    public void init(AbstractBulkEditorInput<?> input){
139

  
140
	    new BulkEditorSearchE4(this, topComposite, SWT.NONE);
141
	    //layout needed because the search bar is added after @PostConstuct method
142
	    topComposite.getParent().layout();
143

  
144
        if(input.getEntityUuid()!=null){
145
            performSearch(new BulkEditorQuery(input.getEntityUuid().toString()));
146
        }
147

  
148
        createTable();
149

  
150
        configureTable();
151

  
152
        styleTable();
153

  
154
        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
155

  
156
        //propagate selection
157
        selectionChangedListener = (event -> selService.setSelection(getSelection()));
158
        RowSelectionProvider<CdmBase> selectionProvider = new RowSelectionProvider<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, true);
159
        selectionProvider.addSelectionChangedListener(selectionChangedListener);
160

  
161
        bottomComposite.layout();
162
	}
163

  
164
	private void createTable(){
165
	    ConfigRegistry configRegistry = new ConfigRegistry();
166
	    //property map
167
        Map<String, String> propertyToLabels = new HashMap<>();
168
        propertyToLabels.put(bulkEditor.getEditorInput().getName(), bulkEditor.getEditorInput().getName());
169
        propertyToLabels.put(TYPE_PROPERTY, TYPE_PROPERTY);
170
        String[] propertyNames = new String[] { bulkEditor.getEditorInput().getName(), TYPE_PROPERTY };
171
        //sorted list
172
        SortedList<CdmBase> sortedList = new SortedList<>(bulkEditor.getEditorInput().getModel(), bulkEditor.getEditorInput().getTitleComparator());
173
        //data provider
174
        BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(bulkEditor.getEditorInput());
175
        bodyDataProvider = new ListDataProvider<CdmBase>(sortedList,
176
                columnPropertyAccessor);
177
        DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(
178
                propertyNames, propertyToLabels);
179
        DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
180
                bodyDataProvider);
181
        //body
182
        DataLayer dataLayer = new DataLayer(bodyDataProvider);
183
        dataLayer.registerCommandHandler(new VisualRefreshCommandHandler());
184
        GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, bulkEditor.getEditorInput().getModel());
185
        bodyLayer = new DefaultBodyLayerStack(eventLayer);
186

  
187
        dataLayer.setColumnPercentageSizing(true);
188
        dataLayer.setColumnWidthPercentageByPosition(0, 80);
189
        dataLayer.setColumnWidthPercentageByPosition(1, 20);
190

  
191
        //column
192
        DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider);
193
        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
194
                columnHeaderDataLayer,
195
                bodyLayer, bodyLayer.getSelectionLayer());
196
        // add the SortHeaderLayer to the column header layer stack
197
        // as we use GlazedLists, we use the GlazedListsSortModel which
198
        // delegates the sorting to the SortedList
199
        final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>(
200
                columnHeaderLayer,
201
                new GlazedListsSortModel<>(
202
                        sortedList,
203
                        columnPropertyAccessor,
204
                        configRegistry,
205
                        columnHeaderDataLayer));
206
        //row
207
        DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
208
        RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
209
                bodyLayer, bodyLayer.getSelectionLayer());
210

  
211
        //corner
212
        DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
213
                colHeaderDataProvider, rowHeaderDataProvider);
214
        DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
215
        CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer);
216
        //grid
217
        GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer,
218
                rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing
219
        natTable = new NatTable(bottomComposite, gridLayer, false);
220
        natTable.setConfigRegistry(configRegistry);
221

  
222
        //full row selection
223
        bodyLayer.getSelectionLayer().setSelectionModel(new RowSelectionModel<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, new IRowIdAccessor<CdmBase>() {
224
            @Override
225
            public Serializable getRowId(CdmBase rowObject) {
226
                return bulkEditor.getEditorInput().getModel().indexOf(rowObject);
227
            }
228
        }));
229

  
230
        //add label to deduplication rows
231
        dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, bulkEditor.getEditorInput()));
232

  
233
        //add tooltip to table
234
        new BulkEditorTooltip(natTable);
235
	}
236

  
237
	private void configureTable(){
238

  
239
	    //this configuration enables cell to be editable in general
240
	    //necessary because we disabled this beforehand by setting autoconfigure=false
241
	    //in the GridLayer constructor
242
	    ((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration());
243

  
244
        natTable.addConfiguration(new AbstractUiBindingConfiguration() {
245
            @Override
246
            public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
247
                uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY),
248
                        new MouseEditAction());
249
            }
250
        });
251

  
252
        //make cells editable to allow selecting the text
253
        natTable.addConfiguration(new AbstractRegistryConfiguration() {
254
            @Override
255
            public void configureRegistry(IConfigRegistry configRegistry) {
256
                //make cell editable
257
                configRegistry.registerConfigAttribute(
258
                        EditConfigAttributes.CELL_EDITABLE_RULE,
259
                        IEditableRule.ALWAYS_EDITABLE,
260
                        DisplayMode.EDIT);
261
                //register editor
262
                TextCellEditor editor = new TextCellEditor();
263
                editor.setEditable(false);
264
                configRegistry.registerConfigAttribute(
265
                        EditConfigAttributes.CELL_EDITOR,
266
                        editor,
267
                        DisplayMode.NORMAL);
268
            }
269
        });
270

  
271
        //+++CONTEXT MENU+++
272
        menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
273
        // get the menu registered by EMenuService
274
        final Menu e4Menu = natTable.getMenu();
275
        // remove the menu reference from NatTable instance
276
        natTable.setMenu(null);
277
        natTable.addConfiguration(
278
                new AbstractUiBindingConfiguration() {
279
            @Override
280
            public void configureUiBindings(
281
                    UiBindingRegistry uiBindingRegistry) {
282
                // add e4 menu to NatTable
283
                new PopupMenuBuilder(natTable, e4Menu)
284
                    .build();
285

  
286
                // register the UI binding for header, corner and body region
287
                uiBindingRegistry.registerMouseDownBinding(
288
                        new MouseEventMatcher(
289
                                SWT.NONE,
290
                                null,
291
                                MouseEventMatcher.RIGHT_BUTTON),
292
                        new PopupMenuAction(e4Menu));
293
            }
294
        });
295

  
296

  
297
        //enable sorting
298
        natTable.addConfiguration(new SingleClickSortConfiguration());
299

  
300
        // Custom style for deduplication labels
301
        natTable.addConfiguration(new LabelStyleConfiguration());
302

  
303
        //add default configuration because autoconfigure is set to false in constructor
304
        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
305
        natTable.configure();
306
	}
307

  
308
	private void styleTable(){
309
	    natTable.setTheme(new ModernNatTableThemeConfiguration());
310
	}
311

  
312
	public void performSearch(BulkEditorQuery query) {
313
	    performSearch(query, null);
314
	}
315

  
316
	/** {@inheritDoc}
317
	 * @param selection */
318
    public void performSearch(BulkEditorQuery query, IStructuredSelection selection) {
319
        if (query != null) {
320
            if (bulkEditor.isDirty()) {
321
                String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
322
                MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
323
                int result = dialog.open();
324
                if (result == 0) {
325
                    bulkEditor.save(new NullProgressMonitor());
326
                } else if (result == 2){
327
                    return;
328
                }
329
            }
330
            bulkEditor.setDirty(false);
331
            bulkEditor.getEditorInput().performSearch(query, selection);
332
            bulkEditor.setLastQuery(query);
333
        }
334
    }
335

  
336
    public void refresh(){
337
        natTable.doCommand(new VisualRefreshCommand());
338
    }
339

  
340
    public IStructuredSelection getSelection(){
341
        List<CdmBase> selection = new ArrayList<>();
342
        int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
343
        for (int i : fullySelectedRowPositions) {
344
            Object rowObject = bodyDataProvider.getRowObject(i);
345
            if(rowObject instanceof CdmBase){
346
                selection.add((CdmBase) rowObject);
347
            }
348
        }
349
        return new StructuredSelection(selection);
350
    }
351

  
352
    public void setSelection(IStructuredSelection selection){
353
        Object[] objects = selection.toArray();
354
        for (Object object : objects) {
355

  
356
            if(object instanceof CdmBase &&  bulkEditor.getEditorInput().getModel().contains(object)){
357
                bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false);
358
            }
359
        }
360
    }
361

  
362
    public void copyDataToClipboard() {
363
        String textData = "";
364
        IStructuredSelection selection = getSelection();
365
        Object[] objects = selection.toArray();
366
        for (Object object : objects) {
367
            if(object instanceof CdmBase){
368
                textData += bulkEditor.getEditorInput().getText((CdmBase)object);
369
            }
370
        }
371
        final TextTransfer textTransfer = TextTransfer.getInstance();
372
        final Clipboard clipboard = new Clipboard(Display.getDefault());
373
        try {
374
            clipboard.setContents(new Object[] { textData.toString() },
375
                    new Transfer[] { textTransfer });
376
        } finally {
377
            clipboard.dispose();
378
        }
379
    }
380

  
381
}
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorFocusCellOwnerDrawHighLighter.java
1
// $Id$
2
/**
3
* Copyright (C) 2018 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.taxeditor.bulkeditor.e4;
11

  
12
import org.eclipse.jface.viewers.ColumnViewer;
13
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
14
import org.eclipse.jface.viewers.ViewerCell;
15
import org.eclipse.swt.SWT;
16
import org.eclipse.swt.graphics.Color;
17

  
18
/**
19
 * @author k.luther
20
 * @date 02.03.2018
21
 *
22
 */
23
public class BulkEditorFocusCellOwnerDrawHighLighter extends FocusCellOwnerDrawHighlighter {
24

  
25
    /**
26
     * @param viewer
27
     */
28
    public BulkEditorFocusCellOwnerDrawHighLighter(ColumnViewer viewer) {
29
        super(viewer);
30

  
31
    }
32

  
33

  
34
    /**
35
     * The color to use when rendering the background of the selected cell when
36
     * the control has <b>no</b> input focus
37
     *
38
     * @param cell
39
     *            the cell which is colored
40
     * @return the color or <code>null</code> to use the same used when
41
     *         control has focus
42
     * @since 3.4
43
     */
44
    @Override
45
    protected Color getSelectedCellBackgroundColorNoFocus(ViewerCell cell) {
46
        return cell.getItem().getDisplay().getSystemColor(
47
                SWT.COLOR_LIST_SELECTION);
48
    }
49

  
50
    /**
51
     * The color to use when rendering the foreground (=text) of the selected
52
     * cell when the control has <b>no</b> input focus
53
     *
54
     * @param cell
55
     *            the cell which is colored
56
     * @return the color or <code>null</code> to use the same used when
57
     *         control has focus
58
     * @since 3.4
59
     */
60
    @Override
61
    protected Color getSelectedCellForegroundColorNoFocus(ViewerCell cell) {
62
        return cell.getItem().getDisplay().getSystemColor(
63
                SWT.COLOR_LIST_SELECTION_TEXT);
64
    }
65

  
66

  
67

  
68
}
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelProvider.java
1
// $Id$
2
/**
3
* Copyright (C) 2017 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.taxeditor.bulkeditor.e4;
11

  
12
import java.net.URISyntaxException;
13
import java.net.URL;
14

  
15
import org.eclipse.core.runtime.FileLocator;
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.jface.viewers.ITableLabelProvider;
19
import org.eclipse.jface.viewers.LabelProvider;
20
import org.eclipse.swt.graphics.Image;
21

  
22
import eu.etaxonomy.cdm.model.common.CdmBase;
23
import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
24
import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
25
import eu.etaxonomy.taxeditor.model.ImageResources;
26

  
27
/**
28
 * @author pplitzner
29
 * @date 11.09.2017
30
 *
31
 */
32
public class BulkEditorLabelProvider extends LabelProvider implements ITableLabelProvider{
33

  
34
    private BulkEditorE4 editor;
35

  
36
    public BulkEditorLabelProvider(BulkEditorE4 editor) {
37
        super();
38
        this.editor = editor;
39
    }
40

  
41
    /** {@inheritDoc} */
42
    @Override
43
    public Image getColumnImage(Object element, int columnIndex) {
44
        if (columnIndex == 0) {
45
            AbstractBulkEditorInput input = editor.getEditorInput();
46

  
47
            try {
48
                if(input.getMergeCandidates().contains(element)){
49
                    IPath path = new Path("icons/merge_candidate.gif"); //$NON-NLS-1$
50
                    URL url = FileLocator.find(TaxeditorBulkeditorPlugin.getDefault().getBundle(), path, null);
51
                    return ImageResources.getImage(url.toURI());
52
                }
53
                else if(input.getMergeTarget()!=null && input.getMergeTarget().equals(element)){
54
                    IPath path = new Path("icons/merge_target.gif"); //$NON-NLS-1$
55
                    URL url = FileLocator.find(TaxeditorBulkeditorPlugin.getDefault().getBundle(), path, null);
56
                    return ImageResources.getImage(url.toURI());
57
                }
58
            } catch (URISyntaxException e) {
59
                return null;
60
            }
61
        }
62
        return null;
63
    }
64

  
65
    /** {@inheritDoc} */
66
    @Override
67
    public String getColumnText(Object element, int columnIndex) {
68
        String text = null;
69

  
70
        if (columnIndex == 0) {
71
            if(element instanceof CdmBase){
72
                text = editor.getEditorInput().getText((CdmBase) element);
73
            }
74
        }else if (columnIndex == 1) {
75
            if(editor.getEditorInput().getTypeText(element)!=null){
76
                text = editor.getEditorInput().getTypeText(element);
77
            }
78
        }
79
        return text;
80
    }
81

  
82

  
83
}
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java
53 53
            if(columnIndex==0){
54 54
                return input.getName();
55 55
            }else if(columnIndex==1){
56
                return BulkEditorE4.TYPE_PROPERTY;
56
                return BulkEditorE4Composite.TYPE_PROPERTY;
57 57
            }
58 58
            return null;
59 59
        }
......
63 63
            if(propertyName.equals(input.getName())){
64 64
                return 0;
65 65
            }
66
            else if(propertyName.equals(BulkEditorE4.TYPE_PROPERTY)){
66
            else if(propertyName.equals(BulkEditorE4Composite.TYPE_PROPERTY)){
67 67
                return 1;
68 68
            }
69 69
            return 0;
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearchE4.java
45 45

  
46 46
	private static final String DEFAULT_TEXT = String.format(Messages.BulkEditorSearchE4_WILDCARD, SearchManager.WILDCARD);
47 47

  
48
	private final BulkEditorE4 editor;
48
	private final BulkEditorE4Composite editor;
49 49

  
50 50
	private Text text;
51 51

  
......
54 54

  
55 55
	public Object ORDER_BY = new Object();
56 56

  
57
	public BulkEditorSearchE4(BulkEditorE4 editor, Composite parent, int style) {
57
	public BulkEditorSearchE4(BulkEditorE4Composite editor, Composite parent, int style) {
58 58
		this.editor = editor;
59 59

  
60 60
		createControl(parent, style);
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java
46 46
        int row = this.natTable.getRowPositionByY(event.y);
47 47

  
48 48
        LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row);
49
        if(configLabels.hasLabel(BulkEditorE4.TARGET_LABEL)){
49
        if(configLabels.hasLabel(BulkEditorE4Composite.TARGET_LABEL)){
50 50
            return Messages.BulkEditorTooltip_TARGET;
51 51
        }
52
        else if(configLabels.hasLabel(BulkEditorE4.CANDIDATE_LABEL)){
52
        else if(configLabels.hasLabel(BulkEditorE4Composite.CANDIDATE_LABEL)){
53 53
            return Messages.BulkEditorTooltip_CANDIDATE;
54 54
        }
55 55
        return ""; //$NON-NLS-1$
......
67 67
        int row = this.natTable.getRowPositionByY(event.y);
68 68

  
69 69
        LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row);
70
        if(configLabels.hasLabel(BulkEditorE4.CANDIDATE_LABEL)
71
                || configLabels.hasLabel(BulkEditorE4.TARGET_LABEL)){
70
        if(configLabels.hasLabel(BulkEditorE4Composite.CANDIDATE_LABEL)
71
                || configLabels.hasLabel(BulkEditorE4Composite.TARGET_LABEL)){
72 72
            return true;
73 73
        }
74 74
        return false;
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/LabelStyleConfiguration.java
30 30
                GUIHelper.COLOR_YELLOW);
31 31
        configRegistry.registerConfigAttribute(
32 32
                CellConfigAttributes.CELL_STYLE, cellStyle,
33
                DisplayMode.NORMAL, BulkEditorE4.CANDIDATE_LABEL);
33
                DisplayMode.NORMAL, BulkEditorE4Composite.CANDIDATE_LABEL);
34 34

  
35 35
        cellStyle = new Style();
36 36
        cellStyle.setAttributeValue(
......
38 38
                GUIHelper.COLOR_GREEN);
39 39
        configRegistry.registerConfigAttribute(
40 40
                CellConfigAttributes.CELL_STYLE, cellStyle,
41
                DisplayMode.NORMAL, BulkEditorE4.TARGET_LABEL);
41
                DisplayMode.NORMAL, BulkEditorE4Composite.TARGET_LABEL);
42 42

  
43 43
    }
44 44
}
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java
304 304
	public String getText(T entity) {
305 305
		if(entity instanceof IdentifiableEntity){
306 306
			IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity);
307
			String text = ""; //$NON-NLS-1$
308
			if(markedMergeCandidates.contains(entity)){
309
			    text += Messages.AbstractBulkEditorInput_CANDIDATE;
310
			}
311
			else if(markedMergeTarget==entity){
312
			    text += Messages.AbstractBulkEditorInput_TARGET;
313
			}
314
			text += identifiableEntity.getTitleCache();
307
			String text = identifiableEntity.getTitleCache();
315 308
			return text;
316 309
		}
317 310

  
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java
4 4

  
5 5
public class Messages extends NLS {
6 6
    private static final String BUNDLE_NAME = "src/main/java/eu.etaxonomy.taxeditor.l10n.messages"; //$NON-NLS-1$
7
    public static String AbstractBulkEditorInput_CANDIDATE;
8 7
    public static String AbstractBulkEditorInput_LOADED;
9 8
    public static String AbstractBulkEditorInput_LOADING;
10 9
    public static String AbstractBulkEditorInput_MERGE_ERROR_MESSAGE;
11 10
    public static String AbstractBulkEditorInput_MERGE_ERROR_TITLE;
12
    public static String AbstractBulkEditorInput_TARGET;
13 11
    public static String USER_CREATOR_user_exists_title;
14 12
    public static String USER_CREATOR_user_exists;
15 13
    public static String BulkEditorE4_CANCEL;
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties
1
AbstractBulkEditorInput_CANDIDATE=[Candidate] 
2 1
AbstractBulkEditorInput_LOADED=%s/%s %s loaded
3 2
AbstractBulkEditorInput_LOADING=Loading %s for %s 
4 3
AbstractBulkEditorInput_MERGE_ERROR_MESSAGE=Could not merge chosen objects of type %s
5 4
AbstractBulkEditorInput_MERGE_ERROR_TITLE=Merging failes
6
AbstractBulkEditorInput_TARGET=[Target] 
7 5
BulkEditorE4_CANCEL=Cancel
8 6
BulkEditorE4_DONT_SAVE=Don't save (and Search)
9 7
BulkEditorE4_SAVE_AND_SEARCH=Save (and Search)
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties
1
AbstractBulkEditorInput_CANDIDATE=[Kandidat] 
2 1
AbstractBulkEditorInput_LOADED=%s/%s %s geladen
3 2
AbstractBulkEditorInput_LOADING=Lade %s f?r %s
4 3
AbstractBulkEditorInput_MERGE_ERROR_MESSAGE=Zusammenf?hren von Objekten des Typen %s fehlgeschlagen 
5 4
AbstractBulkEditorInput_MERGE_ERROR_TITLE=Zusammenf?hren fehlgeschlagen
6
AbstractBulkEditorInput_TARGET=[Ziel] 
7 5
BulkEditorE4_CANCEL=Abbrechen
8 6
BulkEditorE4_DONT_SAVE=Nicht speichern (und suchen)
9 7
BulkEditorE4_SAVE_AND_SEARCH=Speichern (und suchen)

Also available in: Unified diff