Project

General

Profile

Download (16.4 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.apache.commons.lang.StringUtils;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.IStatus;
25
import org.eclipse.jface.dialogs.IDialogSettings;
26
import org.eclipse.jface.viewers.ILabelProvider;
27
import org.eclipse.jface.viewers.LabelProvider;
28
import org.eclipse.jface.viewers.StructuredSelection;
29
import org.eclipse.jface.window.Window;
30
import org.eclipse.jface.wizard.WizardDialog;
31
import org.eclipse.swt.SWT;
32
import org.eclipse.swt.events.SelectionAdapter;
33
import org.eclipse.swt.events.SelectionEvent;
34
import org.eclipse.swt.events.SelectionListener;
35
import org.eclipse.swt.graphics.Cursor;
36
import org.eclipse.swt.layout.GridData;
37
import org.eclipse.swt.layout.GridLayout;
38
import org.eclipse.swt.widgets.Button;
39
import org.eclipse.swt.widgets.Composite;
40
import org.eclipse.swt.widgets.Control;
41
import org.eclipse.swt.widgets.Shell;
42
import org.eclipse.swt.widgets.Text;
43

    
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.common.ICdmBase;
46
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
47
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
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 = null;
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,
89
	        String title, boolean multi, String settings, T cdmObject) {
90
		super(shell, title);
91
		setShellStyle(SWT.DIALOG_TRIM);
92
		setMessage(Messages.SearchDialog_patternLabel);
93
		this.settings = settings;
94

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

    
102
	}
103

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

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

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

    
129
	}
130

    
131
	/**
132
	 * <p>getSelectionFromDialog</p>
133
	 *
134
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
135
	 * @param <TYPE> a TYPE object.
136
	 * @return a TYPE object.
137
	 */
138
	protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) {
139
	    UuidAndTitleCache result = getUuidAndTitleCacheSelectionFromDialog(dialog);
140
	    if (result != null){
141
	        return dialog.getCdmObjectByUuid(result.getUuid());
142
	    } else {
143
            return null;
144
        }
145
	}
146

    
147
	/**
148
     * <p>getSelectionFromDialog</p>
149
     *
150
     * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
151
     * @param <TYPE> a TYPE object.
152
     * @return a TYPE object.
153
     */
154
    protected static UuidAndTitleCache getUuidAndTitleCacheSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog dialog) {
155
        if (dialog == null){
156
            return null;
157
        }
158
        int result = dialog.open();
159

    
160
        if (result == Window.CANCEL) {
161
            return null;
162
        }
163

    
164
        UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
165

    
166
        return uuid;
167
    }
168

    
169
	/**
170
	 * Check if object was created during the life of this dialog. If not,
171
	 * retrieve it from the CdmStore.
172
	 *
173
	 * @param cdmUuid a {@link java.util.UUID} object.
174
	 * @return a T object.
175
	 */
176
	protected T getCdmObjectByUuid(UUID cdmUuid) {
177
		for (T cdmObject : transientCdmObjects) {
178
			if (cdmObject.getUuid().equals(cdmUuid)) {
179
				return cdmObject;
180
			}
181
		}
182
		return getPersistentObject(cdmUuid);
183
	}
184

    
185
	/**
186
	 * <p>getPersistentObject</p>
187
	 *
188
	 * @param uuid a {@link java.util.UUID} object.
189
	 * @return a T object.
190
	 */
191
	abstract protected T getPersistentObject(UUID uuid);
192

    
193

    
194
	/**
195
	 * <p>isObjectTransient</p>
196
	 *
197
	 * @param cdmObject a T object.
198
	 * @return a boolean.
199
	 */
200
	protected boolean isObjectTransient(T cdmObject) {
201
		return (getPersistentObject(cdmObject.getUuid()) == null);
202
	}
203

    
204
	/**
205
	 * <p>getTitle</p>
206
	 *
207
	 * @param cdmObject a T object.
208
	 * @return a {@link java.lang.String} object.
209
	 */
210
	protected String getTitle(T cdmObject) {
211
		if(cdmObject == null){
212
			return "";
213
		}
214

    
215
		if (cdmObject instanceof IIdentifiableEntity) {
216
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
217
		}
218

    
219
		throw new IllegalArgumentException("Generic method only" +
220
				" supports cdmObject of type IIdentifiableEntity." +
221
				" Please implement specific method in subclass.");
222
	}
223

    
224

    
225

    
226
	/**
227
	 * Set the filter input to the Agent's title cache
228
	 *
229
	 * @param cdmObject a T object.
230
	 */
231
	protected void setPattern(T cdmObject) {
232
		String pattern = getTitle(cdmObject);
233
		getSearchField().setText(pattern);
234
	}
235

    
236

    
237

    
238
	/* (non-Javadoc)
239
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
240
	*/
