Project

General

Profile

Download (14 KB) Statistics
| Branch: | Tag: | Revision:
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.editor.e4;
11

    
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.UUID;
15

    
16
import javax.annotation.PreDestroy;
17
import javax.inject.Inject;
18

    
19
import org.eclipse.core.commands.operations.IUndoContext;
20
import org.eclipse.core.commands.operations.UndoContext;
21
import org.eclipse.core.runtime.IProgressMonitor;
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.workbench.modeling.ESelectionService;
26
import org.eclipse.jface.dialogs.MessageDialog;
27
import org.eclipse.jface.viewers.ISelectionChangedListener;
28
import org.eclipse.ui.IEditorInput;
29
import org.eclipse.ui.IEditorPart;
30
import org.eclipse.ui.PartInitException;
31

    
32
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
33
import eu.etaxonomy.cdm.api.application.CdmChangeEvent;
34
import eu.etaxonomy.cdm.api.application.CdmChangeEvent.Action;
35
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
36
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.name.TaxonName;
39
import eu.etaxonomy.cdm.model.taxon.Taxon;
40
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
41
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
42
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
43
import eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage;
44
import eu.etaxonomy.taxeditor.editor.ISecuredEditor;
45
import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
46
import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
47
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
48
import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
49
import eu.etaxonomy.taxeditor.editor.name.container.AbstractGroupedContainer;
50
import eu.etaxonomy.taxeditor.model.AbstractUtility;
51
import eu.etaxonomy.taxeditor.model.DataChangeBridge;
52
import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
53
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
54
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
55
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
56
import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
57
import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
58
import eu.etaxonomy.taxeditor.model.MessagingUtils;
59
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
60

    
61
/**
62
 *
63
 * @author pplitzner
64
 * @date Aug 24, 2017
65
 *
66
 */
67
public class MultiPageTaxonEditorE4
68
        implements IPartContentHasFactualData, IConversationEnabled, IPostOperationEnabled, IDirtyMarkable,
