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.ui.dialog.selection;
11

    
12
import java.text.Collator;
13
import java.util.ArrayList;
14
import java.util.Collections;
15
import java.util.Comparator;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.IStatus;
25
import org.eclipse.core.runtime.OperationCanceledException;
26
import org.eclipse.jface.dialogs.IDialogSettings;
27
import org.eclipse.jface.viewers.ILabelProvider;
28
import org.eclipse.jface.viewers.LabelProvider;
29
import org.eclipse.jface.viewers.StructuredSelection;
30
import org.eclipse.jface.window.Window;
31
import org.eclipse.jface.wizard.WizardDialog;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.events.SelectionAdapter;
34
import org.eclipse.swt.events.SelectionEvent;
35
import org.eclipse.swt.events.SelectionListener;
36
import org.eclipse.swt.graphics.Cursor;
37
import org.eclipse.swt.widgets.Button;
38
import org.eclipse.swt.widgets.Composite;
39
import org.eclipse.swt.widgets.Shell;
40

    
41
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
42
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
43
import eu.etaxonomy.cdm.model.common.CdmBase;
44
import eu.etaxonomy.cdm.model.common.ICdmBase;
45
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
46
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
47
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
48
import eu.etaxonomy.taxeditor.l10n.Messages;
49
import eu.etaxonomy.taxeditor.model.MessagingUtils;
50
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
51
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
52
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
53
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
54

    
55
/**
56
 * <p>Abstract AbstractFilteredCdmResourceSelectionDialog class.</p>
57
 *
58
 * @author n.hoffmann
59
 * @created 04.06.2009
60
 * @version 1.0
61
 */
62
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase> extends
63
		SearchDialog implements IConversationEnabled {
64

    
65
	private final ConversationHolder conversation;
66

    
67
	protected List<UuidAndTitleCache<T>> model;
68
	private final Set<T> transientCdmObjects = new HashSet<T>();
69
	private final String settings;
70
	protected final int limitOfInitialElements = 100;
71

    
72
	private T selectedObject;
73

    
74
	protected T cdmBaseToBeFiltered;
75

    
76

    
77
	/**
78
	 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
79
	 *
80
	 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
81
	 * @param conversation
82
	 * @param title a {@link java.lang.String} object.
83
	 * @param multi a boolean.
84
	 * @param settings a {@link java.lang.String} object.
85
	 * @param cdmObject a T object.
86
	 * @param <T> a T object.
87
	 */
88
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, ConversationHolder conversation, String title, boolean multi, String settings, T cdmObject) {
89
		super(shell, multi);
90
		setShellStyle(SWT.DIALOG_TRIM);
91
		setTitle(title);
92
		setMessage(Messages.SearchDialog_patternLabel);
93
		this.settings = settings;
94

    
95
		this.conversation = conversation;
96
		this.cdmBaseToBeFiltered = cdmObject;
97
		Cursor cursor = shell.getCursor();
98
		shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
99
		init();
100
		shell.setCursor(cursor);
101
		setListLabelProvider(createListLabelProvider());
102

    
103
	}
104

    
105
	/**
106
	 * By default, we are returning the standard list label provider
107
	 *
108
	 * Override in subclasses if you want different behavior
109
	 *
110
	 * @return
111
	 */
112
	protected ILabelProvider createDetailsLabelProvider() {
113
		return createListLabelProvider();
114
	}
115

    
116
	/**
117
	 *
118
	 * @return
119
	 */
120
	protected ILabelProvider createListLabelProvider() {
121
		return new FilteredCdmResourceLabelProvider();
122
	}
123

    
124
	/**
125
	 * Override in subclasses.
126
	 * Will run before initModel()
127
	 */
128
	protected void init() {
129

    
130
	}
131

    
132
	/**
133
	 * <p>getSelectionFromDialog</p>
134
	 *
135
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
136
	 * @param <TYPE> a TYPE object.
137
	 * @return a TYPE object.
138
	 */
139
	protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) {
140
		int result = dialog.open();
141

    
142
		if (result == Window.CANCEL) {
143
			return null;
144
		}
145

    
146
		UUID uuid = dialog.getSelectedUuidAndTitleCache().getUuid();
147
		if(uuid == null){
148
			return null;
149
		}
150
		return dialog.getCdmObjectByUuid(uuid);
151
	}
152

    
153
	/**
154
	 * Check if object was created during the life of this dialog. If not,
155
	 * retrieve it from the CdmStore.
156
	 *
157
	 * @param cdmUuid a {@link java.util.UUID} object.
158
	 * @return a T object.
159
	 */