241
	/** {@inheritDoc} */
242

    
243
	@Override
244
    protected void fillContentProvider(IProgressMonitor progressMonitor)
245
		 {
246
		try {
247
		    if (model == null){
248
		        model = new ArrayList<UuidAndTitleCache<T>>();
249
		    }
250
			if(model != null){
251
			    if (progressMonitor != null){
252
			        progressMonitor.beginTask("Looking for entities", model.size());
253
			    }
254
			    sort();
255

    
256
			    contentProvider.reset();
257
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
258
				UuidAndTitleCache<T> element;
259
				while(iterator.hasNext()){
260
				    element = iterator.next();
261

    
262
				    if (cdmBaseToBeFiltered == null || !element.getUuid().equals(cdmBaseToBeFiltered.getUuid())){
263
				        contentProvider.add(element);
264
				    }
265
				    if (progressMonitor != null){
266
    					if (progressMonitor.isCanceled()) {
267
    						return;
268
    					}
269
    					progressMonitor.worked(1);
270
				    }
271
				}
272
				this.refresh();
273
			}else{
274

    
275
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
276
			}
277
		}
278
		finally {
279
		    if (progressMonitor != null) {
280
                progressMonitor.done();
281
            }
282
		}
283
	}
284

    
285

    
286
    protected void sort() {
287
        Collections.sort(model, getItemsComparator());
288
    }
289

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

    
295
	protected IDialogSettings getDialogSettings() {
296
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
297

    
298
		if (settings == null) {
299
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
300
		}
301
		return settings;
302
	}
303

    
304
	/* (non-Javadoc)
305
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
306
	 */
307
	/** {@inheritDoc} */
308

    
309
	public String getElementName(Object item) {
310
		return ((UuidAndTitleCache) item).getTitleCache();
311
	}
312

    
313
	/* (non-Javadoc)
314
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
315
	 */
316
	/** {@inheritDoc} */
317

    
318
	@Override
319
    protected Comparator getItemsComparator() {
320
		return new Comparator<UuidAndTitleCache>() {
321
			@Override
322
			public int compare(UuidAndTitleCache entity1,
323
					UuidAndTitleCache entity2) {
324
				Collator collator = Collator.getInstance();
325
				if (entity1 == entity2){
326
				    return 0;
327
				}
328

    
329
				if (entity1 == null && entity2 != null){
330
				    return -1;
331
				}
332
				if (entity2 == null && entity1 != null){
333
				    return 1;
334
				}
335
				if (entity1.getUuid().equals(entity2.getUuid())){
336
                    return 0;
337
                }
338
				if (entity1.getTitleCache() == null && entity2.getTitleCache() != null){
339
				    return -1;
340
				}
341
				if (entity2.getTitleCache() == null){
342
				    return 1;
343
				}
344
				int result = collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
345
				if (result == 0){
346
				    result = entity1.getUuid().compareTo(entity2.getUuid());
347
				}
348
				return result;
349
			}
350
		};
351
	}
352

    
353

    
354
	/**
355
	 * <p>getSelectedUuidAndTitleCache</p>
356
	 *
357
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
358
	 */
359
	protected UuidAndTitleCache getSelectedUuidAndTitleCache() {
360
		Object result = getResult();
361
		if (result instanceof UuidAndTitleCache){
362
		    return (UuidAndTitleCache) result;
363
		}
364
		return null;
365
	}
366

    
367
	/**
368
     * @return
369
     */
370
    private Object getResult() {
371
        StructuredSelection selection = getCurrentSelection();
372
        if (selection == null){
373
            return null;
374
        }
375
        return selection.getFirstElement();
376
    }
377

    
378
    /**
379
	 * <p>Getter for the field <code>settings</code>.</p>
380
	 *
381
	 * @return a {@link java.lang.String} object.
382
	 */
383
	public String getSettings()  {
384
		if(settings == null){
385
			throw new IllegalStateException("No SETTINGS set.");
386
		}
387
		return settings;
388
	}
389

    
390

    
391

    
392
	/**
393
	 * <p>getNewWizardLinkText</p>
394
	 *
395
	 * @return a {@link java.lang.String} object.
396
	 */
397
	protected abstract String[] getNewWizardText();
398

    
399
	/**
400
	 * <p>getNewEntityWizard</p>
401
	 * @param parameter
402
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
403
	 */
404
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
405

    
406
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
407
		@Override
408
		public String getText(Object element) {
409
			if (element == null) {
410
				return null;
411
			}
412
			UuidAndTitleCache uuidAndTitleCache = (UuidAndTitleCache) element;
413
			String titleCache = uuidAndTitleCache.getTitleCache();
414
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_ID_IN_ENTITY_SELECTION_DIAOLOG)){
415
			    titleCache += " ["+uuidAndTitleCache.getId()+"]";
416
			}