69
        IPartContentHasDetails, IPartContentHasSupplementalData, ISecuredEditor, IPartContentHasMedia, ITaxonEditor {
70

    
71
    /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon"{trunked}</code> */
72
    public static final String ID = "eu.etaxonomy.taxeditor.editor.taxon"; //$NON-NLS-1$
73

    
74
    private ConversationHolder conversation;
75
    private IDataChangeBehavior dataChangeBehavior;
76
    private IUndoContext undoContext;
77

    
78
    private TaxonEditorInputE4 input;
79

    
80
    @Inject
81
    private ESelectionService selService;
82

    
83
    @Inject
84
    private MDirtyable dirty;
85

    
86
    private ISelectionChangedListener selectionChangedListener;
87

    
88

    
89
    @Inject
90
    public MultiPageTaxonEditorE4() {
91
        undoContext = new UndoContext();
92

    
93
    }
94

    
95
    /** {@inheritDoc} */
96
    @PreDestroy
97
    public void dispose() {
98
        input.dispose();
99
        conversation.unregisterForDataStoreChanges(this);
100
        conversation.close();
101
    }
102

    
103
    /** {@inheritDoc} */
104
    @Override
105
    protected void addPages() {
106
        input = getEditorInput();
107
        conversation = input.getConversationHolder();
108
        conversation.registerForDataStoreChanges(this);
109

    
110
        try {
111
            addPage(Page.NAME.getIndex(), new TaxonNameEditor(this),
112
                    getEditorInput());
113

    
114
        } catch (PartInitException e) {
115
            MessagingUtils.error(getClass(), e);
116
        }
117
    }
118

    
119
    /**
120
     * {@inheritDoc}
121
     */
122
    @Override
123
    protected void pageChange(int newPageIndex) {
124
        if(getCurrentPage()==-1){
125
            return;
126
        }
127
        super.pageChange(newPageIndex);
128
    }
129

    
130
    /** {@inheritDoc} */
131
    @Persist
132
    public void doSave(IProgressMonitor monitor) {
133
        monitor.beginTask(Messages.MultiPageTaxonEditor_SAVING_EDITOR, 4);
134
        try {
135
            if (!conversation.isBound()) {
136
                conversation.bind();
137
            }
138
            monitor.worked(1);
139

    
140
            for (IEditorPart editorPage : getPages()) {
141
                if (editorPage instanceof TaxonNameEditor) {
142
                    if (((TaxonNameEditor) editorPage).checkForEmptyNames()) {
143
                        MessageDialog.openWarning(AbstractUtility.getShell(), Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED,
144
                                Messages.MultiPageTaxonEditor_NO_NAME_SPECIFIED_MESSAGE);
145
                        return;
146
                    }
147
                }
148

    
149
                editorPage.doSave(monitor);
150
                monitor.worked(1);
151
            }
152

    
153
            // commit the conversation and start a new transaction immediately
154

    
155
            input.merge();
156

    
157
            conversation.commit(true);
158
            CdmApplicationState.getCurrentDataChangeService()
159
            .fireChangeEvent(new CdmChangeEvent(Action.Update, input.getTaxonNode() , MultiPageTaxonEditorE4.class), true);
160
            monitor.worked(1);
161

    
162
            this.setDirty(false);
163
            monitor.worked(1);
164
        } catch (Exception e) {
165
            setFocus();
166
            MessagingUtils.operationDialog(this, e, TaxeditorEditorPlugin.PLUGIN_ID,Messages.MultiPageTaxonEditor_SAVING_TAXON, Messages.MultiPageTaxonEditor_SAVING_TAXON_MESSAGE);
167
            disableEditor(true);
168
        } finally {
169
            monitor.done();
170
        }
171
    }
172

    
173
    private void disableEditor(boolean isOnError) {
174
        for (IMultiPageTaxonEditorPage editorPage : getPages()) {
175
            if(isOnError){
176
                editorPage.setOnError();
177
            }else {
178
                editorPage.setDisabled();
179
            }
180
        }
181

    
182
        conversation.unregisterForDataStoreChanges(this);
183
        conversation.close();
184
        setDirty(false);
185
    }
186

    
187
    private void setDirty(boolean dirty) {
188
        this.dirty.setDirty(dirty);
189
    }
190

    
191
    public boolean isDirty() {
192
        return dirty.isDirty();
193
    }
194

    
195
    public void init(IEditorInput input)
196
            throws PartInitException {
197

    
198
        if (!(input instanceof TaxonEditorInputE4)) {
199
            throw new PartInitException(
200
                    Messages.MultiPageTaxonEditor_INVALID_INPUT);
201
        }
202

    
203
        this.input = (TaxonEditorInputE4) input;
204
        setPartName();
205
    }
206

    
207
    /**
208
     * Calls <code>MultiPageEditorPart.setPartName(String partName)</code> with
209
     * text appropriate to the state of the taxon: any taxon that has been saved
210
     * will by necessity have a name to display; a new taxon should display
211
     * "New taxon" in the editor tab.
212
     */
213
    protected void setPartName() {
214

    
215
        String partName = null;
216
        TaxonName name = getTaxon().getName();
217

    
218
        if (name != null) {
219
            partName = name.getTitleCache();
220
        }
221

    
222
        if (partName == null || partName.equals("")) { //$NON-NLS-1$
223
            partName = (Messages.MultiPageTaxonEditor_NEW_TAXON);
224
        }
225

    
226
        //FIXME E4 migrate
227
//        setPartName(partName);
228
    }
229

    
230
    /**
231
     * {@inheritDoc}
232
     *
233
     * Editor pages call this in their postOperation to notify the
234
     * MultiPageTaxonEditor of unsaved changes
235
     */
236
    @Override
237
    public void changed(Object element) {
238
        // setDirty(true);
239
        // if the attribute is null then do not set the dirty flag -> hotfix for the problem that for tasks done in service methods the changes are saved automatically
240
        if (element != null){
241
            setDirty(true);
242
        }
243

    
244
        if (element instanceof TaxonBase) {
245
            TaxonNameEditor page = (TaxonNameEditor) getPage(Page.NAME);
246
            AbstractGroupedContainer container = page.getContainer((TaxonBase) element);
247
            if (container != null) {
248
                container.refresh();
249
            }
250
        }
251
        if (element instanceof TaxonRelationship) {
252
            TaxonNameEditor page = (TaxonNameEditor) getPage(Page.NAME);
253
            AbstractGroupedContainer container = page.getContainer(((TaxonRelationship) element).getFromTaxon());
254
            if (container != null) {
255
                container.refresh();
256
            }
257
        }
258
        //refresh part title
259
        //TODO: refresh taxon node in taxon navigator
260
        setPartName();
261
    }
262

    
263
    @Override
264
    public void forceDirty() {
265
        changed(null);
266
    }
267

    
268
    /**
269
     * The accepted taxon that is the input for this editor
270
     *
271
     * @return the accepted taxon
272
     */
273
    @Override
274
    public Taxon getTaxon() {
275
        return input.getTaxon();
276
    }
277

    
278
    @Override
279
    public ConversationHolder getConversationHolder() {
280
        return conversation;
281
    }
282

    
283
    public void setConversationHolder(ConversationHolder conversation) {
284
        this.conversation = conversation;
285
    }
286

    
287
    public IUndoContext getUndoContext() {
288
        return undoContext;
289
    }
290

    
291
    public void setUndoContext(IUndoContext undoContext) {
292
        this.undoContext = undoContext;
293
    }
294

    
295
    /** {@inheritDoc} */
296
    @Focus
297
    public void setFocus() {
298
        // logger.warn("Setting focus to editor");
299
        // bind the conversation
300
        getConversationHolder().bind();
301
        input.bind();
302
        // pass focus to the active editor page
303
        //FIXME E4 migrate
304
//        getActiveEditor().setFocus();
305
    }
306

    
307
    /** {@inheritDoc} */
308
    @Override
309
    public void update(CdmDataChangeMap events) {
310
        if (dataChangeBehavior == null) {
311
            dataChangeBehavior = new MultiPageTaxonEditorDataChangeBehaviourE4(this);
312
        }
313

    
314
        DataChangeBridge.handleDataChange(events, dataChangeBehavior);
315
    }
316

    
317
    /** {@inheritDoc} */
318
    @Override
319
    public boolean postOperation(CdmBase objectAffectedByOperation) {
320
    		setDirty(true);
321

    
322
        for (IEditorPart editor : this.getPages()) {
323
            if (editor instanceof IPostOperationEnabled) {
324
                ((IPostOperationEnabled) editor).postOperation(objectAffectedByOperation);
325
            } else {
326
                MessagingUtils.warn(getClass(), Messages.MultiPageTaxonEditor_POST_OP_NOT_ENABLED + editor);
327
            }
328
        }
329
        MessagingUtils.warn(getClass(), Messages.MultiPageTaxonEditor_POST_OP_CALLED);
330

    
331
        return false;
332
    }
333

    
334
    /**
335
     * Returns an <code>IEditorPart</code> implementation by type
336
     *
337
     * @param page
338
     *            the page type
339
     * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage}
340
     *         object.
341
     */
342
    public IMultiPageTaxonEditorPage getPage(Page page) {
343
        for (IEditorPart editor : this.getPages()) {
344
            if (editor.getClass().equals(page.getClazz())) {
345
                return (IMultiPageTaxonEditorPage) editor;
346
            }
347
        }
348
        return null;
349
    }
350

    
351
    /**
352
     * Return a list of <code>AbstractTaxonEditor</code>s registered with this
353
     * <code>MultiPageTaxonEditor</code>.
354
     *
355
     * @return a {@link java.util.List} object.
356
     */
357
    public List<IMultiPageTaxonEditorPage> getPages() {
358
        ArrayList<IMultiPageTaxonEditorPage> editors = new ArrayList<IMultiPageTaxonEditorPage>();
359
        for (int i = 0; i < this.getPageCount(); i++) {
360

    
361
            editors.add((IMultiPageTaxonEditorPage) this.getEditor(i));
362
        }
363
        return editors;
364
    }
365

    
366
    /**
367
     * Refreshes a certain page of the MultipageTaxonEditor
368
     *
369
     * @param page
370
     *            a {@link eu.etaxonomy.taxeditor.editor.Page} object.
371
     * @return a boolean.
372
     */
373
    public boolean redraw(Page page) {
374
        return redraw(page, true);
375
    }
376

    
377
    /**
378
     * Refreshes a certain page of the MultipageTaxonEditor and sets focus to
379
     * that page
380
     *
381
     * @param page
382
     *            a {@link eu.etaxonomy.taxeditor.editor.Page} object.
383
     * @param focus
384
     *            a boolean.
385
     * @return a boolean.
386
     */
387
    public boolean redraw(Page page, boolean focus) {
388
        IMultiPageTaxonEditorPage editorPage = getPage(page);
389
        return editorPage != null && editorPage.redraw(focus);
390
    }
391

    
392
    /**
393
     * <p>
394
     * onComplete
395
     * </p>
396
     *
397
     * @return a boolean.
398
     */
399
    @Override
400
    public boolean onComplete() {
401
        return false;
402
    }
403

    
404
    /**
405
     * Reloads the data for this
406
     */
407
    public void reload() {
408
        if (isDirty()) {
409
            MessagingUtils.warningDialog(Messages.MultiPageTaxonEditor_UNSAVED_DATA, getClass(), Messages.MultiPageTaxonEditor_UNSAVED_DATA_MESSAGE);
410
        } else {
411
            TaxonEditorInputE4 input = getEditorInput();
412

    
413
            UUID uuid = input.getTaxonNode().getUuid();
414

    
415
            conversation.clear();
416

    
417
            try {
418
                TaxonEditorInputE4 newInput = TaxonEditorInputE4.NewInstance(uuid);
419
                setInput(newInput);
420
                for (IMultiPageTaxonEditorPage editorPart : getPages()) {
421
                    editorPart.redraw();
422
                }
423
            } catch (Exception e) {
424
                MessagingUtils.messageDialog(Messages.MultiPageTaxonEditor_REFRESH_ERROR, getClass(), Messages.MultiPageTaxonEditor_REFRESH_ERROR_MESSAGE, e);
425
            }
426
        }
427
    }
428

    
429
    @Override
430
    public String toString() {
431
        return String.format("%s[%s]", this.getClass().getSimpleName(), getEditorInput()); //$NON-NLS-1$
432
    }
433

    
434
    @Override
435
    public boolean permissionsSatisfied() {
436
        IEditorPart activeEditor = getActiveEditor();
437
        if(activeEditor != null && ISecuredEditor.class.isAssignableFrom(activeEditor.getClass())){
438
            return ((ISecuredEditor)activeEditor).permissionsSatisfied();
439
        }
440
        return true;
441
    }
442

    
443
    @Override
444
    public boolean canAttachMedia() {
445
        return true;
446
    }
447

    
448
    public TaxonEditorInputE4 getEditorInput() {
449
        return input;
450
    }
451

    
452
}
(2-2/5)