Project

General

Profile

Download (12.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.view.e4;
10

    
11
import java.util.Set;
12

    
13
import javax.annotation.PreDestroy;
14
import javax.inject.Inject;
15
import javax.inject.Named;
16

    
17
import org.apache.log4j.Logger;
18
import org.eclipse.e4.core.contexts.IEclipseContext;
19
import org.eclipse.e4.core.di.annotations.Optional;
20
import org.eclipse.e4.ui.di.PersistState;
21
import org.eclipse.e4.ui.di.UISynchronize;
22
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
23
import org.eclipse.e4.ui.services.IServiceConstants;
24
import org.eclipse.e4.ui.workbench.modeling.EPartService;
25
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
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.jface.viewers.Viewer;
30
import org.eclipse.swt.SWTException;
31

    
32
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
33
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
34
import eu.etaxonomy.cdm.api.service.ITermService;
35
import eu.etaxonomy.cdm.api.service.IVocabularyService;
36
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.taxon.Taxon;
39
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
40
import eu.etaxonomy.cdm.persistence.dto.TermDto;
41
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
42
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
43
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
44
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
45
import eu.etaxonomy.taxeditor.model.MessagingUtils;
46
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
47
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
48
import eu.etaxonomy.taxeditor.store.CdmStore;
49
import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
50
import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
51
import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
52
import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
53

    
54
/**
55
 * @author pplitzner
56
 * @since Aug 10, 2017
57
 *
58
 */
59
public abstract class AbstractCdmEditorPartE4
60
        implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
61

    
62
    private DelaySelection delaySelection = null;
63
    /**
64
     * This is the monitor for the DelaySelection runnable.
65
     * If it is <code>true</code> then it is currently delaying a selection.
66
     */
67
    private boolean isInDelay;
68
    private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
69

    
70
    /**
71
     * This class invokes internal_selectionChanged() in a separate thread.
72
     * This allows an asynchronous and/or delayed handling of selection changes
73
     */
74
    private class DelaySelection implements Runnable{
75
        private Object selection;
76
        private MPart activePart;
77
        private MPart thisPart;
78

    
79
        public DelaySelection(Object selection, MPart activePart, MPart thisPart) {
80
            super();
81
            this.selection = selection;
82
            this.activePart= activePart;
83
            this.thisPart = thisPart;
84
        }
85

    
86
        @Override
87
        public void run() {
88
            try{
89
                selectionChanged_internal(selection, activePart, thisPart);
90
            }
91
            finally{
92
                isInDelay = false;
93
            }
94
        }
95

    
96
        public synchronized void setSelection(Object selection) {
97
            this.selection = selection;
98
        }
99

    
100
        public synchronized void setActivePart(MPart activePart) {
101
            this.activePart = activePart;
102
        }
103

    
104
        public synchronized void setThisPart(MPart thisPart) {
105
            this.thisPart = thisPart;
106
        }
107

    
108
    }
109

    
110
    protected Viewer viewer;
111

    
112
    protected MPart thisPart;
113

    
114
    protected MPart selectionProvidingPart;
115

    
116
    protected Object previousSelection;
117

    
118
    protected ISelectionChangedListener selectionChangedListener;
119

    
120
    public ISelectionChangedListener getSelectionChangedListener() {
121
        return selectionChangedListener;
122
    }
123

    
124
    @Inject
125
    protected ESelectionService selService;
126

    
127
    @Inject
128
    protected IEclipseContext context;
129

    
130
    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
131

    
132
    @Inject
133
    public void selectionChanged(
134
            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
135
            @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
136
            MPart thisPart, UISynchronize sync, EPartService partService){
137
        //multiple selections are not supported
138
        if(activePart!=null
139
                && thisPart!=null
140
                && !activePart.equals(thisPart)
141
                && selection instanceof IStructuredSelection
142
                && ((IStructuredSelection) selection).size()>1){
143
            showEmptyPage();
144
            return;
145
        }
146
        // no active editor found
147
        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null){
148
            showEmptyPage();
149
            return;
150
        }
151
        if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
152
           try{
153
               viewer.getControl().setEnabled(true);
154
           }catch(SWTException e){
155
              logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
156
           }
157

    
158
        }
159

    
160
        if((previousSelection!=null && selection!=null) && (activePart != null &&  selectionProvidingPart != null && activePart.equals(selectionProvidingPart)) &&
161
                (previousSelection==selection
162
                || previousSelection.equals(selection)
163
                || new StructuredSelection(selection).equals(previousSelection))
164
                ) {
165
            return;
166
        }
167
        if(delaySelection==null){
168
            delaySelection = new DelaySelection(selection, activePart, thisPart);
169
        }
170
        delaySelection.setSelection(selection);
171
        delaySelection.setActivePart(activePart);
172
        delaySelection.setThisPart(thisPart);
173
        if(!isInDelay){
174
            isInDelay = true;
175
            sync.asyncExec(delaySelection);
176
            previousSelection = selection;
177
        }
178
    }
179

    
180
    /** {@inheritDoc} */
