Project

General

Profile

Download (15.8 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.CellEditor.LayoutData;
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.Label;
43
import org.eclipse.swt.widgets.Shell;
44
import org.eclipse.swt.widgets.Text;
45

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

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

    
67
//	private final ConversationHolder conversation = null;
68

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

    
74
	private T selectedObject;
75

    
76
	protected T cdmBaseToBeFiltered;
77

    
78

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

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

    
105
	}
106

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

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

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

    
132
	}
133

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

    
144
		if (result == Window.CANCEL) {
145
			return null;
146
		}
147

    
148
		UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
149
		if(uuid == null){
150
			return null;
151
		}
152
		return dialog.getCdmObjectByUuid(uuid.getUuid());
153
	}
154

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

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

    
179

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

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

    
201
		if (cdmObject instanceof IIdentifiableEntity) {
202
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
203
		}
204

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

    
210

    
211

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

    
222

    
223

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

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

    
242
			    contentProvider.reset();
243
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
244
				UuidAndTitleCache<T> element;
245
				while(iterator.hasNext()){
246
				    element = iterator.next();
247
				    if (!element.equals(cdmBaseToBeFiltered)){
248
				        contentProvider.add(element);
249
				    }
250
				    if (progressMonitor != null){
251
    					if (progressMonitor.isCanceled()) {
252
    						return;
253
    					}
254
    					progressMonitor.worked(1);
255
				    }
256
				}
257
				this.refresh();
258
			}else{
259

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

    
270

    
271
    protected void sort() {
272
        Collections.sort(model, getItemsComparator());
273
    }
274

    
275
    /* (non-Javadoc)
276
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
277
	 */
278
	/** {@inheritDoc} */
279

    
280
	protected IDialogSettings getDialogSettings() {
281
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
282

    
283
		if (settings == null) {
284
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
285
		}
286
		return settings;
287
	}
288

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

    
294
	public String getElementName(Object item) {
295
		return ((UuidAndTitleCache) item).getTitleCache();
296
	}
297

    
298
	/* (non-Javadoc)
299
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
300
	 */
301
	/** {@inheritDoc} */
302

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

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

    
338

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

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

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

    
375

    
376

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

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

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

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

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

    
423
	@Override
424
    protected void createButtonsForButtonBar(Composite parent) {
425
	    String[] newButtonText = getNewWizardText();
426
	    
427
	    if (newButtonText!= null){
428
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
429
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
430
	       
431
    	    
432
	        if (newButtonText.length > 1){
433
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
434
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
435

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

    
458
	protected SelectionListener getNewWizardButtonSelectionListener(){
459
		return new SelectionAdapter() {
460

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

    
479
			            if (status == IStatus.OK) {
480

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

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

    
508
	/** {@inheritDoc} */
509
//	@Override
510
//	public void update(CdmDataChangeMap changeEvents) {}
511

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

    
521
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
522

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

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

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

    
558
    abstract void callService(String pattern);
559

    
560
}
(2-2/39)