Project

General

Profile

Download (15.7 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
		int result = dialog.open();
140

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

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

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

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

    
176

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

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

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

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

    
207

    
208

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

    
219

    
220

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

    
226
	@Override
227
    protected void fillContentProvider(IProgressMonitor progressMonitor)
228
		 {
229
		try {
230
		    if (model == null){
231
		        model = new ArrayList<UuidAndTitleCache<T>>();
232
		    }
233
			if(model != null){
234
			    if (progressMonitor != null){
235
			        progressMonitor.beginTask("Looking for entities", model.size());
236
			    }
237
			    sort();
238

    
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
    						return;
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

    
268
    protected void sort() {
269
        Collections.sort(model, getItemsComparator());
270
    }
271

    
272
    /* (non-Javadoc)
273
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
274
	 */
275
	/** {@inheritDoc} */
276

    
277
	protected IDialogSettings getDialogSettings() {
278
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
279

    
280
		if (settings == null) {
281
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
282
		}
283
		return settings;
284
	}
285

    
286
	/* (non-Javadoc)
287
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
288
	 */
289
	/** {@inheritDoc} */
290

    
291
	public String getElementName(Object item) {
292
		return ((UuidAndTitleCache) item).getTitleCache();
293
	}
294

    
295
	/* (non-Javadoc)
296
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
297
	 */
298
	/** {@inheritDoc} */
299

    
300
	@Override
301
    protected Comparator getItemsComparator() {
302
		return new Comparator<UuidAndTitleCache>() {
303
			@Override
304
			public int compare(UuidAndTitleCache entity1,
305
					UuidAndTitleCache entity2) {
306
				Collator collator = Collator.getInstance();
307
				if (entity1 == entity2){
308
				    return 0;
309
				}
310

    
311
				if (entity1 == null && entity2 != null){
312
				    return -1;
313
				}
314
				if (entity2 == null && entity1 != null){
315
				    return 1;
316
				}
317
				if (entity1.getUuid().equals(entity2.getUuid())){
318
                    return 0;
319
                }
320
				if (entity1.getTitleCache() == null && entity2.getTitleCache() != null){
321
				    return -1;
322
				}
323
				if (entity2.getTitleCache() == null){
324
				    return 1;
325
				}
326
				int result = collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
327
				if (result == 0){
328
				    result = entity1.getUuid().compareTo(entity2.getUuid());
329
				}
330
				return result;
331
			}
332
		};
333
	}
334

    
335

    
336
	/**
337
	 * <p>getSelectedUuidAndTitleCache</p>
338
	 *
339
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
340
	 */
341
	protected UuidAndTitleCache getSelectedUuidAndTitleCache() {
342
		Object result = getResult();
343
		if (result instanceof UuidAndTitleCache){
344
		    return (UuidAndTitleCache) result;
345
		}
346
		return null;
347
	}
348

    
349
	/**
350
     * @return
351
     */
352
    private Object getResult() {
353
        StructuredSelection selection = getCurrentSelection();
354
        if (selection == null){
355
            return null;
356
        }
357
        return selection.getFirstElement();
358
    }
359

    
360
    /**
361
	 * <p>Getter for the field <code>settings</code>.</p>
362
	 *
363
	 * @return a {@link java.lang.String} object.
364
	 */
365
	public String getSettings()  {
366
		if(settings == null){
367
			throw new IllegalStateException("No SETTINGS set.");
368
		}
369
		return settings;
370
	}
371

    
372

    
373

    
374
	/**
375
	 * <p>getNewWizardLinkText</p>
376
	 *
377
	 * @return a {@link java.lang.String} object.
378
	 */
379
	protected abstract String[] getNewWizardText();
380

    
381
	/**
382
	 * <p>getNewEntityWizard</p>
383
	 * @param parameter
384
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
385
	 */
386
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
387

    
388
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
389
		@Override
390
		public String getText(Object element) {
391
			if (element == null) {
392
				return null;
393
			}
394
			UuidAndTitleCache uuidAndTitleCache = (UuidAndTitleCache) element;
395
			String titleCache = uuidAndTitleCache.getTitleCache();
396
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_ID_IN_ENTITY_SELECTION_DIAOLOG)){
397
			    titleCache += " ["+uuidAndTitleCache.getId()+"]";
398
			}
399
            return titleCache;
400
		}
401
	};
402

    
403
	/* (non-Javadoc)
404
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
405
	*/
406
	/** {@inheritDoc} */
407

    
408
//	@Override
409
//    protected Control createExtendedContentArea(Composite parent) {
410
//		String newWizardLinkText = getNewWizardLinkText();
411
////        if(newWizardLinkText != null){
412
////            newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
413
////
414
////            newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
415
////			return newButton1;
416
////		}
417
//		return null;
418
//	}
419

    
420
	@Override
421
    protected void createButtonsForButtonBar(Composite parent) {
422
	    String[] newButtonText = getNewWizardText();
423

    
424
	    if (newButtonText!= null){
425
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
426
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
427

    
428

    
429
	        if (newButtonText.length > 1){
430
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
431
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
432

    
433
	        }
434

    
435
	    }
436
	    Button space = createButton(parent, this.space_id, " ", false);
437
	    space.setEnabled(false);
438
	    space.setVisible(false);
439
	    GridData gridData = new GridData();
440
        gridData.grabExcessHorizontalSpace = false;
441
        gridData.widthHint = 3;
442
	    space.setLayoutData(gridData);
443
	    GridLayout gridLayout = new GridLayout();
444
	    gridLayout.makeColumnsEqualWidth= false;
445
	    if (newButtonText != null){
446
	    	gridLayout.numColumns=newButtonText.length+2;
447
	    }else{
448
	    	gridLayout.numColumns=2;
449
	    }
450
	    parent.setLayout(gridLayout);
451

    
452
        super.createButtonsForButtonBar(parent);
453
    }
454

    
455
	protected SelectionListener getNewWizardButtonSelectionListener(){
456
		return new SelectionAdapter() {
457

    
458
			/* (non-Javadoc)
459
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
460
			 */
461
			@Override
462
			public void widgetSelected(SelectionEvent e) {
463
			    Object source = e.getSource();
464
			    String text = null;
465
			    if (source instanceof Button){
466
			        Button sourceButton = (Button) source;
467
			        text = sourceButton.getText();
468
			    }
469
			    AbstractNewEntityWizard wizard = getNewEntityWizard(text);
470
			    if(wizard!=null){
471
			        wizard.init(null, null);
472
			        if(wizard.getEntity() != null) {
473
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
474
			            int status = dialog.open();
475

    
476
			            if (status == IStatus.OK) {
477

    
478
			                T entity = (T) wizard.getEntity();
479
			                refresh();
480
			                setPattern(entity);
481
//			                if (getConversationHolder() != null){
482
//			                    getConversationHolder().bind();
483
//			                }
484
			            }
485
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
486
//			            if (getConversationHolder() != null){
487
//			                getConversationHolder().commit();
488
//			            }
489
			        }
490
			    }
491
			}
492
		};
493
	}
494

    
495
	/**
496
	 * <p>getConversationHolder</p>
497
	 *
498
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
499
//	 */
500
//	@Override
501
//	public ConversationHolder getConversationHolder() {
502
//		return conversation;
503
//	}
504

    
505
	/** {@inheritDoc} */
506
//	@Override
507
//	public void update(CdmDataChangeMap changeEvents) {}
508

    
509
	/**
510
	 * Don't want to add for example a taxon or synonym to itself
511
	 * so filter the list to remove the taxon in question
512
	 * (<code>cdmBaseToBeFiltered</code>)
513
	 * so it is not available in the filtered list.
514
	 */
515
	private void filterExcludedObjects() {
516
		if (model != null && cdmBaseToBeFiltered != null) {
517

    
518
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
519

    
520
			for (UuidAndTitleCache uuidAndTitleCache : model){
521
				if ((cdmBaseToBeFiltered.getUuid()).equals(uuidAndTitleCache.getUuid())) {
522
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
523
				}
524
			}
525
			model.remove(uuidAndTitleCacheToRemove);
526
		}
527
	}
528
	@Override
529
	void createFilterButton(Composite searchAndFilter){
530
	    //as default no filter button available
531
	}
532

    
533
	/** {@inheritDoc} */
534
    @Override
535
    protected void search() {
536
        Control control =getSearchField();
537
        String pattern = null;
538
        if (control != null){
539
            pattern = ((Text)control).getText();
540
            if (pattern.equals("*") || pattern.equals("?")){
541
                callService(null);
542
            }else if (StringUtils.isNotBlank(pattern)){
543
                callService(pattern);
544
            }
545
            fillContentProvider(null);
546
        }
547

    
548
//        if (pattern.equals("?")){
549
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(null, null);
550
//        }else if (pattern != null){
551
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(limitOfInitialElements, pattern);
552
//        }
553
    }
554

    
555
    abstract void callService(String pattern);
556

    
557
}
(2-2/40)