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