160
	protected T getCdmObjectByUuid(UUID cdmUuid) {
161
		for (T cdmObject : transientCdmObjects) {
162
			if (cdmObject.getUuid().equals(cdmUuid)) {
163
				return cdmObject;
164
			}
165
		}
166
		return getPersistentObject(cdmUuid);
167
	}
168

    
169
	/**
170
	 * <p>getPersistentObject</p>
171
	 *
172
	 * @param uuid a {@link java.util.UUID} object.
173
	 * @return a T object.
174
	 */
175
	abstract protected T getPersistentObject(UUID uuid);
176

    
177

    
178
	/**
179
	 * <p>isObjectTransient</p>
180
	 *
181
	 * @param cdmObject a T object.
182
	 * @return a boolean.
183
	 */
184
	protected boolean isObjectTransient(T cdmObject) {
185
		return (getPersistentObject(cdmObject.getUuid()) == null);
186
	}
187

    
188
	/**
189
	 * <p>getTitle</p>
190
	 *
191
	 * @param cdmObject a T object.
192
	 * @return a {@link java.lang.String} object.
193
	 */
194
	protected String getTitle(T cdmObject) {
195
		if(cdmObject == null){
196
			return "";
197
		}
198

    
199
		if (cdmObject instanceof IIdentifiableEntity) {
200
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
201
		}
202

    
203
		throw new IllegalArgumentException("Generic method only" +
204
				" supports cdmObject of type IIdentifiableEntity." +
205
				" Please implement specific method in subclass.");
206
	}
207

    
208

    
209

    
210
	/**
211
	 * Set the filter input to the Agent's title cache
212
	 *
213
	 * @param cdmObject a T object.
214
	 */
215
	protected void setPattern(T cdmObject) {
216
		String pattern = getTitle(cdmObject);
217
		getSearchField().setText(pattern);
218
	}
219

    
220

    
221

    
222
	/* (non-Javadoc)
223
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
224
	*/
225
	/** {@inheritDoc} */
226

    
227
	@Override
228
    protected void fillContentProvider(IProgressMonitor progressMonitor)
229
		throws CoreException {
230
		try {
231
		    if (model == null){
232
		        model = new ArrayList<UuidAndTitleCache<T>>();
233
		    }
234
			if(model != null){
235
			    if (progressMonitor != null){
236
			        progressMonitor.beginTask("Looking for entities", model.size());
237
			    }
238
			    Collections.sort(model, getItemsComparator());
239
			    contentProvider.reset();
240
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
241
				UuidAndTitleCache<T> element;
242
				while(iterator.hasNext()){
243
				    element = iterator.next();
244
				    if (!element.equals(cdmBaseToBeFiltered)){
245
				        contentProvider.add(element);
246
				    }
247
				    if (progressMonitor != null){
248
    					if (progressMonitor.isCanceled()) {
249
    						throw new OperationCanceledException();
250
    					}
251
    					progressMonitor.worked(1);
252
				    }
253
				}
254
				this.refresh();
255
			}else{
256

    
257
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
258
			}
259
		}
260
		finally {
261
		    if (progressMonitor != null) {
262
                progressMonitor.done();
263
            }
264
		}
265
	}
266

    
267
	/* (non-Javadoc)
268
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
269
	 */
270
	/** {@inheritDoc} */
271

    
272
	protected IDialogSettings getDialogSettings() {
273
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
274

    
275
		if (settings == null) {
276
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
277
		}
278
		return settings;
279
	}
280

    
281
	/* (non-Javadoc)
282
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
283
	 */
284
	/** {@inheritDoc} */
285

    
286
	public String getElementName(Object item) {
287
		return ((UuidAndTitleCache) item).getTitleCache();
288
	}
289

    
290
	/* (non-Javadoc)
291
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
292
	 */
293
	/** {@inheritDoc} */
294

    
295
	@Override
296
    protected Comparator getItemsComparator() {
297
		return new Comparator<UuidAndTitleCache>() {
298
			@Override
299
			public int compare(UuidAndTitleCache entity1,
300
					UuidAndTitleCache entity2) {
301
				Collator collator = Collator.getInstance();
302
				if (entity1.getUuid().equals(entity2.getUuid())){
303
				    return 0;
304
				}
305
				int result = collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
306
				if (result == 0){
307
				    result = entity1.getUuid().compareTo(entity2.getUuid());
308
				}
309
				return result;
310
			}
311
		};
312
	}
313

    
314

    
315
	/**
316
	 * <p>getSelectedUuidAndTitleCache</p>
317
	 *
318
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
319
	 */
320
	protected UuidAndTitleCache getSelectedUuidAndTitleCache() {
321
		Object result = getResult();
322
		if (result instanceof UuidAndTitleCache){
323
		    return (UuidAndTitleCache) result;
324
		}
325
		return null;
326
	}