417
            return titleCache;
418
		}
419
	};
420

    
421
	/* (non-Javadoc)
422
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
423
	*/
424
	/** {@inheritDoc} */
425

    
426
//	@Override
427
//    protected Control createExtendedContentArea(Composite parent) {
428
//		String newWizardLinkText = getNewWizardLinkText();
429
////        if(newWizardLinkText != null){
430
////            newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
431
////
432
////            newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
433
////			return newButton1;
434
////		}
435
//		return null;
436
//	}
437

    
438
	@Override
439
    protected void createButtonsForButtonBar(Composite parent) {
440
	    String[] newButtonText = getNewWizardText();
441

    
442
	    if (newButtonText!= null){
443
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
444
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
445

    
446

    
447
	        if (newButtonText.length > 1){
448
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
449
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
450

    
451
	        }
452

    
453
	    }
454
	    Button space = createButton(parent, this.space_id, " ", false);
455
	    space.setEnabled(false);
456
	    space.setVisible(false);
457
	    GridData gridData = new GridData();
458
        gridData.grabExcessHorizontalSpace = false;
459
        gridData.widthHint = 3;
460
	    space.setLayoutData(gridData);
461
	    GridLayout gridLayout = new GridLayout();
462
	    gridLayout.makeColumnsEqualWidth= false;
463
	    if (newButtonText != null){
464
	    	gridLayout.numColumns=newButtonText.length+2;
465
	    }else{
466
	    	gridLayout.numColumns=2;
467
	    }
468
	    parent.setLayout(gridLayout);
469

    
470
        super.createButtonsForButtonBar(parent);
471
    }
472

    
473
	protected SelectionListener getNewWizardButtonSelectionListener(){
474
		return new SelectionAdapter() {
475

    
476
			/* (non-Javadoc)
477
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
478
			 */
479
			@Override
480
			public void widgetSelected(SelectionEvent e) {
481
			    Object source = e.getSource();
482
			    String text = null;
483
			    if (source instanceof Button){
484
			        Button sourceButton = (Button) source;
485
			        text = sourceButton.getText();
486
			    }
487
			    AbstractNewEntityWizard wizard = getNewEntityWizard(text);
488
			    if(wizard!=null){
489
			        wizard.init(null, null);
490
			        if(wizard.getEntity() != null) {
491
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
492
			            int status = dialog.open();
493

    
494
			            if (status == IStatus.OK) {
495

    
496
			                T entity = (T) wizard.getEntity();
497
			                refresh();
498
			                setPattern(entity);
499
//			                if (getConversationHolder() != null){
500
//			                    getConversationHolder().bind();
501
//			                }
502
			            }
503
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
504
//			            if (getConversationHolder() != null){
505
//			                getConversationHolder().commit();
506
//			            }
507
			        }
508
			    }
509
			}
510
		};
511
	}
512

    
513
	/**
514
	 * <p>getConversationHolder</p>
515
	 *
516
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
517
//	 */
518
//	@Override
519
//	public ConversationHolder getConversationHolder() {
520
//		return conversation;
521
//	}
522

    
523
	/** {@inheritDoc} */
524
//	@Override
525
//	public void update(CdmDataChangeMap changeEvents) {}
526

    
527
	/**
528
	 * Don't want to add for example a taxon or synonym to itself
529
	 * so filter the list to remove the taxon in question
530
	 * (<code>cdmBaseToBeFiltered</code>)
531
	 * so it is not available in the filtered list.
532
	 */
533
	private void filterExcludedObjects() {
534
		if (model != null && cdmBaseToBeFiltered != null) {
535

    
536
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
537

    
538
			for (UuidAndTitleCache uuidAndTitleCache : model){
539
				if ((cdmBaseToBeFiltered.getUuid()).equals(uuidAndTitleCache.getUuid())) {
540
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
541
				}
542
			}
543
			model.remove(uuidAndTitleCacheToRemove);
544
		}
545
	}
546
	@Override
547
	void createFilterButton(Composite searchAndFilter){
548
	    //as default no filter button available
549
	}
550

    
551
	/** {@inheritDoc} */
552
    @Override
553
    protected void search() {
554
        Control control =getSearchField();
555
        String pattern = null;
556
        if (control != null){
557
            pattern = ((Text)control).getText();
558
            if (pattern.equals("*") || pattern.equals("?")){
559
                callService(null);
560
            }else if (StringUtils.isNotBlank(pattern)){
561
                callService(pattern);
562
            }
563
            fillContentProvider(null);
564
        }
565

    
566
//        if (pattern.equals("?")){
567
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(null, null);
568
//        }else if (pattern != null){
569
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(limitOfInitialElements, pattern);
570
//        }
571
    }
572

    
573
    abstract void callService(String pattern);
574

    
575
}
(2-2/41)