Project

General

Profile

Download (21.4 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
 * Copyright (C) 2007 EDIT
4
 * European Distributed Institute of Taxonomy
5
 * http://www.e-taxonomy.eu
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version 1.1
8
 * See LICENSE.TXT at the top of this package for the full license terms.
9
 */
10

    
11
package eu.etaxonomy.taxeditor.editor.view.checklist;
12

    
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Collections;
16
import java.util.HashMap;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.SortedSet;
20

    
21
import org.apache.log4j.Logger;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.Status;
25
import org.eclipse.core.runtime.jobs.Job;
26
import org.eclipse.jface.viewers.ISelection;
27
import org.eclipse.jface.viewers.StructuredViewer;
28
import org.eclipse.jface.viewers.TableViewer;
29
import org.eclipse.jface.viewers.TableViewerColumn;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.events.ModifyListener;
32
import org.eclipse.swt.events.SelectionAdapter;
33
import org.eclipse.swt.events.SelectionEvent;
34
import org.eclipse.swt.layout.GridData;
35
import org.eclipse.swt.layout.GridLayout;
36
import org.eclipse.swt.widgets.Composite;
37
import org.eclipse.swt.widgets.Display;
38
import org.eclipse.swt.widgets.Label;
39
import org.eclipse.swt.widgets.Menu;
40
import org.eclipse.swt.widgets.Table;
41
import org.eclipse.swt.widgets.TableColumn;
42
import org.eclipse.swt.widgets.Text;
43
import org.eclipse.swt.widgets.ToolBar;
44
import org.eclipse.swt.widgets.ToolItem;
45
import org.eclipse.ui.IEditorInput;
46
import org.eclipse.ui.IEditorSite;
47
import org.eclipse.ui.IMemento;
48
import org.eclipse.ui.ISelectionListener;
49
import org.eclipse.ui.ISelectionService;
50
import org.eclipse.ui.IWorkbenchPart;
51
import org.eclipse.ui.PartInitException;
52
import org.eclipse.ui.part.EditorPart;
53
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
54

    
55
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
56
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
57
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
58
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
59
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
60
import eu.etaxonomy.cdm.model.taxon.Classification;
61
import eu.etaxonomy.cdm.model.taxon.Taxon;
62
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
63
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
64
import eu.etaxonomy.taxeditor.editor.EditorUtil;
65
import eu.etaxonomy.taxeditor.editor.SimpleSelectionProvider;
66
import eu.etaxonomy.taxeditor.editor.view.checklist.edit.DistributionEditingSupport;
67
import eu.etaxonomy.taxeditor.editor.view.checklist.edit.RankEditingSupport;
68
import eu.etaxonomy.taxeditor.editor.view.checklist.filter.ChecklistEditorFilter;
69
import eu.etaxonomy.taxeditor.editor.view.checklist.listener.ChecklistDropdownSelectionListener;
70
import eu.etaxonomy.taxeditor.editor.view.checklist.listener.ChecklistFocusListener;
71
import eu.etaxonomy.taxeditor.editor.view.checklist.listener.ChecklistModifyListener;
72
import eu.etaxonomy.taxeditor.model.IContextListener;
73
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
74
import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
75
import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
76
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
77
import eu.etaxonomy.taxeditor.preference.Resources;
78
import eu.etaxonomy.taxeditor.store.CdmStore;
79

    
80
/**
81
 * <p>
82
 * ChecklistViewPart class.
83
 * </p>
84
 *
85
 * @author a.oppermann
86
 * @created 30.04.2014
87
 * @version 1.0
88
 */
89
public class ChecklistEditor extends EditorPart implements ISelectionListener, IPartContentHasFactualData,
90
        IConversationEnabled, IContextListener, IPartContentHasDetails, IDirtyMarkable {
91

    
92
    private static final Logger logger = Logger.getLogger(ChecklistEditor.class);
93
    /**
94
     * Key used for storing Checklist Editor View
95
     */
96
    private static final String CHECKLIST_EDITOR_MEMENTO_KEY = "checklistEditor";
97

    
98
    private class ChecklistJob extends Job {
99

    
100
        private List<TaxonNode> taxonNodes;
101

    
102
        /**
103
         * @param name
104
         */
105
        public ChecklistJob(String title, List<TaxonNode> listTaxonNodes) {
106
            super(title);
107
            this.taxonNodes = listTaxonNodes;
108

    
109
        }
110

    
111
        /*
112
         * (non-Javadoc)
113
         *
114
         * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
115
         * IProgressMonitor)
116
         */
117
        @Override
118
        public IStatus run(final IProgressMonitor monitor) {
119
            try {
120
                logger.debug("Begin of eclipse core runtime Job to Retrieve datasources");
121
                monitor.beginTask("Retrieving TaxonNodes", taxonNodes.size() + 1);
122

    
123
                final List<Taxon> taxonList = new ArrayList<Taxon>();
124

    
125
                for (TaxonNode taxonNode : taxonNodes) {
126
                    HibernateProxyHelper hh = new HibernateProxyHelper();
127
                    Taxon taxon = hh.deproxy(taxonNode.getTaxon(), Taxon.class);
128
                    taxonList.add(taxon);
129
                }
130
                // set View input
131
                Display.getDefault().asyncExec(new Runnable() {
132

    
133
                    @Override
134
                    public void run() {
135
                        viewer.setInput(taxonList);
136
                    }
137
                });
138
                monitor.worked(1);
139

    
140
            } finally {
141
                monitor.done();
142
                taxonNodes = null;
143
            }
144
            return Status.OK_STATUS;
145
        }
146
    }
147

    
148
    /**
149
     * Constant
150
     * <code>ID="eu.etaxonomy.taxeditor.store.datasource"{trunked}</code>
151
     */
152
    public static String ID = "eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor";
153

    
154
    private TableViewer viewer;
155

    
156
    private String partNameCache;
157

    
158
    private IWorkbenchSiteProgressService service;
159

    
160
    private ITaxonNodeService taxonNodeService;
161

    
162
    private ChecklistEditorComparator comparator;
163

    
164
    private ChecklistEditorInput checklistEditorInput;
165

    
166
    private SimpleSelectionProvider simpleSelectionProvider;
167

    
168
    private ISelectionService selectionService;
169

    
170
    private ConversationHolder conversation;
171

    
172
    private Integer countNodes;
173

    
174
    private List<TaxonNode> selectedTaxonNodes;
175

    
176
    private boolean dirty;
177

    
178
    private ChecklistEditorFilter filter;
179

    
180
    private Menu headerMenu;
181

    
182
    private Label statusLabel;
183

    
184
    private SortedSet<DefinedTermBase> terms = null;
185

    
186
    /**
187
     * @return the selectedTaxonNodes
188
     */
189
    public List<TaxonNode> getSelectedTaxonNodes() {
190
        return selectedTaxonNodes;
191
    }
192

    
193
    /**
194
     * @param selectedTaxonNodes
195
     *            the selectedTaxonNodes to set
196
     */
197
    public void setSelectedTaxonNodes(List<TaxonNode> selectedTaxonNodes) {
198
        this.selectedTaxonNodes = selectedTaxonNodes;
199
    }
200

    
201
    /**
202
     * <p>
203
     * Constructor for CdmDataSourceViewPart.
204
     * </p>
205
     */
206
    public ChecklistEditor() {
207
    }
208

    
209
    /** {@inheritDoc} */
210
    @Override
211
    public void createPartControl(Composite parent) {
212
        service = (IWorkbenchSiteProgressService) getSite().getAdapter(IWorkbenchSiteProgressService.class);
213
        taxonNodeService = CdmStore.getService(ITaxonNodeService.class);
214
        selectionService = getSite().getWorkbenchWindow().getSelectionService();
215
        selectionService.addSelectionListener(this);
216
        filter = new ChecklistEditorFilter();
217
        ChecklistLabelProvider labelProvider = new ChecklistLabelProvider();
218
        terms = (SortedSet<DefinedTermBase>) labelProvider.getTermsOrderedByLabels(labelProvider.getNamedAreas(),
219
                CdmStore.getDefaultLanguage());
220
        createTopComposite(parent);
221
        loadDataInput();
222
    }
223

    
224
    /**
225
     * @param parent
226
     */
227
    private void createTopComposite(Composite parent) {
228
        GridLayout gridLayout = new GridLayout(3, false);
229
        gridLayout.marginWidth = 0;
230
        gridLayout.marginHeight = 0;
231
        parent.setLayout(gridLayout);
232

    
233
        final Text searchText = createSearchBar(parent);
234

    
235
//        if (terms != null && !terms.isEmpty()) {
236
            createToolbar(parent);
237
//        }
238
        viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
239
        getSite().setSelectionProvider(viewer);
240

    
241
        final ModifyListener modifyListener = new ChecklistModifyListener(viewer, filter, searchText);
242

    
243
        searchText.addFocusListener(new ChecklistFocusListener(searchText, modifyListener));
244
        searchText.addModifyListener(modifyListener);
245

    
246
        // Layout the viewer
247
        GridData gridData = new GridData();
248
        gridData.verticalAlignment = GridData.FILL;
249
        gridData.horizontalSpan = 3;
250
        gridData.grabExcessHorizontalSpace = true;
251
        gridData.grabExcessVerticalSpace = true;
252
        gridData.horizontalAlignment = GridData.FILL;
253
        viewer.getControl().setLayoutData(gridData);
254

    
255
        viewer.addFilter(filter);
256
        createColumns(viewer);
257

    
258
        viewer.setContentProvider(new ChecklistContentProvider());
259
        viewer.setLabelProvider(new ChecklistLabelProvider());
260
        comparator = new ChecklistEditorComparator();
261
        viewer.setComparator(comparator);
262

    
263
        createStatusBar(parent);
264
    }
265

    
266
    /**
267
     * @param parent
268
     * @return
269
     */
270
    private Text createSearchBar(Composite parent) {
271
        Label searchLabel = new Label(parent, SWT.NONE);
272
        searchLabel.setText("Search: ");
273
        final Text searchText = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.CANCEL);
274
        searchText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
275
        searchText.setForeground(EditorUtil.getColor(Resources.SEARCH_VIEW_FOREGROUND));
276
        searchText.setText("type filter text");
277
        return searchText;
278
    }
279

    
280
    /**
281
     * @param parent
282
     */
283
    private void createToolbar(Composite parent) {
284
        ToolBar toolBar = new ToolBar(parent, SWT.NONE);
285
        ToolItem toolItem = new ToolItem(toolBar, SWT.DROP_DOWN | SWT.BORDER);
286
        toolItem.setText("Distribution Status");
287
        toolItem.setToolTipText("Show Distribution Status for selected Areas");
288
        ChecklistDropdownSelectionListener dropListener = new ChecklistDropdownSelectionListener(toolItem, this, terms);
289
        for (DefinedTermBase<DefinedTermBase> term : terms) {
290
            if(term!=null){
291
                dropListener.add(term);
292
            }
293
        }
294
        toolItem.addSelectionListener(dropListener);
295
        toolBar.pack();
296
    }
297

    
298
    private void createStatusBar(Composite composite) {
299
        GridData gridData = new GridData();
300
        gridData.horizontalSpan = 3;
301
        gridData.grabExcessHorizontalSpace = true;
302
        gridData.horizontalAlignment = GridData.FILL;
303

    
304
        statusLabel = new Label(composite, SWT.LEFT);
305
        statusLabel.setText("Anzahl der Elemente: " + (countNodes != null ? countNodes : "uknown"));
306
        statusLabel.setLayoutData(gridData);
307
    }
308

    
309
    // This will create the columns for the table
310
    private void createColumns(TableViewer viewer) {
311
        Table table = viewer.getTable();
312
        List<String> titles = new ArrayList<String>();
313
        Collections.addAll(titles, "Taxon", "Author", "Reference", "Rank");
314
        List<Integer> bounds = new ArrayList<Integer>();
315
        Collections.addAll(bounds, 300, 200, 200, 200);
316
        Map<Integer, Boolean>restoreColumnWidth = new HashMap<Integer, Boolean>();
317
        if (terms != null) {
318
            int i = 4;
319
            for (DefinedTermBase<DefinedTermBase> term : terms) {
320
                if(term != null){
321
                    restoreColumnWidth.put(i, PreferencesUtil.getPreferenceStore().getBoolean(term.getUuid().toString()));
322
                    titles.add(term.getTitleCache());
323
                    bounds.add(200);
324
                    i++;
325
                }
326
            }
327
        }
328

    
329
        for (int i = 0; i < titles.size(); i++) {
330
            TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
331
            column.getColumn().setText(titles.get(i));
332
            column.getColumn().setWidth(bounds.get(i));
333
            column.getColumn().setResizable(true);
334
            column.getColumn().setMoveable(true);
335
            column.getColumn().addSelectionListener(getSelectionAdapter(column.getColumn(), i));
336
            if (i == 1) {
337
                table.setSortColumn(column.getColumn());
338
            }
339
            if (i == 3) {
340
            	/** uncommented it for now because no rank editing is wanted **/
341
//                column.setEditingSupport(new RankEditingSupport(viewer, this));
342
            }
343
            if (i >= 4) {
344
                //read PrefrenceStore to setWidth according to last saved state
345
                if(restoreColumnWidth.get(i)){
346
                    column.getColumn().setWidth(100);
347
                }else{
348
                    column.getColumn().setWidth(0);
349
                }
350
                column.setEditingSupport(new DistributionEditingSupport(viewer, this, i));
351
            }
352
        }
353
        table.setSortDirection(SWT.DOWN);
354
        table.setHeaderVisible(true);
355
        table.setLinesVisible(true);
356
    }
357

    
358
    /**
359
     *
360
     * pull data from database and set input for view
361
     *
362
     */
363
    private void loadDataInput() {
364
        Classification classification = checklistEditorInput.getClassification();
365
        TaxonNode taxonNode = checklistEditorInput.getTaxonNode();
366
        if (classification != null && taxonNode == null) {
367
            countNodes = taxonNodeService.countAllNodesForClassification(classification);
368
            statusLabel.setText("Anzahl der Elemente: " + (countNodes != null ? countNodes : "uknown"));
369
            // This should not kill the view nor the editor if something goes
370
            // wrong
371
            // TODO: don't load the whole taxonNode Object but rather a small
372
            // and simple Solution
373
            // FIXME: May be don't open classification which are greater than
374
            // 3000 Taxa
375
            selectedTaxonNodes = taxonNodeService.listAllNodesForClassification(classification, 0, countNodes);
376
            getService().schedule(new ChecklistJob("loading Taxa", selectedTaxonNodes), Job.LONG);
377
        }
378
        if (taxonNode != null) {
379
            selectedTaxonNodes = taxonNodeService.loadChildNodesOfTaxonNode(taxonNode, NODE_INIT_STRATEGY, true, false);
380
            getService().schedule(new ChecklistJob("loading Taxa", selectedTaxonNodes), Job.LONG);
381
        }
382
    }
383

    
384
    /** {@inheritDoc} */
385
    @Override
386
    public void dispose() {
387
        super.dispose();
388
    }
389

    
390
    /** {@inheritDoc} */
391
    @Override
392
    public void setFocus() {
393
        viewer.getControl().setFocus();
394
    }
395

    
396
    /*
397
     * (non-Javadoc)
398
     *
399
     * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
400
     */
401
    /** {@inheritDoc} */
402
    @Override
403
    public void showBusy(boolean busy) {
404
        super.showBusy(busy);
405
        // viewer.getTable().setEnabled(!busy);
406
        if (busy) {
407
            partNameCache = getPartName();
408
            setPartName("Loading " + countNodes + " Taxa...");
409
        } else {
410
            if (partNameCache != null) {
411
                setPartName(partNameCache);
412
            }
413
        }
414
    }
415

    
416
    /**
417
     * <p>
418
     * Getter for the field <code>viewer</code>.
419
     * </p>
420
     *
421
     * @return a {@link org.eclipse.jface.viewers.StructuredViewer} object.
422
     */
423
    public StructuredViewer getViewer() {
424
        return viewer;
425
    }
426

    
427
    public void refresh() {
428
        viewer.refresh();
429
    }
430

    
431
    /**
432
     * <p>
433
     * Getter for the field <code>service</code>.
434
     * </p>
435
     *
436
     * @return the service
437
     */
438
    public IWorkbenchSiteProgressService getService() {
439
        return service;
440
    }
441

    
442
    private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) {
443
        SelectionAdapter selectionAdapter = new SelectionAdapter() {
444
            @Override
445
            public void widgetSelected(SelectionEvent e) {
446
                comparator.setColumn(index);
447
                int dir = viewer.getTable().getSortDirection();
448
                if (viewer.getTable().getSortColumn() == column) {
449
                    dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
450
                } else {
451
                    dir = SWT.DOWN;
452
                }
453
                viewer.getTable().setSortDirection(dir);
454
                viewer.getTable().setSortColumn(column);
455
                viewer.refresh();
456
            }
457
        };
458
        return selectionAdapter;
459
    }
