Project

General

Profile

Download (16.5 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.IDialogConstants;
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.layout.GridData;
38
import org.eclipse.swt.layout.GridLayout;
39
import org.eclipse.swt.widgets.Button;
40
import org.eclipse.swt.widgets.Composite;
41
import org.eclipse.swt.widgets.Control;
42
import org.eclipse.swt.widgets.Shell;
43
import org.eclipse.swt.widgets.Text;
44

    
45
import eu.etaxonomy.cdm.model.common.CdmBase;
46
import eu.etaxonomy.cdm.model.common.ICdmBase;
47
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
48
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
49
import eu.etaxonomy.taxeditor.l10n.Messages;
50
import eu.etaxonomy.taxeditor.model.MessagingUtils;
51
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
52
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
53
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
54
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
55

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

    
66
//	private final ConversationHolder conversation = null;
67

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

    
73
	private T selectedObject;
74

    
75
	protected T cdmBaseToBeFiltered;
76

    
77

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

    
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
	    UuidAndTitleCache result = getUuidAndTitleCacheSelectionFromDialog(dialog);
141
	    if (result != null){
142
	        return dialog.getCdmObjectByUuid(result.getUuid());
143
	    } else {
144
            return null;
145
        }
146
	}
147

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

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

    
165
        UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
166

    
167
        return uuid;
168
    }
169

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

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

    
194

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

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

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

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

    
225

    
226

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

    
237

    
238

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

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

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

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

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

    
286

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

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

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

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

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

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

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

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

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

    
354

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

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

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

    
391

    
392

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

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

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

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

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

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

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

    
447

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

    
452
	        }
453

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

    
471
        super.createButtonsForButtonBar(parent);
472
        super.getButton(IDialogConstants.OK_ID).setEnabled(false);
473
    }
474

    
475
	protected SelectionListener getNewWizardButtonSelectionListener(){
476
		return new SelectionAdapter() {
477

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

    
496
			            if (status == IStatus.OK) {
497

    
498
			                T entity = (T) wizard.getEntity();
499
			                refresh();
500
			                setPattern(entity);
501

    
502
//			                if (getConversationHolder() != null){
503
//			                    getConversationHolder().bind();
504
//			                }
505
			            }
506
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
507
//			            if (getConversationHolder() != null){
508
//			                getConversationHolder().commit();
509
//			            }
510
			        }
511
			    }
512
			}
513
		};
514
	}
515

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

    
526
	/** {@inheritDoc} */
527
//	@Override
528
//	public void update(CdmDataChangeMap changeEvents) {}
529

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

    
539
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
540

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

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

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

    
576
    abstract void callService(String pattern);
577

    
578
}
(2-2/41)