181
    @Override
182
    public void changed(Object object) {
183
        if(selectionProvidingPart!=null){
184
            Object part = selectionProvidingPart.getObject();
185
            if(part instanceof IDirtyMarkable){
186
                ((IDirtyMarkable) part).changed(object);
187
            }
188
        }
189
    }
190

    
191
    public Viewer getViewer() {
192
        return viewer;
193
    }
194

    
195
    protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
196
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
197
            Object element = selection.getFirstElement();
198
            Object part = createPartObject(activePart);
199
            viewer.getControl().setEnabled(true);
200
            if(selection.getFirstElement()!=null){
201
                if (element instanceof Taxon){
202
                    Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
203
                    if (taxon.isMisapplication() || taxon.isProparteSynonym() || taxon.isInvalidDesignation()){
204

    
205
                        if(part instanceof ITaxonEditor){
206
                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
207
                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
208

    
209
                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
210
                                TaxonRelationship rel = rels.iterator().next();
211
                                if ((rel.getType().isMisappliedNameOrInvalidDesignation() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
212
                                    viewer.setInput(rel);
213
                                    selectionProvidingPart = activePart;
214
                                    return;
215
                                }
216
                            }
217
                        }
218

    
219

    
220
                    }
221
                }
222
                //unwrap term DTOs
223
                if(element instanceof TermDto){
224
                    element = CdmStore.getService(ITermService.class).load(((TermDto) element).getUuid());
225
                }
226
                else if(element instanceof TermVocabularyDto){
227
                    element = CdmStore.getService(IVocabularyService.class).load(((TermVocabularyDto) element).getUuid());
228
                }
229

    
230
                selectionProvidingPart = activePart;
231
                if (viewer instanceof DetailsViewerE4){
232
                    ((DetailsViewerE4)viewer).setInput(element, part);
233
                    ((DetailsViewerE4)viewer).setDetailsEnabled(true);
234

    
235
                }
236

    
237
                else{
238
                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
239
                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
240
                    }
241
                    viewer.setInput(element);
242
                }
243
            }
244
        }
245
    }
246

    
247
    protected Object createPartObject(MPart activePart) {
248
        Object partObject = activePart;
249
        Object wrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
250
        if(wrappedPart!=null){
251
            partObject = wrappedPart;
252
        }
253
        return partObject;
254
    }
255

    
256
    protected void showEmptyPage() {
257
        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
258
            viewer.setInput(null);
259
            try{
260
	            if (!viewer.getControl().isDisposed()){
261
	                viewer.getControl().setEnabled(false);
262
	            }
263
            }catch(SWTException e){
264
            	if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
265
                    MessagingUtils.errorDialog("Widget is disposed",
266
                            null,
267
                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
268
                            null,
269
                            e,
270
                            true);
271

    
272
                }
273
            }
274

    
275
        }
276
        reset();
277
        if(thisPart!=null){
278
            thisPart.setLabel(getViewName());
279
        }
280
    }
281

    
282
    protected IStructuredSelection createSelection(Object selection) {
283
        if(selection==null){
284
            return null;
285
        }
286
        IStructuredSelection structuredSelection;
287
        if(!(selection instanceof IStructuredSelection)){
288
            structuredSelection = new StructuredSelection(selection);
289
        }
290
        else{
291
            structuredSelection = (IStructuredSelection) selection;
292
        }
293
        return structuredSelection;
294
    }
295

    
296
    /**
297
     * {@inheritDoc}
298
     */
299
    @Override
300
    public ConversationHolder getConversationHolder() {
301
        if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
302
            return ((IConversationEnabled) selectionProvidingPart).getConversationHolder();
303
        }
304
        return null;
305
    }
306

    
307
    /**
308
     * {@inheritDoc}
309
     */
310
    @Override
311
    public boolean postOperation(Object objectAffectedByOperation) {
312
        changed(objectAffectedByOperation);
313
        return true;
314
    }
315

    
316
    /**
317
     * {@inheritDoc}
318
     */
319
    @Override
320
    public boolean onComplete() {
321
        viewer.refresh();
322
        return true;
323
    }
324

    
325
    /**
326
     * {@inheritDoc}
327
     */
328
    @Override
329
    public MPart getSelectionProvidingPart() {
330
        return selectionProvidingPart;
331
    }
332

    
333
    @PreDestroy
334
    private void dispose() {
335
    }
336

    
337
    private void reset(){
338
        previousSelection = null;
339
        selectionProvidingPart = null;
340
        delaySelection = null;
341
        context.deactivate();
342
    }
343

    
344
    @PersistState
345
    private void persistState(){
346

    
347
    }
348

    
349
    /**
350
     * {@inheritDoc}
351
     */
352
    @Override
353
    public void update(CdmDataChangeMap arg0) {
354
    }
355

    
356
    /**
357
     * {@inheritDoc}
358
     */
359
    @Override
360
    public void forceDirty() {
361
    }
362

    
363
    protected abstract String getViewName();
364

    
365
}
(2-2/2)