460

    
461
    @Override
462
    public void doSave(IProgressMonitor monitor) {
463
        try {
464
            monitor.beginTask("Saving Editor", 1);
465
            getConversationHolder().bind();
466
            getConversationHolder().commit(true);
467
            setDirty(false);
468
            monitor.worked(1);
469
        } finally {
470
            monitor.done();
471
        }
472

    
473
    }
474

    
475
    @Override
476
    public void doSaveAs() {
477
        // TODO Auto-generated method stub
478

    
479
    }
480

    
481
    @Override
482
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
483
        setSite(site);
484
        setInput(input);
485
        if (input instanceof ChecklistEditorInput) {
486
            checklistEditorInput = (ChecklistEditorInput) input;
487
            setPartName(getPartName() + ": " + checklistEditorInput.getName());
488
            conversation = ((ChecklistEditorInput) input).getConversationHolder();
489
        }
490
        simpleSelectionProvider = new SimpleSelectionProvider();
491
        getSite().setSelectionProvider(simpleSelectionProvider);
492
    }
493

    
494
    @Override
495
    public boolean isSaveAsAllowed() {
496
        // TODO Auto-generated method stub
497
        return false;
498
    }
499

    
500
    /*
501
     * (non-Javadoc)
502
     *
503
     * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.
504
     * IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
505
     */
