Project

General

Profile

Download (11 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
package eu.etaxonomy.taxeditor.ui.dialog.selection;
10

    
11
import java.lang.reflect.Field;
12
import java.text.Collator;
13
import java.util.Comparator;
14
import java.util.List;
15

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

    
38
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
39
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
40
import eu.etaxonomy.cdm.model.term.IEnumTerm;
41
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
42
import eu.etaxonomy.taxeditor.model.MessagingUtils;
43
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
44
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
45

    
46
/**
47
* <p>Abstract AbstractFilteredCdmEnumSelectionDialog class.</p>
48
*
49
* @author c.mathew
50
* @created 18.07.2013
51
*/
52
public abstract class AbstractFilteredCdmEnumSelectionDialog<T extends IEnumTerm> extends
53
		FilteredItemsSelectionDialog implements IConversationEnabled {
54

    
55
	private ConversationHolder conversation;
56

    
57
	protected List<T> model;
58
	private String settings;
59

    
60
	/**
61
	 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
62
	 *
63
	 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
64
	 * @param conversation
65
	 * @param title a {@link java.lang.String} object.
66
	 * @param multi a boolean.
67
	 * @param settings a {@link java.lang.String} object.
68
	 * @param cdmEnum a T object.
69
	 * @param <T> a T object.
70
	 */
71
	protected AbstractFilteredCdmEnumSelectionDialog(Shell shell,
72
			ConversationHolder conversation,
73
			String title,
74
			boolean multi,
75
			String settings,
76
			T cdmEnum) {
77
		super(shell, multi);
78
		setTitle(title);
79
		setMessage("Use * for wildcard, or ? to see all entries");
80
		this.settings = settings;
81

    
82
		this.conversation = conversation;
83

    
84
		init();
85

    
86
		initModel();
87

    
88
		String objectTitle = getTitle(cdmEnum);
89
		if (objectTitle != null) {
90
			setInitialPattern(objectTitle);
91
		}
92

    
93
		setListLabelProvider(createListLabelProvider());
94
		setDetailsLabelProvider(createDetailsLabelProvider());
95

    
96
		setSelectionHistory(new ResourceSelectionHistory());
97
	}
98

    
99
	/**
100
	 * By default, we are returning the standard list label provider
101
	 *
102
	 * Override in subclasses if you want different behavior
103
	 *
104
	 * @return
105
	 */
106
	protected ILabelProvider createDetailsLabelProvider() {
107
		return createListLabelProvider();
108
	}
109

    
110
	/**
111
	 *
112
	 * @return
113
	 */
114
	protected ILabelProvider createListLabelProvider() {
115
		return new FilteredCdmResourceLabelProvider();
116
	}
117

    
118
	/**
119
	 * Override in subclasses.
120
	 * Will run before initModel()
121
	 */
122
	protected void init() {
123

    
124
	}
125

    
126
	/**
127
	 * <p>getSelectionFromDialog</p>
128
	 *
129
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
130
	 * @param <TYPE> a TYPE object.
131
	 * @return a TYPE object.
132
	 */
133
	protected static <TYPE extends IEnumTerm> TYPE getSelectionFromDialog(AbstractFilteredCdmEnumSelectionDialog<TYPE> dialog) {
134

    
135
		int result = dialog.open();
136

    
137
		if (result == Window.CANCEL) {
138
			return null;
139
		}
140

    
141
		return dialog.getSelectedEnumTerm();
142
	}
143

    
144

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

    
155
	@Override
156
	public void refresh() {
157
		initModel();
158
		super.refresh();
159
	}
160

    
161
	/**
162
	 * <p>initModel</p>
163
	 */
164
	abstract protected void initModel();
165

    
166
	@Override
167
	protected ItemsFilter createFilter() {
168
		return new ItemsFilter() {
169

    
170
			/**
171
			 * Always returns false to enforce refiltering even if the pattern is equal
172
			 */
173
			@Override
174
			public boolean equalsFilter(ItemsFilter filter) {
175
				return false;
176
			}
177

    
178
			@Override
179
			public boolean isConsistentItem(Object item) {
180
				return false;
181
			}
182

    
183
			@Override
184
			public boolean matchItem(Object item) {
185
				String text = null;
186
				if(item instanceof IEnumTerm){
187
					text = ((IEnumTerm) item).getLabel();
188
				}else if(item instanceof String){
189
					text = (String) item;
190
				}
191
				return text != null ? matches(text) : false;
192
			}
193

    
194
		};
195
	}
196

    
197
	/**
198
	 * Set the filter input to the Agent's title cache
199
	 *
200
	 * @param cdmObject a T object.
201
	 */
202
	protected void setPattern(T cdmObject) {
203
		// FilteredSelection does some very tricky caching to make sure it
204
		// runs with high performance.
205
		// This works for most use cases, but we want to change the model while the dialog is open
206
		// and all the clever caching prevents the content provider from knowing that the model has changed
207
		// I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient
208
		// way to solve the problem.
209
		try {
210
			Field lastCompletedFilter = this.getClass().getSuperclass().getSuperclass().getDeclaredField("lastCompletedFilter");
211
			lastCompletedFilter.setAccessible(true);
212
			lastCompletedFilter.set(this, null);
213
		} catch (SecurityException e) {
214
			MessagingUtils.error(getClass(), e);
215
		} catch (NoSuchFieldException e) {
216
			MessagingUtils.error(getClass(), e);
217
		} catch (IllegalArgumentException e) {
218
			MessagingUtils.error(getClass(), e);
219
		} catch (IllegalAccessException e) {
220
			MessagingUtils.error(getClass(), e);
221
		}
222

    
223
		// this also is not the nicest way to do it.
224
		// I am still amazed, that FilteredSelectionDialog does not offer any methods to change its data
225
		// once it was opened. Am I doing it wrong?
226
		String pattern = getTitle(cdmObject);
227
		((Text) getPatternControl()).setText(pattern);
228
	}
229

    
230
	@Override
231
	protected void fillContentProvider(AbstractContentProvider contentProvider,
232
		ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
233
		throws CoreException {
234
		try {
235
			if(model != null){
236
				progressMonitor.beginTask("Looking for entities", model.size());
237
				for(T element : model){
238
					contentProvider.add(element, itemsFilter);
239
					if (progressMonitor.isCanceled()) {
240
						throw new OperationCanceledException();
241
					}
242
					progressMonitor.worked(1);
243
				}
244
			}else{
245
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
246
			}
247
		}
248
		finally {
249
			progressMonitor.done();
250
		}
251
	}
252

    
253
	@Override
254
	protected IDialogSettings getDialogSettings() {
255
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
256

    
257
		if (settings == null) {
258
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
259
		}
260
		return settings;
261
	}
262

    
263
	@Override
264
	public String getElementName(Object item) {
265
		return ((IEnumTerm) item).getLabel();
266
	}
267

    
268
	@Override
269
	protected Comparator getItemsComparator() {
270
		return new Comparator<IEnumTerm>() {
271
			@Override
272
            public int compare(IEnumTerm entity1,
273
					IEnumTerm entity2) {
274
				if (entity1.equals(entity2)){
275
				    return 0;
276
				}
277
			    Collator collator = Collator.getInstance();
278

    
279
				int result = collator.compare(entity1.getLabel(), entity2.getLabel());
280
				if (result == 0){
281
				    return entity1.getUuid().compareTo(entity2.getUuid());
282
				}
283
				return result;
284
			}
285
		};
286
	}
287

    
288
	/* (non-Javadoc)
289
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)
290
	 */
291
	/** {@inheritDoc} */
292
	@Override
293
	protected IStatus validateItem(Object item) {
294
		return Status.OK_STATUS;
295
	}
296

    
297
	/**
298
	 * <p>getSelectedUuidAndTitleCache</p>
299
	 *
300
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
301
	 */
302
	protected T getSelectedEnumTerm() {
303
		Object[] result = getResult();
304
		return result[0] == null ? null : (T) result[0];
305
	}
306

    
307
	/**
308
	 * <p>Getter for the field <code>settings</code>.</p>
309
	 *
310
	 * @return a {@link java.lang.String} object.
311
	 */
312
	public String getSettings()  {
313
		if(settings == null){
314
			throw new IllegalStateException("No SETTINGS set.");
315
		}
316
		return settings;
317
	}
318

    
319
	/**
320
	 *
321
	 * @author n.hoffmann
322
	 * @created Oct 19, 2009
323
	 * @version 1.0
324
	 */
325
	private class ResourceSelectionHistory extends SelectionHistory {
326
	    /*
327
	    * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#restoreItemFromMemento(org.eclipse.ui.IMemento)
328
	   	*/
329
		@Override
330
        protected Object restoreItemFromMemento(IMemento element) {
331
			return element.getString("resource"); //$NON-NLS-1$
332
	  	}
333
	  	/*
334
	  	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object,
335
	  	 *      org.eclipse.ui.IMemento)
336
	  	 */
337
		@Override
338
        protected void storeItemToMemento(Object item, IMemento element) {
339
			element.putString("resource", item.toString()); //$NON-NLS-1$
340
		}
341
	}
342

    
343
	/**
344
	 * <p>getNewWizardLinkText</p>
345
	 *
346
	 * @return a {@link java.lang.String} object.
347
	 */
348
	protected abstract String getNewWizardLinkText();
349

    
350
	/**
351
	 * <p>getNewEntityWizard</p>
352
	 * @param parameter
353
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
354
	 */
355
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
356

    
357
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
358
		@Override
359
        public String getText(Object element) {
360
			if (element == null) {
361
				return null;
362
			}
363
			return ((IEnumTerm) element).getLabel();
364
		}
365
	};
366

    
367
	@Override
368
	protected Control createExtendedContentArea(Composite parent) {
369
		if(getNewWizardLinkText() != null){
370
			Link link = new Link(parent, SWT.NONE);
371
			link.setText(getNewWizardLinkText());
372
			link.addSelectionListener(getNewWizardLinkSelectionListener());
373
			return link;
374
		}
375
		return null;
376
	}
377

    
378
	protected SelectionListener getNewWizardLinkSelectionListener(){
379
		return new SelectionAdapter() {
380

    
381
			@Override
382
			public void widgetSelected(SelectionEvent e) {
383

    
384
				AbstractNewEntityWizard<T> wizard = getNewEntityWizard(e.text);
385
				wizard.init(null, null);
386
				WizardDialog dialog = new WizardDialog(getShell(), wizard);
387
				int status = dialog.open();
388

    
389
				if (status == IStatus.OK) {
390

    
391
					T entity = (T) wizard.getEntity();
392

    
393
					refresh();
394
					setPattern(entity);
395
					getConversationHolder().bind();
396
				}
397
			}
398
		};
399
	}
400

    
401
	/**
402
	 * <p>getConversationHolder</p>
403
	 *
404
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
405
	 */
406
	@Override
407
    public ConversationHolder getConversationHolder() {
408
		return conversation;
409
	}
410

    
411
	@Override
412
    public void update(CdmDataChangeMap changeEvents) {}
413
}
(1-1/46)