merge master into develop
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / view / e4 / AbstractCdmEditorPartE4.java
1 /**
2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.taxeditor.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.apache.lucene.search.similarities.Distribution;
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 import org.hibernate.proxy.HibernateProxyHelper;
32
33 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
34 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
35 import eu.etaxonomy.cdm.model.common.CdmBase;
36 import eu.etaxonomy.cdm.model.taxon.Taxon;
37 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
38 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
39 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
40 import eu.etaxonomy.taxeditor.editor.IDistributionEditor;
41 import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
42 import eu.etaxonomy.taxeditor.event.EventUtility;
43 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
44 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
45 import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
46 import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
47 import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
48
49 /**
50 * @author pplitzner
51 * @since Aug 10, 2017
52 *
53 */
54 public abstract class AbstractCdmEditorPartE4
55 implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
56
57 private DelaySelection delaySelection = null;
58 /**
59 * This is the monitor for the DelaySelection runnable.
60 * If it is <code>true</code> then it is currently delaying a selection.
61 */
62 private boolean isInDelay;
63 private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
64
65 /**
66 * This class invokes internal_selectionChanged() in a separate thread.
67 * This allows an asynchronous and/or delayed handling of selection changes
68 */
69 private class DelaySelection implements Runnable{
70 private Object selection;
71 private MPart activePart;
72 private MPart thisPart;
73
74 public DelaySelection(Object selection, MPart activePart, MPart thisPart) {
75 super();
76 this.selection = selection;
77 this.activePart= activePart;
78 this.thisPart = thisPart;
79 }
80
81 @Override
82 public void run() {
83 try{
84 selectionChanged_internal(selection, activePart, thisPart);
85 }
86 finally{
87 isInDelay = false;
88 }
89 }
90
91 public synchronized void setSelection(Object selection) {
92 this.selection = selection;
93 }
94
95 public synchronized void setActivePart(MPart activePart) {
96 this.activePart = activePart;
97 }
98
99 public synchronized void setThisPart(MPart thisPart) {
100 this.thisPart = thisPart;
101 }
102
103 }
104
105 protected Viewer viewer;
106
107 protected MPart thisPart;
108
109 protected MPart selectionProvidingPart;
110
111 protected Object previousSelection;
112
113 protected ISelectionChangedListener selectionChangedListener;
114
115 public ISelectionChangedListener getSelectionChangedListener() {
116 return selectionChangedListener;
117 }
118
119 @Inject
120 protected ESelectionService selService;
121
122 protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
123
124 @Inject
125 public void selectionChanged(
126 @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
127 @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
128 MPart thisPart, UISynchronize sync, EPartService partService){
129 if(activePart==thisPart && EventUtility.getActiveEditorPart(partService)==null){
130 showEmptyPage();
131 return;
132 }
133 if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
134 try{
135 viewer.getControl().setEnabled(true);
136 }catch(SWTException e){
137 logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
138 }
139
140 }
141
142
143 if(previousSelection==null ||
144 previousSelection!=selection){//skip redundant rendering of details view
145 if(delaySelection==null){
146 delaySelection = new DelaySelection(selection, activePart, thisPart);
147 }
148 delaySelection.setSelection(selection);
149 delaySelection.setActivePart(activePart);
150 delaySelection.setThisPart(thisPart);
151 if(!isInDelay){
152 isInDelay = true;
153 sync.asyncExec(delaySelection);
154 previousSelection = selection;
155 }
156 }
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public void changed(Object object) {
162 if(selectionProvidingPart!=null){
163 Object part = selectionProvidingPart.getObject();
164 if(part instanceof IDirtyMarkable){
165 ((IDirtyMarkable) part).changed(object);
166 }
167 }
168 }
169
170 public Viewer getViewer() {
171 return viewer;
172 }
173
174 protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
175 if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
176 Object element = selection.getFirstElement();
177 Object part = createPartObject(activePart);
178 viewer.getControl().setEnabled(true);
179 if(selection.getFirstElement()!=null){
180 if (element instanceof Taxon){
181 Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
182 if (taxon.isMisapplication()){
183
184 if(part instanceof ITaxonEditor){
185 Taxon accepted = ((ITaxonEditor) part).getTaxon();
186
187 // Taxon accepted= ((ITaxonEditor)activePart).getTaxon();
188 Set<TaxonRelationship> rels = taxon.getTaxonRelations(accepted);
189
190 if (rels.iterator().hasNext()){
191 TaxonRelationship rel = rels.iterator().next();
192 if (rel.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
193 viewer.setInput(rel);
194
195 return;
196 }
197 }
198 }
199
200
201 }
202 }
203 if (element instanceof Distribution && part instanceof IDistributionEditor){
204 ((DetailsViewerE4)viewer).setInput(element, part);
205 }else{
206 viewer.setInput(element);
207 }
208 selectionProvidingPart = activePart;
209 }
210 }
211 }
212
213 protected Object createPartObject(MPart activePart) {
214 Object partObject = activePart;
215 Object wrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
216 if(wrappedPart!=null){
217 partObject = wrappedPart;
218 }
219 return partObject;
220 }
221
222 protected void showEmptyPage() {
223 if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
224 viewer.setInput(null);
225 viewer.getControl().setEnabled(false);
226 }
227 selectionProvidingPart = null;
228 if(thisPart!=null){
229 thisPart.setLabel(getViewName());
230 }
231 }
232
233 protected IStructuredSelection createSelection(Object selection) {
234 if(selection==null){
235 return null;
236 }
237 IStructuredSelection structuredSelection;
238 if(!(selection instanceof IStructuredSelection)){
239 structuredSelection = new StructuredSelection(selection);
240 }
241 else{
242 structuredSelection = (IStructuredSelection) selection;
243 }
244 return structuredSelection;
245 }
246
247 /**
248 * {@inheritDoc}
249 */
250 @Override
251 public ConversationHolder getConversationHolder() {
252 if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
253 return ((IConversationEnabled) selectionProvidingPart).getConversationHolder();
254 }
255 return null;
256 }
257
258 /**
259 * {@inheritDoc}
260 */
261 @Override
262 public boolean postOperation(CdmBase objectAffectedByOperation) {
263 changed(objectAffectedByOperation);
264 return true;
265 }
266
267 /**
268 * {@inheritDoc}
269 */
270 @Override
271 public boolean onComplete() {
272 viewer.refresh();
273 return true;
274 }
275
276 /**
277 * {@inheritDoc}
278 */
279 @Override
280 public Object getSelectionProvidingPart() {
281 return selectionProvidingPart;
282 }
283
284 @PreDestroy
285 private void dispose() {
286 }
287
288 @PersistState
289 private void persistState(){
290
291 }
292
293 /**
294 * {@inheritDoc}
295 */
296 @Override
297 public void update(CdmDataChangeMap arg0) {
298 }
299
300 /**
301 * {@inheritDoc}
302 */
303 @Override
304 public void forceDirty() {
305 }
306
307 protected abstract String getViewName();
308
309 }