506
    @Override
507
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
508
        // TODO Auto-generated method stub
509

    
510
    }
511

    
512
    /*
513
     * (non-Javadoc)
514
     *
515
     * @see
516
     * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update
517
     * (eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
518
     */
519
    @Override
520
    public void update(CdmDataChangeMap changeEvents) {
521

    
522
    }
523

    
524
    /*
525
     * (non-Javadoc)
526
     *
527
     * @see
528
     * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
529
     * ()
530
     */
531
    @Override
532
    public ConversationHolder getConversationHolder() {
533
        return conversation;
534
    }
535

    
536
    /*
537
     * (non-Javadoc)
538
     *
539
     * @see
540
     * eu.etaxonomy.taxeditor.model.IContextListener#contextAboutToStop(org.
541
     * eclipse.ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
542
     */
543

    
544
    @Override
545
    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
546

    
547
    }
548

    
549
    /*
550
     * (non-Javadoc)
551
     *
552
     * @see
553
     * eu.etaxonomy.taxeditor.model.IContextListener#contextStop(org.eclipse
554
     * .ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
555
     */
556
    @Override
557
    public void contextStop(IMemento memento, IProgressMonitor monitor) {
558
        // TODO Auto-generated method stub
559
//        IStructuredSelection sel = (IStructuredSelection) this.viewer.getSelection();
560
//        if (sel.isEmpty()) {
561
//            return;
562
//        }
563
//        memento = memento.createChild("tree-selections");
564
//        Iterator iter = sel.iterator();
565
//        while (iter.hasNext()) {
566
//            String nodeName = (String) iter.next();
567
//            memento.createChild("selected-nodes", nodeName);
568
//        }
569
    }
