Merge branch 'release/5.19.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / key / polytomous / e4 / PolytomousKeyViewPartE4.java
1 /**
2 * Copyright (C) 2007 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.navigation.key.polytomous.e4;
10
11 import java.util.List;
12 import java.util.Map;
13
14 import javax.annotation.PostConstruct;
15 import javax.annotation.PreDestroy;
16 import javax.inject.Inject;
17
18 import org.eclipse.core.commands.Command;
19 import org.eclipse.core.commands.ParameterizedCommand;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.e4.core.commands.ECommandService;
22 import org.eclipse.e4.core.commands.EHandlerService;
23 import org.eclipse.e4.ui.di.Focus;
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.ESelectionService;
28 import org.eclipse.jface.viewers.ColumnLabelProvider;
29 import org.eclipse.jface.viewers.DoubleClickEvent;
30 import org.eclipse.jface.viewers.IDoubleClickListener;
31 import org.eclipse.jface.viewers.ISelection;
32 import org.eclipse.jface.viewers.ISelectionChangedListener;
33 import org.eclipse.jface.viewers.ListViewer;
34 import org.eclipse.jface.viewers.Viewer;
35 import org.eclipse.jface.viewers.ViewerFilter;
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.events.ModifyEvent;
38 import org.eclipse.swt.events.ModifyListener;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Composite;
42 import org.eclipse.swt.widgets.Display;
43 import org.eclipse.swt.widgets.Event;
44 import org.eclipse.swt.widgets.Text;
45 import org.eclipse.ui.IMemento;
46
47 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
48 import eu.etaxonomy.cdm.api.application.CdmChangeEvent;
49 import eu.etaxonomy.cdm.api.application.CdmChangeEvent.Action;
50 import eu.etaxonomy.cdm.api.application.ICdmChangeListener;
51 import eu.etaxonomy.cdm.api.application.ICdmDataChangeService;
52 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
53 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
54 import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
55 import eu.etaxonomy.cdm.model.description.PolytomousKey;
56 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
57 import eu.etaxonomy.taxeditor.model.ContextListenerAdapter;
58 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
59 import eu.etaxonomy.taxeditor.model.IContextListener;
60 import eu.etaxonomy.taxeditor.model.MessagingUtils;
61 import eu.etaxonomy.taxeditor.navigation.key.polytomous.PolytomousKeyContentProvider;
62 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
63 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
64 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
65 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
66 import eu.etaxonomy.taxeditor.store.CdmStore;
67 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
68
69 /**
70 * @author pplitzner
71 * @since Sep 28, 2017
72 */
73 public class PolytomousKeyViewPartE4 implements
74 IConversationEnabled, ICdmEntitySessionEnabled<PolytomousKey>, IPostOperationEnabled,
75 ICdmChangeListener {
76
77 private class FilterModifyListener implements ModifyListener{
78 @Override
79 public void modifyText(ModifyEvent e) {
80 ViewerFilter filter = new ViewerFilter(){
81
82 @Override
83 public boolean select(Viewer viewer, Object parentElement,
84 Object element) {
85
86 if(element instanceof PolytomousKey){
87 PolytomousKey key = (PolytomousKey) element;
88 if(key.getTitleCache().contains(text_filter.getText())){
89 return true;
90 }
91 }
92
93 return false;
94 }
95
96 };
97
98 viewer.setFilters(new ViewerFilter[]{filter});
99 }
100 }
101
102 public static final String ID = "eu.etaxonomy.taxeditor.navigation.key.polytomous.polytomousKeyViewPart"; //$NON-NLS-1$
103
104 public static final String OPEN_COMMAND_ID = "eu.etaxonomy.taxeditor.navigation.key.polytomous.editNodes"; //$NON-NLS-1$
105
106 private class ContextListener extends ContextListenerAdapter{
107 @Override
108 public void contextStop(IMemento memento, IProgressMonitor monitor) {
109 monitor.subTask(Messages.PolytomousKeyViewPart_SHUTDOWN);
110 if(!viewer.getControl().isDisposed()){
111 viewer.setInput(null);
112 }
113 }
114
115 @Override
116 public void contextStart(IMemento memento, IProgressMonitor monitor) {
117 monitor.subTask(Messages.PolytomousKeyViewPart_INIT);
118 setInput();
119 }
120 }
121
122 private ListViewer viewer;
123 private ConversationHolder conversation;
124 private IContextListener contextListener;
125 private final CdmFormFactory formFactory;
126 private Text text_filter;
127 private ICdmEntitySession cdmEntitySession;
128
129 private PolytomousKeyViewPartDataChangeBehaviorE4 dataChangeBehavior;
130
131
132 @Inject
133 private EHandlerService handlerService;
134
135 @Inject
136 private ECommandService commandService;
137
138 @Inject
139 private ESelectionService selService;
140
141 @Inject
142 private MDirtyable dirty;
143
144 private ISelectionChangedListener selectionChangedListener;
145
146 @Inject
147 private MPart thisPart;
148
149 public PolytomousKeyViewPartE4(){
150 formFactory = new CdmFormFactory(Display.getDefault());
151 }
152
153 @PostConstruct
154 public void createPartControl(Composite parent, EMenuService menuService) {
155
156 Composite container = new Composite(parent, SWT.NONE);
157 container.setLayout(new GridLayout());
158
159 contextListener = new ContextListener();
160 CdmStore.getContextManager().addContextListener(contextListener);
161
162 text_filter = formFactory.createText(container, ""); //$NON-NLS-1$
163 text_filter.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
164 text_filter.addModifyListener(new FilterModifyListener());
165
166 viewer = new ListViewer(container, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
167 viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
168
169 viewer.setContentProvider(new PolytomousKeyContentProvider());
170 viewer.setLabelProvider(new ColumnLabelProvider());
171
172 viewer.addDoubleClickListener(new IDoubleClickListener() {
173
174 @Override
175 public void doubleClick(DoubleClickEvent event) {
176 openSelectedKeyNodes();
177 }
178 });
179
180 //propagate selection
181 selectionChangedListener = (event -> selService.setSelection(event.getSelection()));
182 viewer.addSelectionChangedListener(selectionChangedListener);
183
184 //create context menu
185 menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.navigation.popupmenu.polytomouskeyview");
186
187 if(CdmStore.isActive()){
188 setInput();
189 }
190 }
191
192 public void openSelectedKeyNodes() {
193 Command command = commandService.getCommand(OPEN_COMMAND_ID);
194 ParameterizedCommand parameterizedCommand = ParameterizedCommand.generateCommand(command, null);
195 if(command.isEnabled()) {
196 try {
197 handlerService.executeHandler(parameterizedCommand);
198 } catch (Exception e) {
199 MessagingUtils.error(getClass(), Messages.PolytomousKeyViewPart_EXCEPTION, e);
200 }
201 }
202 }
203
204 public void setViewerSelection(ISelection selection, boolean reveal) {
205 viewer.setSelection(selection,reveal);
206 viewer.getList().notifyListeners(SWT.Selection,new Event());
207 }
208
209 private void setInput() {
210 conversation = CdmStore.createConversation();
211 conversation.registerForDataStoreChanges(this);
212 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
213 CdmApplicationState.getCurrentDataChangeService().register(this);
214
215 List<PolytomousKey> input = CdmStore.getService(IPolytomousKeyService.class).list(PolytomousKey.class, null, null, null, null);
216 if(!viewer.getControl().isDisposed()){
217 viewer.setInput(input);
218 }
219 }
220
221 @Focus
222 public void setFocus() {
223 if(cdmEntitySession != null) {
224 cdmEntitySession.bind();
225 }
226 if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()) {
227 viewer.getControl().setFocus();
228 }
229 }
230
231 @Override
232 public void update(CdmDataChangeMap changeEvents) {
233 if (dataChangeBehavior == null) {
234 dataChangeBehavior = new PolytomousKeyViewPartDataChangeBehaviorE4(this);
235 }
236
237 DataChangeBridge.handleDataChange(changeEvents, dataChangeBehavior);
238 }
239
240 @Override
241 public ConversationHolder getConversationHolder() {
242 return conversation;
243 }
244
245 @PreDestroy
246 public void dispose() {
247 if(conversation!=null){
248 conversation.unregisterForDataStoreChanges(this);
249 conversation.close();
250 CdmStore.getContextManager().removeContextListener(contextListener);
251 conversation = null;
252 }
253 if(cdmEntitySession != null) {
254 cdmEntitySession.dispose();
255 cdmEntitySession = null;
256 }
257 ICdmDataChangeService currentDataChangeService = CdmApplicationState.getCurrentDataChangeService();
258 if(currentDataChangeService!=null){
259 currentDataChangeService.unregister(this);
260 }
261 }
262
263 @Override
264 public boolean postOperation(Object objectAffectedByOperation) {
265 getConversationHolder().bind();
266 getConversationHolder().commit(true);
267 viewer.refresh();
268 return true;
269 }
270
271 @Override
272 public boolean onComplete() {
273 return true;
274 }
275
276 public void refresh() {
277 getConversationHolder().bind();
278 //FIXME : Need to make sure this is a stable fix (ticket 3822)
279 getConversationHolder().commit();
280 List<PolytomousKey> input = CdmStore.getService(IPolytomousKeyService.class).list(PolytomousKey.class, null, null, null, null);
281 if(!viewer.getControl().isDisposed()){
282 viewer.setInput(input);
283 }
284 }
285
286 public List<PolytomousKey> getKeys() {
287 return (List<PolytomousKey>)viewer.getInput();
288 }
289
290 @Override
291 public ICdmEntitySession getCdmEntitySession() {
292 return cdmEntitySession;
293 }
294
295 @Override
296 public List<PolytomousKey> getRootEntities() {
297 return getKeys();
298 }
299
300 @Override
301 public void onChange(CdmChangeEvent event) {
302 if(event.getAction() == Action.Delete && PolytomousKey.class.equals(event.getEntityType())) {
303 refresh();
304 }
305 }
306
307 @Override
308 public Map<Object, List<String>> getPropertyPathsMap() {
309 return null;
310 }
311 }