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