07e7b7798b2b9c272654f95dbc15686a02402f3f
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / editor / definedterm / e4 / DefinedTermEditorE4.java
1 /**
2 * Copyright (C) 2009 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.editor.definedterm.e4;
10
11 import java.util.HashSet;
12 import java.util.Set;
13
14 import javax.annotation.PostConstruct;
15 import javax.annotation.PreDestroy;
16 import javax.inject.Inject;
17
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.e4.core.contexts.ContextInjectionFactory;
20 import org.eclipse.e4.core.contexts.IEclipseContext;
21 import org.eclipse.e4.ui.di.Focus;
22 import org.eclipse.e4.ui.di.Persist;
23 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
24 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
25 import org.eclipse.e4.ui.services.EMenuService;
26 import org.eclipse.e4.ui.workbench.modeling.EPartService;
27 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
28 import org.eclipse.jface.util.LocalSelectionTransfer;
29 import org.eclipse.jface.viewers.ISelectionChangedListener;
30 import org.eclipse.jface.viewers.StructuredSelection;
31 import org.eclipse.jface.viewers.TreeViewer;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.dnd.DND;
34 import org.eclipse.swt.dnd.Transfer;
35 import org.eclipse.swt.layout.FillLayout;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Tree;
38 import org.eclipse.ui.IMemento;
39
40 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
41 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
42 import eu.etaxonomy.cdm.api.service.ITermService;
43 import eu.etaxonomy.cdm.api.service.IVocabularyService;
44 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
45 import eu.etaxonomy.cdm.model.term.TermBase;
46 import eu.etaxonomy.cdm.model.term.TermVocabulary;
47 import eu.etaxonomy.cdm.persistence.dto.TermDto;
48 import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
49 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
50 import eu.etaxonomy.taxeditor.editor.definedterm.DefinedTermSorter;
51 import eu.etaxonomy.taxeditor.editor.definedterm.TermDtoContentProvider;
52 import eu.etaxonomy.taxeditor.editor.definedterm.TermDtoLabelProvider;
53 import eu.etaxonomy.taxeditor.editor.definedterm.input.TermEditorInput;
54 import eu.etaxonomy.taxeditor.event.EventUtility;
55 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
56 import eu.etaxonomy.taxeditor.model.IContextListener;
57 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
58 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
59 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
60 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
61 import eu.etaxonomy.taxeditor.store.AppModelId;
62 import eu.etaxonomy.taxeditor.store.CdmStore;
63 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
64 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
65
66 /**
67 *
68 * @author pplitzner
69 * @since Aug 22, 2017
70 *
71 */
72 public class DefinedTermEditorE4 implements IConversationEnabled, IDirtyMarkable, IPostOperationEnabled,
73 IPartContentHasDetails, IPartContentHasSupplementalData, IE4SavablePart, IContextListener {
74
75 public static final String OPEN_COMMAND_ID = "eu.etaxonomy.taxeditor.store.openDefinedTermEditor"; //$NON-NLS-1$
76
77 protected TreeViewer viewer;
78
79 protected ConversationHolder conversation;
80
81 @Inject
82 private ESelectionService selService;
83
84 @Inject
85 private MDirtyable dirty;
86
87 private ISelectionChangedListener selectionChangedListener;
88 private final int dndOperations = DND.DROP_COPY | DND.DROP_MOVE;
89
90 private TermEditorInput input =null;
91
92 @Inject
93 private MPart thisPart;
94
95 private Set<TermBase> changedTerms = new HashSet<>();
96
97 @Inject
98 public DefinedTermEditorE4() {
99 CdmStore.getContextManager().addContextListener(this);
100 }
101
102 @PostConstruct
103 public void createPartControl(Composite parent, EMenuService menuService,
104 IEclipseContext context) {
105 if (CdmStore.isActive()){
106 if(conversation == null){
107 conversation = CdmStore.createConversation();
108 }
109 }
110 else{
111 return;
112 }
113 FillLayout layout = new FillLayout();
114 layout.marginHeight = 0;
115 layout.marginWidth = 0;
116 layout.type = SWT.VERTICAL;
117
118 parent.setLayout(layout);
119 viewer = new TreeViewer(new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI));
120 viewer.getControl().setLayoutData(LayoutConstants.FILL());
121 viewer.setContentProvider(new TermDtoContentProvider());
122 viewer.setLabelProvider(new TermDtoLabelProvider());
123 viewer.setComparator(new DefinedTermSorter());
124
125 Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
126 viewer.addDragSupport(dndOperations, transfers, new DefinedTermDragListenerE4(viewer));
127 DefinedTermDropAdapterE4 dropListener = new DefinedTermDropAdapterE4(this);
128 ContextInjectionFactory.inject(dropListener, context);
129 viewer.addDropSupport(dndOperations, transfers, dropListener);
130
131 //propagate selection
132 selectionChangedListener = (event -> selService.setSelection(event.getSelection()));
133 viewer.addSelectionChangedListener(selectionChangedListener);
134
135 //create context menu
136 menuService.registerContextMenu(viewer.getControl(), AppModelId.POPUPMENU_EU_ETAXONOMY_TAXEDITOR_STORE_POPUPMENU_TERMEDITOR);
137
138 }
139
140 @Override
141 public boolean postOperation(Object objectAffectedByOperation) {
142 if(objectAffectedByOperation instanceof TermVocabularyDto
143 || objectAffectedByOperation instanceof TermVocabulary){
144 input.initialiseVocabularies();
145 }
146 if(objectAffectedByOperation instanceof TermDto){
147 viewer.refresh(((TermDto) objectAffectedByOperation).getVocabularyDto());
148 }
149 else{
150 viewer.refresh(objectAffectedByOperation);
151 }
152 if(objectAffectedByOperation != null){
153 StructuredSelection selection = new StructuredSelection(objectAffectedByOperation);
154 viewer.setSelection(selection);
155 viewer.expandToLevel(objectAffectedByOperation, 1);
156 }
157 return true;
158 }
159
160 public void init(TermEditorInput input){
161 this.input = input;
162
163 viewer.setInput(input.getVocabularies());
164 thisPart.setLabel(input.getName());
165 }
166
167 @Override
168 @Persist
169 public void save(IProgressMonitor monitor) {
170 getConversationHolder().commit();
171 for(TermBase term:changedTerms){
172 if(term.isInstanceOf(DefinedTermBase.class)){
173 DefinedTermBase definedTermBase = (DefinedTermBase) term;
174 CdmStore.getService(ITermService.class).merge(definedTermBase);
175 viewer.refresh(TermDto.fromTerm(definedTermBase));
176 }
177 else if(term.isInstanceOf(TermVocabulary.class)){
178 TermVocabulary voc = (TermVocabulary) term;
179 CdmStore.getService(IVocabularyService.class).merge(voc);
180 viewer.refresh(new TermVocabularyDto(voc.getUuid(), voc.getRepresentations(), voc.getTermType()));
181 }
182 }
183 setDirty(false);
184 input.initialiseVocabularies();
185 changedTerms.clear();
186 EventUtility.postEvent(WorkbenchEventConstants.REFRESH_SUPPLEMENTAL, true);
187 }
188
189 @Override
190 public boolean isDirty() {
191 return dirty.isDirty();
192 }
193
194 @Focus
195 public void setFocus() {
196 if(viewer!=null && viewer.getControl() != null && !viewer.getControl().isDisposed()){
197 viewer.getControl().setFocus();
198 }
199 if(conversation!=null){
200 conversation.bind();
201 }
202 if(input!=null){
203 input.bind();
204 }
205 }
206
207 @Override
208 public void update(CdmDataChangeMap changeEvents) {
209 }
210
211 @Override
212 public ConversationHolder getConversationHolder() {
213 return conversation;
214 }
215
216 @Override
217 public void changed(Object element) {
218 if(element instanceof DefinedTermBase){
219 DefinedTermBase definedTermBase = (DefinedTermBase) element;
220 TermDto termDto = TermDto.fromTerm(definedTermBase);
221 viewer.update(termDto, null);
222 changedTerms.add(definedTermBase);
223 }
224 else if(element instanceof TermVocabulary){
225 TermVocabulary vocabulary = (TermVocabulary)element;
226 TermVocabularyDto vocabularyDto = new TermVocabularyDto(vocabulary.getUuid(), vocabulary.getRepresentations(), vocabulary.getTermType());
227 viewer.update(vocabularyDto, null);
228 changedTerms.add(vocabulary);
229 }
230 setDirty(true);
231 viewer.update(element, null);
232 }
233
234 @Override
235 public void forceDirty() {
236 changed(null);
237 }
238
239 public void setDirty(boolean dirty) {
240 this.dirty.setDirty(dirty);
241 }
242
243 @Override
244 public boolean onComplete() {
245 return false;
246 }
247
248 public TreeViewer getViewer() {
249 return viewer;
250 }
251
252 @PreDestroy
253 public void dispose() {
254 if(conversation!=null){
255 conversation.unregisterForDataStoreChanges(this);
256 conversation.close();
257 conversation = null;
258 }
259 if(input!=null){
260 input.dispose();
261 }
262 this.dirty.setDirty(false);
263 }
264
265 public TermEditorInput getDefinedTermEditorInput() {
266 return input;
267 }
268
269 @Override
270 public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
271 }
272
273 @Override
274 public void contextStop(IMemento memento, IProgressMonitor monitor) {
275 //close view when workbench closes
276 try{
277 thisPart.getContext().get(EPartService.class).hidePart(thisPart);
278 }
279 catch(Exception e){
280 //nothing
281 }
282 }
283
284 @Override
285 public void contextStart(IMemento memento, IProgressMonitor monitor) {
286 }
287
288 @Override
289 public void contextRefresh(IProgressMonitor monitor) {
290 }
291
292 @Override
293 public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
294 }
295
296 }