ref #6990, #6932 Fix exception when opening orphaned taxon in bulkeditor
[taxeditor.git] / eu.etaxonomy.taxeditor.bulkeditor / src / main / java / eu / etaxonomy / taxeditor / bulkeditor / e4 / BulkEditorE4.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
10 package eu.etaxonomy.taxeditor.bulkeditor.e4;
11
12 import java.util.List;
13
14 import javax.annotation.PostConstruct;
15 import javax.inject.Inject;
16
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.NullProgressMonitor;
19 import org.eclipse.e4.ui.di.Persist;
20 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
21 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
22 import org.eclipse.e4.ui.services.EMenuService;
23 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
24 import org.eclipse.jface.dialogs.MessageDialog;
25 import org.eclipse.jface.viewers.ArrayContentProvider;
26 import org.eclipse.jface.viewers.CellEditor;
27 import org.eclipse.jface.viewers.ICellModifier;
28 import org.eclipse.jface.viewers.ISelectionChangedListener;
29 import org.eclipse.jface.viewers.ITableLabelProvider;
30 import org.eclipse.jface.viewers.TableViewer;
31 import org.eclipse.jface.viewers.TableViewerColumn;
32 import org.eclipse.jface.viewers.TextCellEditor;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.layout.FillLayout;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.layout.GridLayout;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Table;
39
40 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
41 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
42 import eu.etaxonomy.cdm.model.common.CdmBase;
43 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
44 import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
45 import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
46 import eu.etaxonomy.taxeditor.l10n.Messages;
47 import eu.etaxonomy.taxeditor.model.AbstractUtility;
48 import eu.etaxonomy.taxeditor.model.IDerivedUnitFacadePart;
49 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
50 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
51 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
52 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
53 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
54 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
55 import eu.etaxonomy.taxeditor.store.CdmStore;
56 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
57
58 /**
59 *
60 * @author pplitzner
61 * @since Sep 8, 2017
62 *
63 */
64 public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnabled, IPostOperationEnabled,
65 IDirtyMarkable, IDerivedUnitFacadePart, IPartContentHasFactualData,
66 IPartContentHasSupplementalData, IPartContentHasMedia, IE4SavablePart {
67
68 @Inject
69 private MDirtyable dirty;
70
71 private AbstractBulkEditorInput<?> input;
72
73 private Composite topComposite;
74
75 private TableViewer viewer;
76
77 private ConversationHolder conversation;
78
79 @Inject
80 private ESelectionService selService;
81
82 private ISelectionChangedListener selectionChangedListener;
83
84 @Inject
85 private MPart thisPart;
86
87 @Inject
88 public BulkEditorE4() {
89 }
90
91 public void init(AbstractBulkEditorInput<?> input){
92 this.input = input;
93 AbstractBulkEditorInput<?> bulkEditorInput = input;
94 BulkEditorSearchE4 searchBar = new BulkEditorSearchE4(this, topComposite, SWT.NONE);
95 //layout needed because the search bar is added after @PostConstuct method
96 topComposite.getParent().layout();
97
98 thisPart.setLabel(input.getName());
99
100 //create columns
101 Table table = viewer.getTable();
102 String[] titles = {input.getName(), "Type"};
103 int[] bounds = {500, 100};
104
105 CellEditor[] editors = new CellEditor[titles.length];
106 for (int i = 0; i < titles.length; i++) {
107 TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
108 editors[i] = new TextCellEditor(table);
109 column.getColumn().setText(titles[i]);
110 column.getColumn().setWidth(bounds[i]);
111 column.getColumn().setResizable(true);
112 column.getColumn().setMoveable(true);
113 }
114 table.setHeaderVisible(true);
115 table.setLinesVisible(true);
116 viewer.setCellEditors(editors);
117 viewer.setColumnProperties(titles);
118
119 //content and label provider (NOTE: has to be set AFTER creating cell editors
120 viewer.setContentProvider(new ArrayContentProvider());
121 BulkEditorLabelProvider labelProvider = new BulkEditorLabelProvider(this);
122 viewer.setLabelProvider(labelProvider);
123
124
125 //allow text selection
126 viewer.setCellModifier(new ICellModifier() {
127 @Override
128 public void modify(Object element, String property, Object value) {
129 }
130 @Override
131 public Object getValue(Object element, String property) {
132 ITableLabelProvider tableLabelProvider = null;
133 if(viewer.getLabelProvider() instanceof ITableLabelProvider){
134 tableLabelProvider = (ITableLabelProvider) viewer.getLabelProvider();
135 }
136 Object[] columnProperties = viewer.getColumnProperties();
137 for (int i=0;i<columnProperties.length;i++) {
138 if(columnProperties[i].equals(property) && tableLabelProvider!=null){
139 return tableLabelProvider.getColumnText(element, i);
140 }
141 }
142 return "";
143 }
144 @Override
145 public boolean canModify(Object element, String property) {
146 return true;
147 }
148 });
149
150 if(bulkEditorInput.getEntityUuid()!=null){
151 performSearch(new BulkEditorQuery(bulkEditorInput.getEntityUuid().toString(), null));
152 }
153 }
154
155 /** {@inheritDoc} */
156 @PostConstruct
157 public void createPartControl(Composite parent, EMenuService menuService) {
158 if (CdmStore.isActive()){
159 if(conversation == null){
160 conversation = CdmStore.createConversation();
161 }
162 }
163 else{
164 return;
165 }
166
167 parent.setLayout(new GridLayout());
168
169 topComposite = new Composite(parent, SWT.NONE);
170 topComposite.setLayout(new GridLayout());
171
172 GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
173 topComposite.setLayoutData(gridData);
174
175 Composite bottomComposite = new Composite(parent, SWT.NONE);
176 bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
177 bottomComposite.setLayout(new FillLayout());
178 viewer = new TableViewer(bottomComposite, SWT.MULTI | SWT.H_SCROLL
179 | SWT.V_SCROLL | SWT.FULL_SELECTION);
180
181 // createColumns(viewer);
182
183 //propagate selection
184 selectionChangedListener = (event -> selService.setSelection(AbstractUtility.getElementsFromSelectionChangedEvent(event)));
185 viewer.addSelectionChangedListener(selectionChangedListener);
186
187 //create context menu
188 menuService.registerContextMenu(viewer.getControl(), "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
189
190 }
191
192 @Override
193 @Persist
194 public void save(IProgressMonitor monitor) {
195 input.saveModel();
196
197 // commit the conversation and start a new transaction immediately
198 conversation.commit(true);
199
200 Object object = viewer.getInput();
201 if(object instanceof List){
202 for (Object item: (List)object) {
203 CdmBase cdmBase = (CdmBase) item;
204 CdmStore.getService(cdmBase).merge(cdmBase, true);
205 }
206 }
207 dirty.setDirty(false);
208 viewer.refresh();
209
210 }
211
212 /** {@inheritDoc} */
213 public void performSearch(BulkEditorQuery query) {
214 if (query != null) {
215
216 // TODO check if dirty, prompt save
217 if (isDirty()) {
218 String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
219 MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
220 int result = dialog.open();
221 if (result == 0) {
222 save(new NullProgressMonitor());
223 } else if (result == 2){
224 return;
225 }
226 }
227
228 getEditorInput().performSearch(query);
229
230 viewer.setInput(getEditorInput().getModel());
231 refresh();
232 }
233 }
234
235 public void refresh() {
236 refresh(false);
237 }
238
239 public void refresh(boolean resetInput) {
240 if(resetInput){
241 viewer.setInput(getEditorInput().getModel());
242 }
243 viewer.refresh();
244 }
245
246 public TableViewer getViewer() {
247 return viewer;
248 }
249
250 public void setDirty(){
251 dirty.setDirty(true);
252 }
253
254 public boolean isDirty() {
255 return dirty.isDirty();
256 }
257
258 public AbstractBulkEditorInput getEditorInput() {
259 return input;
260 }
261
262 /**
263 * {@inheritDoc}
264 */
265 @Override
266 public void update(CdmDataChangeMap arg0) {
267 }
268
269 /**
270 * {@inheritDoc}
271 */
272 @Override
273 public boolean canAttachMedia() {
274 return true;
275 }
276
277 /**
278 * {@inheritDoc}
279 */
280 @Override
281 public void changed(Object element) {
282 dirty.setDirty(true);
283 }
284
285 /**
286 * {@inheritDoc}
287 */
288 @Override
289 public void forceDirty() {
290 dirty.setDirty(true);
291 }
292
293 /**
294 * {@inheritDoc}
295 */
296 @Override
297 public boolean postOperation(CdmBase objectAffectedByOperation) {
298 return false;
299 }
300
301 /**
302 * {@inheritDoc}
303 */
304 @Override
305 public boolean onComplete() {
306 return false;
307 }
308
309 /**
310 * {@inheritDoc}
311 */
312 @Override
313 public ConversationHolder getConversationHolder() {
314 return conversation;
315 }
316
317 }