327

    
328
	/**
329
     * @return
330
     */
331
    private Object getResult() {
332
        StructuredSelection selection = getCurrentSelection();
333
        return selection.getFirstElement();
334
    }
335

    
336
    /**
337
	 * <p>Getter for the field <code>settings</code>.</p>
338
	 *
339
	 * @return a {@link java.lang.String} object.
340
	 */
341
	public String getSettings()  {
342
		if(settings == null){
343
			throw new IllegalStateException("No SETTINGS set.");
344
		}
345
		return settings;
346
	}
347

    
348

    
349

    
350
	/**
351
	 * <p>getNewWizardLinkText</p>
352
	 *
353
	 * @return a {@link java.lang.String} object.
354
	 */
355
	protected abstract String[] getNewWizardText();
356

    
357
	/**
358
	 * <p>getNewEntityWizard</p>
359
	 * @param parameter
360
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
361
	 */
362
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
363

    
364
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
365
		@Override
366
		public String getText(Object element) {
367
			if (element == null) {
368
				return null;
369
			}
370
			UuidAndTitleCache uuidAndTitleCache = (UuidAndTitleCache) element;
371
			String titleCache = uuidAndTitleCache.getTitleCache();
372
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_ID_IN_ENTITY_SELECTION_DIAOLOG)){
373
			    titleCache += " ["+uuidAndTitleCache.getId()+"]";
374
			}
375
            return titleCache;
376
		}
377
	};
378

    
379
	/* (non-Javadoc)
380
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
381
	*/
382
	/** {@inheritDoc} */
383

    
384
//	@Override
385
//    protected Control createExtendedContentArea(Composite parent) {
386
//		String newWizardLinkText = getNewWizardLinkText();
387
////        if(newWizardLinkText != null){
388
////            newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
389
////
390
////            newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
391
////			return newButton1;
392
////		}
393
//		return null;
394
//	}
395

    
396
	@Override
397
    protected void createButtonsForButtonBar(Composite parent) {
398
	    String[] newButtonText = getNewWizardText();
399
	    if (newButtonText!= null){
400
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
401
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
402
	        if (newButtonText.length > 1){
403
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
404
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
405
	        }
406
	    }
407

    
408
        super.createButtonsForButtonBar(parent);
409
    }
410

    
411
	protected SelectionListener getNewWizardButtonSelectionListener(){
412
		return new SelectionAdapter() {
413

    
414
			/* (non-Javadoc)
415
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
416
			 */
417
			@Override
418
			public void widgetSelected(SelectionEvent e) {
419
			    Object source = e.getSource();
420
			    String text = null;
421
			    if (source instanceof Button){
422
			        Button sourceButton = (Button) source;
423
			        text = sourceButton.getText();
424
			    }
425
			    AbstractNewEntityWizard wizard = getNewEntityWizard(text);
426
			    if(wizard!=null){
427
			        wizard.init(null, null);
428
			        if(wizard.getEntity() != null) {
429
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
430
			            int status = dialog.open();
431

    
432
			            if (status == IStatus.OK) {
433

    
434
			                T entity = (T) wizard.getEntity();
435
			                refresh();
436
			                setPattern(entity);
437
			                if (getConversationHolder() != null){
438
			                    getConversationHolder().bind();
439
			                }
440
			            }
441
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
442
			            if (getConversationHolder() != null){
443
			                getConversationHolder().commit();
444
			            }
445
			        }
446
			    }
447
			}
448
		};
449
	}
450

    
451
	/**
452
	 * <p>getConversationHolder</p>
453
	 *
454
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
455
	 */
456
	@Override
457
	public ConversationHolder getConversationHolder() {
458
		return conversation;
459
	}
460

    
461
	/** {@inheritDoc} */
462
	@Override
463
	public void update(CdmDataChangeMap changeEvents) {}
464

    
465
	/**
466
	 * Don't want to add for example a taxon or synonym to itself
467
	 * so filter the list to remove the taxon in question
468
	 * (<code>cdmBaseToBeFiltered</code>)
469
	 * so it is not available in the filtered list.
470
	 */
471
	private void filterExcludedObjects() {
472
		if (model != null && cdmBaseToBeFiltered != null) {
473

    
474
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
475

    
476
			for (UuidAndTitleCache uuidAndTitleCache : model){
477
				if ((cdmBaseToBeFiltered.getUuid()).equals(uuidAndTitleCache.getUuid())) {
478
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
479
				}
480
			}
481
			model.remove(uuidAndTitleCacheToRemove);
482
		}
483
	}
484
	@Override
485
	void createFilterButton(Composite searchAndFilter){
486
	    //as default no filter button available
487
	}
488
}
(2-2/40)