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