Project

General

Profile

Download (11.8 KB) Statistics
| Branch: | Tag: | Revision:
1
//$Id$
2

    
3
package eu.etaxonomy.taxeditor.ui.dialog.selection;
4

    
5
import java.lang.reflect.Field;
6
import java.text.Collator;
7
import java.util.Comparator;
8
import java.util.List;
9

    
10
import org.eclipse.core.runtime.CoreException;
11
import org.eclipse.core.runtime.IProgressMonitor;
12
import org.eclipse.core.runtime.IStatus;
13
import org.eclipse.core.runtime.OperationCanceledException;
14
import org.eclipse.core.runtime.Status;
15
import org.eclipse.jface.dialogs.IDialogSettings;
16
import org.eclipse.jface.viewers.ILabelProvider;
17
import org.eclipse.jface.viewers.LabelProvider;
18
import org.eclipse.jface.window.Window;
19
import org.eclipse.jface.wizard.WizardDialog;
20
import org.eclipse.swt.SWT;
21
import org.eclipse.swt.events.SelectionAdapter;
22
import org.eclipse.swt.events.SelectionEvent;
23
import org.eclipse.swt.events.SelectionListener;
24
import org.eclipse.swt.widgets.Composite;
25
import org.eclipse.swt.widgets.Control;
26
import org.eclipse.swt.widgets.Link;
27
import org.eclipse.swt.widgets.Shell;
28
import org.eclipse.swt.widgets.Text;
29
import org.eclipse.ui.IMemento;
30
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
31

    
32
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
33
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
34
import eu.etaxonomy.cdm.model.common.IEnumTerm;
35
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
36
import eu.etaxonomy.taxeditor.model.MessagingUtils;
37
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
38
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
39

    
40
/**
41
* <p>Abstract AbstractFilteredCdmEnumSelectionDialog class.</p>
42
*
43
* @author c.mathew
44
* @created 18.07.2013
45
* @version 1.0
46
*/
47
public abstract class AbstractFilteredCdmEnumSelectionDialog<T extends IEnumTerm> extends
48
		FilteredItemsSelectionDialog implements IConversationEnabled {
49

    
50
	private ConversationHolder conversation;
51

    
52
	protected List<T> model;	
53
	private String settings;	
54
	
55
	
56
	
57
	/**
58
	 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
59
	 *
60
	 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
61
	 * @param conversation 
62
	 * @param title a {@link java.lang.String} object.
63
	 * @param multi a boolean.
64
	 * @param settings a {@link java.lang.String} object.
65
	 * @param cdmEnum a T object.
66
	 * @param <T> a T object.
67
	 */
68
	protected AbstractFilteredCdmEnumSelectionDialog(Shell shell, 
69
			ConversationHolder conversation, 
70
			String title, 
71
			boolean multi, 
72
			String settings,
73
			T cdmEnum) {
74
		super(shell, multi);
75
		setTitle(title);
76
		setMessage("Use * for wildcard, or ? to see all entries");
77
		this.settings = settings;
78
		
79
		this.conversation = conversation;
80
		
81
		init();
82
		
83
		initModel();
84
		
85
		String objectTitle = getTitle(cdmEnum);
86
		if (objectTitle != null) {
87
			setInitialPattern(objectTitle);
88
		}
89
		
90
		setListLabelProvider(createListLabelProvider());
91
		setDetailsLabelProvider(createDetailsLabelProvider());
92
		
93
		setSelectionHistory(new ResourceSelectionHistory());
94
	}
95
	
96
	/**
97
	 * By default, we are returning the standard list label provider
98
	 * 
99
	 * Override in subclasses if you want different behavior 
100
	 * 
101
	 * @return
102
	 */
103
	protected ILabelProvider createDetailsLabelProvider() {
104
		return createListLabelProvider();
105
	}
106

    
107
	/**
108
	 * 
109
	 * @return
110
	 */
111
	protected ILabelProvider createListLabelProvider() {
112
		return new FilteredCdmResourceLabelProvider();
113
	}
114

    
115
	/**
116
	 * Override in subclasses.
117
	 * Will run before initModel()
118
	 */
119
	protected void init() {
120
		
121
	}
122
	
123
	/**
124
	 * <p>getSelectionFromDialog</p>
125
	 *
126
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
127
	 * @param <TYPE> a TYPE object.
128
	 * @return a TYPE object.
129
	 */
130
	protected static <TYPE extends IEnumTerm> TYPE getSelectionFromDialog(AbstractFilteredCdmEnumSelectionDialog<TYPE> dialog) {
131
		
132
		int result = dialog.open();
133
		
134
		if (result == Window.CANCEL) {
135
			return null;
136
		}
137
		
138
		return dialog.getSelectedEnumTerm();
139
	}
140

    
141

    
142
	/**
143
	 * <p>getTitle</p>
144
	 *
145
	 * @param cdmObject a T object.
146
	 * @return a {@link java.lang.String} object.
147
	 */
148
	protected String getTitle(T cdmEnum) {
149
		return cdmEnum.getMessage();
150
	}
151
	
152

    
153
	/** {@inheritDoc} */
154
	@Override
155
	public void refresh() {
156
		initModel();		
157
		super.refresh();
158
	}
159
	
160
	/**
161
	 * <p>initModel</p>
162
	 */
163
	abstract protected void initModel();
164

    
165
	/* (non-Javadoc)
166
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
167
	 */
168
	/** {@inheritDoc} */
169
	@Override
170
	protected ItemsFilter createFilter() {
171
		return new ItemsFilter() {
172

    
173
			/**
174
			 * Always returns false to enforce refiltering even if the pattern is equal
175
			 */
176
			@Override
177
			public boolean equalsFilter(ItemsFilter filter) {
178
				return false;
179
			}
180
			
181
			@Override
182
			public boolean isConsistentItem(Object item) {
183
				return false;
184
			}
185

    
186
			@Override
187
			public boolean matchItem(Object item) {
188
				String text = null;
189
				if(item instanceof IEnumTerm){
190
					text = ((IEnumTerm) item).getMessage();
191
				}else if(item instanceof String){
192
					text = (String) item;
193
				}
194
				return text != null ? matches(text) : false;
195
			}
196
			
197
		};
198
	}
199
	
200

    
201
	/**
202
	 * Set the filter input to the Agent's title cache
203
	 *
204
	 * @param cdmObject a T object.
205
	 */
206
	protected void setPattern(T cdmObject) {
207
		// FilteredSelection does some very tricky caching to make sure it 
208
		// runs with high performance. 
209
		// This works for most use cases, but we want to change the model while the dialog is open
210
		// and all the clever caching prevents the content provider from knowing that the model has changed
211
		// I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient 
212
		// way to solve the problem.
213
		try {
214
			Field lastCompletedFilter = this.getClass().getSuperclass().getSuperclass().getDeclaredField("lastCompletedFilter");
215
			lastCompletedFilter.setAccessible(true);
216
			lastCompletedFilter.set(this, null);
217
		} catch (SecurityException e) {
218
			MessagingUtils.error(getClass(), e);
219
		} catch (NoSuchFieldException e) {
220
			MessagingUtils.error(getClass(), e);
221
		} catch (IllegalArgumentException e) {
222
			MessagingUtils.error(getClass(), e);
223
		} catch (IllegalAccessException e) {
224
			MessagingUtils.error(getClass(), e);
225
		}
226
		
227
		// this also is not the nicest way to do it. 
228
		// I am still amazed, that FilteredSelectionDialog does not offer any methods to change its data
229
		// once it was opened. Am I doing it wrong?
230
		String pattern = getTitle(cdmObject);
231
		((Text) getPatternControl()).setText(pattern);
232
	}
233
	
234
	/* (non-Javadoc)
235
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
236
	*/
237
	/** {@inheritDoc} */
238
	@Override
239
	protected void fillContentProvider(AbstractContentProvider contentProvider,
240
		ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
241
		throws CoreException {
242
		try {
243
			if(model != null){				
244
				progressMonitor.beginTask("Looking for entities", model.size());
245
				for(T element : model){
246
					contentProvider.add(element, itemsFilter);
247
					if (progressMonitor.isCanceled()) {
248
						throw new OperationCanceledException();
249
					}
250
					progressMonitor.worked(1);
251
				}
252
			}else{
253
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
254
			}
255
		}
256
		finally {
257
			progressMonitor.done();
258
		}
259
	}
260

    
261
	/* (non-Javadoc)
262
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
263
	 */
264
	/** {@inheritDoc} */
265
	@Override
266
	protected IDialogSettings getDialogSettings() {
267
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
268

    
269
		if (settings == null) {
270
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
271
		}
272
		return settings;
273
	}
274

    
275
	/* (non-Javadoc)
276
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
277
	 */
278
	/** {@inheritDoc} */
279
	@Override
280
	public String getElementName(Object item) {
281
		return ((IEnumTerm) item).getMessage();
282
	}
283

    
284
	/* (non-Javadoc)
285
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
286
	 */
287
	/** {@inheritDoc} */
288
	@Override
289
	protected Comparator getItemsComparator() {
290
		return new Comparator<IEnumTerm>() {
291
			public int compare(IEnumTerm entity1,
292
					IEnumTerm entity2) {
293
				Collator collator = Collator.getInstance();
294
				return collator.compare(entity1.getMessage(), entity2.getMessage());
295
			}
296
		};
297
	}
298

    
299
	/* (non-Javadoc)
300
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)
301
	 */
302
	/** {@inheritDoc} */
303
	@Override
304
	protected IStatus validateItem(Object item) {
305
		return Status.OK_STATUS;
306
	}
307
	
308
	/**
309
	 * <p>getSelectedUuidAndTitleCache</p>
310
	 *
311
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
312
	 */
313
	protected T getSelectedEnumTerm() {
314
		Object[] result = getResult();
315
		return result[0] == null ? null : (T) result[0];
316
	}
317
	
318
	/**
319
	 * <p>Getter for the field <code>settings</code>.</p>
320
	 *
321
	 * @return a {@link java.lang.String} object.
322
	 */
323
	public String getSettings()  {
324
		if(settings == null){
325
			throw new IllegalStateException("No SETTINGS set.");
326
		}
327
		return settings;
328
	}
329
	
330
	/**
331
	 * 
332
	 * @author n.hoffmann
333
	 * @created Oct 19, 2009
334
	 * @version 1.0
335
	 */
336
	private class ResourceSelectionHistory extends SelectionHistory {
337
	    /*
338
	    * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#restoreItemFromMemento(org.eclipse.ui.IMemento)
339
	   	*/
340
		protected Object restoreItemFromMemento(IMemento element) {
341
			return element.getString("resource"); //$NON-NLS-1$
342
	  	}
343
	  	/*
344
	  	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object,
345
	  	 *      org.eclipse.ui.IMemento)
346
	  	 */
347
		protected void storeItemToMemento(Object item, IMemento element) {
348
			element.putString("resource", item.toString()); //$NON-NLS-1$
349
		}
350
	}
351
	
352
	/**
353
	 * <p>getNewWizardLinkText</p>
354
	 *
355
	 * @return a {@link java.lang.String} object.
356
	 */
357
	protected abstract String getNewWizardLinkText();
358
	
359
	/**
360
	 * <p>getNewEntityWizard</p>
361
	 * @param parameter 
362
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
363
	 */
364
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
365
	
366
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
367
		public String getText(Object element) {
368
			if (element == null) {
369
				return null;
370
			}
371
			return ((IEnumTerm) element).getMessage();
372
		}			
373
	};
374

    
375
	/* (non-Javadoc)
376
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
377
	*/
378
	/** {@inheritDoc} */
379
	@Override
380
	protected Control createExtendedContentArea(Composite parent) {
381
		if(getNewWizardLinkText() != null){
382
			Link link = new Link(parent, SWT.NONE);
383
			link.setText(getNewWizardLinkText());
384
			link.addSelectionListener(getNewWizardLinkSelectionListener());
385
			return link;
386
		}
387
		return null;
388
	}
389
	
390
	protected SelectionListener getNewWizardLinkSelectionListener(){
391
		return new SelectionAdapter() {
392
			
393
			/* (non-Javadoc)
394
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
395
			 */
396
			@Override
397
			public void widgetSelected(SelectionEvent e) {
398
				
399
				AbstractNewEntityWizard wizard = getNewEntityWizard(e.text);
400
				wizard.init(null, null);
401
				WizardDialog dialog = new WizardDialog(getShell(), wizard);
402
				int status = dialog.open();
403
				
404
				if (status == IStatus.OK) {
405
					
406
					T entity = (T) wizard.getEntity();
407

    
408
					refresh();
409
					setPattern(entity);
410
					getConversationHolder().bind();
411
				}
412
			}
413
		};
414
	}
415
	
416
	/**
417
	 * <p>getConversationHolder</p>
418
	 *
419
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
420
	 */
421
	public ConversationHolder getConversationHolder() {
422
		return conversation;
423
	}
424
	
425
	/** {@inheritDoc} */
426
	public void update(CdmDataChangeMap changeEvents) {}
427

    
428
}
(1-1/32)