570

    
571
    /*
572
     * (non-Javadoc)
573
     *
574
     * @see
575
     * eu.etaxonomy.taxeditor.model.IContextListener#contextStart(org.eclipse
576
     * .ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
577
     */
578
    @Override
579
    public void contextStart(IMemento memento, IProgressMonitor monitor) {
580

    
581
    }
582

    
583
    /*
584
     * (non-Javadoc)
585
     *
586
     * @see
587
     * eu.etaxonomy.taxeditor.model.IContextListener#contextRefresh(org.eclipse
588
     * .core.runtime.IProgressMonitor)
589
     */
590
    @Override
591
    public void contextRefresh(IProgressMonitor monitor) {
592
        // TODO Auto-generated method stub
593

    
594
    }
595

    
596
    /*
597
     * (non-Javadoc)
598
     *
599
     * @see
600
     * eu.etaxonomy.taxeditor.model.IContextListener#workbenchShutdown(org.eclipse
601
     * .ui.IMemento, org.eclipse.core.runtime.IProgressMonitor)
602
     */
603
    @Override
604
    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
605
        conversation.clear();
606
        conversation.close();
607
        conversation = null;
608
    }
609

    
610
    private static final List<String> NODE_INIT_STRATEGY = Arrays.asList(new String[] { "descriptions",
611
            "descriptions.*", "description.state", "feature", "feature.*", "childNodes", "childNodes.taxon",
612
            "childNodes.taxon.name", "taxonNodes", "taxonNodes.*", "taxonNodes.taxon.*", "taxon.*",
613
            "taxon.descriptions", "taxon.sec", "taxon.name.*", "taxon.synonymRelations", "terms", "name.*",
614
            "name.rank.representations", "name.status.type.representations", "sources.$", "stateData.$" });
615

    
616
    /*
617
     * (non-Javadoc)
618
     *
619
     * @see
620
     * eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(
621
     * java.lang.Object)
622
     */
623
    @Override
624
    public void changed(Object element) {
625
        if (element != null) {
626
            viewer.update(element, null);
627
            setDirty(true);
628
            firePropertyChange(PROP_DIRTY);
629
        }
630
    }
631

    
632
    /* (non-Javadoc)
633
     * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#forceDirty()
634
     */
635
    @Override
636
    public void forceDirty() {
637
        changed(null);
638
    }
639

    
640
    public void setDirty(boolean dirty) {
641
        this.dirty = dirty;
642
        firePropertyChange(PROP_DIRTY);
643
    }
644

    
645
    /*
646
     * (non-Javadoc)
647
     *
648
     * @see org.eclipse.ui.forms.editor.FormEditor#isDirty()
649
     */
650
    @Override
651
    public boolean isDirty() {
652
        return dirty;
653
    }
654
}
(2-2/5)