Revision 496d0049
Added by Patrick Plitzner over 10 years ago
- fixed the link in CollectionSelectionDialog and InstitutionSelectionDialog to create a new entity
- found strange bug in org.eclipse.swt.widgets.Link described in Ticket #3691
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/selection/AbstractFilteredCdmResourceSelectionDialog.java | ||
---|---|---|
1 | 1 |
// $Id$ |
2 | 2 |
/** |
3 | 3 |
* Copyright (C) 2007 EDIT |
4 |
* European Distributed Institute of Taxonomy
|
|
4 |
* European Distributed Institute of Taxonomy |
|
5 | 5 |
* http://www.e-taxonomy.eu |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
8 | 8 |
* See LICENSE.TXT at the top of this package for the full license terms. |
9 | 9 |
*/ |
... | ... | |
47 | 47 |
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity; |
48 | 48 |
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache; |
49 | 49 |
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap; |
50 |
import eu.etaxonomy.taxeditor.model.AbstractUtility; |
|
50 | 51 |
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard; |
51 |
import eu.etaxonomy.taxeditor.store.StoreUtil; |
|
52 | 52 |
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin; |
53 | 53 |
|
54 | 54 |
/** |
... | ... | |
61 | 61 |
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase> extends |
62 | 62 |
FilteredItemsSelectionDialog implements IConversationEnabled { |
63 | 63 |
|
64 |
private ConversationHolder conversation; |
|
64 |
private final ConversationHolder conversation;
|
|
65 | 65 |
|
66 | 66 |
protected List<UuidAndTitleCache<T>> model; |
67 |
private Set<T> transientCdmObjects = new HashSet<T>(); |
|
68 |
private String settings;
|
|
69 |
|
|
67 |
private final Set<T> transientCdmObjects = new HashSet<T>();
|
|
68 |
private final String settings;
|
|
69 |
|
|
70 | 70 |
protected T cdmBaseToBeFiltered; |
71 |
|
|
71 |
|
|
72 | 72 |
/** |
73 | 73 |
* <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p> |
74 | 74 |
* |
75 | 75 |
* @param shell a {@link org.eclipse.swt.widgets.Shell} object. |
76 |
* @param conversation
|
|
76 |
* @param conversation |
|
77 | 77 |
* @param title a {@link java.lang.String} object. |
78 | 78 |
* @param multi a boolean. |
79 | 79 |
* @param settings a {@link java.lang.String} object. |
... | ... | |
85 | 85 |
setTitle(title); |
86 | 86 |
setMessage("Use * for wildcard, or ? to see all entries"); |
87 | 87 |
this.settings = settings; |
88 |
|
|
88 |
|
|
89 | 89 |
this.conversation = conversation; |
90 |
|
|
90 |
|
|
91 | 91 |
init(); |
92 |
|
|
92 |
|
|
93 | 93 |
initModel(); |
94 |
|
|
94 |
|
|
95 | 95 |
String objectTitle = getTitle(cdmObject); |
96 | 96 |
if (objectTitle != null) { |
97 | 97 |
setInitialPattern(objectTitle); |
98 | 98 |
} |
99 |
|
|
99 |
|
|
100 | 100 |
setListLabelProvider(createListLabelProvider()); |
101 | 101 |
setDetailsLabelProvider(createDetailsLabelProvider()); |
102 |
|
|
102 |
|
|
103 | 103 |
setSelectionHistory(new ResourceSelectionHistory()); |
104 | 104 |
} |
105 |
|
|
105 |
|
|
106 | 106 |
/** |
107 | 107 |
* By default, we are returning the standard list label provider |
108 |
*
|
|
109 |
* Override in subclasses if you want different behavior
|
|
110 |
*
|
|
108 |
* |
|
109 |
* Override in subclasses if you want different behavior |
|
110 |
* |
|
111 | 111 |
* @return |
112 | 112 |
*/ |
113 | 113 |
protected ILabelProvider createDetailsLabelProvider() { |
... | ... | |
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
/** |
118 |
*
|
|
118 |
* |
|
119 | 119 |
* @return |
120 | 120 |
*/ |
121 | 121 |
protected ILabelProvider createListLabelProvider() { |
... | ... | |
127 | 127 |
* Will run before initModel() |
128 | 128 |
*/ |
129 | 129 |
protected void init() { |
130 |
|
|
130 |
|
|
131 | 131 |
} |
132 |
|
|
132 |
|
|
133 | 133 |
/** |
134 | 134 |
* <p>getSelectionFromDialog</p> |
135 | 135 |
* |
... | ... | |
140 | 140 |
protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) { |
141 | 141 |
//dialog.setInitialPattern(""); |
142 | 142 |
int result = dialog.open(); |
143 |
|
|
143 |
|
|
144 | 144 |
if (result == Window.CANCEL) { |
145 | 145 |
return null; |
146 | 146 |
} |
147 |
|
|
147 |
|
|
148 | 148 |
UUID uuid = dialog.getSelectedUuidAndTitleCache().getUuid(); |
149 | 149 |
if(uuid == null){ |
150 | 150 |
return null; |
151 |
}
|
|
151 |
} |
|
152 | 152 |
return dialog.getCdmObjectByUuid(uuid); |
153 | 153 |
} |
154 |
|
|
154 |
|
|
155 | 155 |
/** |
156 | 156 |
* Check if object was created during the life of this dialog. If not, |
157 | 157 |
* retrieve it from the CdmStore. |
... | ... | |
167 | 167 |
} |
168 | 168 |
return getPersistentObject(cdmUuid); |
169 | 169 |
} |
170 |
|
|
170 |
|
|
171 | 171 |
/** |
172 | 172 |
* <p>getPersistentObject</p> |
173 | 173 |
* |
... | ... | |
204 | 204 |
if(cdmObject == null){ |
205 | 205 |
return ""; |
206 | 206 |
} |
207 |
|
|
207 |
|
|
208 | 208 |
if (cdmObject instanceof IIdentifiableEntity) { |
209 |
return ((IIdentifiableEntity) cdmObject).getTitleCache();
|
|
209 |
return ((IIdentifiableEntity) cdmObject).getTitleCache(); |
|
210 | 210 |
} |
211 |
|
|
211 |
|
|
212 | 212 |
throw new IllegalArgumentException("Generic method only" + |
213 | 213 |
" supports cdmObject of type IIdentifiableEntity." + |
214 | 214 |
" Please implement specific method in subclass."); |
215 | 215 |
} |
216 |
|
|
216 |
|
|
217 | 217 |
|
218 | 218 |
/** {@inheritDoc} */ |
219 | 219 |
@Override |
... | ... | |
222 | 222 |
filterExcludedObjects(); |
223 | 223 |
super.refresh(); |
224 | 224 |
} |
225 |
|
|
225 |
|
|
226 | 226 |
/** |
227 | 227 |
* <p>initModel</p> |
228 | 228 |
*/ |
... | ... | |
243 | 243 |
public boolean equalsFilter(ItemsFilter filter) { |
244 | 244 |
return false; |
245 | 245 |
} |
246 |
|
|
246 |
|
|
247 | 247 |
@Override |
248 | 248 |
public boolean isConsistentItem(Object item) { |
249 | 249 |
return false; |
... | ... | |
259 | 259 |
} |
260 | 260 |
return text != null ? matches(text) : false; |
261 | 261 |
} |
262 |
|
|
262 |
|
|
263 | 263 |
}; |
264 | 264 |
} |
265 |
|
|
265 |
|
|
266 | 266 |
|
267 | 267 |
/** |
268 | 268 |
* Set the filter input to the Agent's title cache |
... | ... | |
270 | 270 |
* @param cdmObject a T object. |
271 | 271 |
*/ |
272 | 272 |
protected void setPattern(T cdmObject) { |
273 |
// FilteredSelection does some very tricky caching to make sure it
|
|
274 |
// runs with high performance.
|
|
273 |
// FilteredSelection does some very tricky caching to make sure it |
|
274 |
// runs with high performance. |
|
275 | 275 |
// This works for most use cases, but we want to change the model while the dialog is open |
276 | 276 |
// and all the clever caching prevents the content provider from knowing that the model has changed |
277 |
// I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient
|
|
277 |
// I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient |
|
278 | 278 |
// way to solve the problem. |
279 | 279 |
try { |
280 | 280 |
Field lastCompletedFilter = this.getClass().getSuperclass().getSuperclass().getDeclaredField("lastCompletedFilter"); |
281 | 281 |
lastCompletedFilter.setAccessible(true); |
282 | 282 |
lastCompletedFilter.set(this, null); |
283 | 283 |
} catch (SecurityException e) { |
284 |
StoreUtil.error(getClass(), e);
|
|
284 |
AbstractUtility.error(getClass(), e);
|
|
285 | 285 |
} catch (NoSuchFieldException e) { |
286 |
StoreUtil.error(getClass(), e);
|
|
286 |
AbstractUtility.error(getClass(), e);
|
|
287 | 287 |
} catch (IllegalArgumentException e) { |
288 |
StoreUtil.error(getClass(), e);
|
|
288 |
AbstractUtility.error(getClass(), e);
|
|
289 | 289 |
} catch (IllegalAccessException e) { |
290 |
StoreUtil.error(getClass(), e);
|
|
290 |
AbstractUtility.error(getClass(), e);
|
|
291 | 291 |
} |
292 |
|
|
293 |
// this also is not the nicest way to do it.
|
|
292 |
|
|
293 |
// this also is not the nicest way to do it. |
|
294 | 294 |
// I am still amazed, that FilteredSelectionDialog does not offer any methods to change its data |
295 | 295 |
// once it was opened. Am I doing it wrong? |
296 | 296 |
String pattern = getTitle(cdmObject); |
297 | 297 |
((Text) getPatternControl()).setText(pattern); |
298 | 298 |
} |
299 |
|
|
299 |
|
|
300 | 300 |
/* (non-Javadoc) |
301 | 301 |
* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor) |
302 | 302 |
*/ |
... | ... | |
306 | 306 |
ItemsFilter itemsFilter, IProgressMonitor progressMonitor) |
307 | 307 |
throws CoreException { |
308 | 308 |
try { |
309 |
if(model != null){
|
|
309 |
if(model != null){ |
|
310 | 310 |
progressMonitor.beginTask("Looking for entities", model.size()); |
311 | 311 |
for(UuidAndTitleCache<T> element : model){ |
312 | 312 |
contentProvider.add(element, itemsFilter); |
... | ... | |
316 | 316 |
progressMonitor.worked(1); |
317 | 317 |
} |
318 | 318 |
}else{ |
319 |
StoreUtil.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
|
|
319 |
AbstractUtility.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
|
|
320 | 320 |
} |
321 | 321 |
} |
322 | 322 |
finally { |
... | ... | |
354 | 354 |
@Override |
355 | 355 |
protected Comparator getItemsComparator() { |
356 | 356 |
return new Comparator<UuidAndTitleCache>() { |
357 |
public int compare(UuidAndTitleCache entity1, |
|
357 |
@Override |
|
358 |
public int compare(UuidAndTitleCache entity1, |
|
358 | 359 |
UuidAndTitleCache entity2) { |
359 | 360 |
Collator collator = Collator.getInstance(); |
360 | 361 |
return collator.compare(entity1.getTitleCache(), entity2.getTitleCache()); |
... | ... | |
370 | 371 |
protected IStatus validateItem(Object item) { |
371 | 372 |
return Status.OK_STATUS; |
372 | 373 |
} |
373 |
|
|
374 |
|
|
374 | 375 |
/** |
375 | 376 |
* <p>getSelectedUuidAndTitleCache</p> |
376 | 377 |
* |
... | ... | |
380 | 381 |
Object[] result = getResult(); |
381 | 382 |
return result[0] == null ? null : (UuidAndTitleCache) result[0]; |
382 | 383 |
} |
383 |
|
|
384 |
|
|
384 | 385 |
/** |
385 | 386 |
* <p>Getter for the field <code>settings</code>.</p> |
386 | 387 |
* |
... | ... | |
392 | 393 |
} |
393 | 394 |
return settings; |
394 | 395 |
} |
395 |
|
|
396 |
|
|
396 | 397 |
/** |
397 |
*
|
|
398 |
* |
|
398 | 399 |
* @author n.hoffmann |
399 | 400 |
* @created Oct 19, 2009 |
400 | 401 |
* @version 1.0 |
... | ... | |
403 | 404 |
/* |
404 | 405 |
* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#restoreItemFromMemento(org.eclipse.ui.IMemento) |
405 | 406 |
*/ |
406 |
protected Object restoreItemFromMemento(IMemento element) { |
|
407 |
@Override |
|
408 |
protected Object restoreItemFromMemento(IMemento element) { |
|
407 | 409 |
return element.getString("resource"); //$NON-NLS-1$ |
408 | 410 |
} |
409 | 411 |
/* |
410 | 412 |
* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object, |
411 | 413 |
* org.eclipse.ui.IMemento) |
412 | 414 |
*/ |
413 |
protected void storeItemToMemento(Object item, IMemento element) { |
|
415 |
@Override |
|
416 |
protected void storeItemToMemento(Object item, IMemento element) { |
|
414 | 417 |
element.putString("resource", item.toString()); //$NON-NLS-1$ |
415 | 418 |
} |
416 | 419 |
} |
417 |
|
|
420 |
|
|
418 | 421 |
/** |
419 | 422 |
* <p>getNewWizardLinkText</p> |
420 | 423 |
* |
421 | 424 |
* @return a {@link java.lang.String} object. |
422 | 425 |
*/ |
423 | 426 |
protected abstract String getNewWizardLinkText(); |
424 |
|
|
427 |
|
|
425 | 428 |
/** |
426 | 429 |
* <p>getNewEntityWizard</p> |
427 |
* @param parameter
|
|
430 |
* @param parameter |
|
428 | 431 |
* @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object. |
429 | 432 |
*/ |
430 | 433 |
protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter); |
431 |
|
|
434 |
|
|
432 | 435 |
public class FilteredCdmResourceLabelProvider extends LabelProvider { |
433 |
public String getText(Object element) { |
|
436 |
@Override |
|
437 |
public String getText(Object element) { |
|
434 | 438 |
if (element == null) { |
435 | 439 |
return null; |
436 | 440 |
} |
437 | 441 |
return ((UuidAndTitleCache) element).getTitleCache(); |
438 |
}
|
|
442 |
} |
|
439 | 443 |
}; |
440 | 444 |
|
441 | 445 |
/* (non-Javadoc) |
... | ... | |
444 | 448 |
/** {@inheritDoc} */ |
445 | 449 |
@Override |
446 | 450 |
protected Control createExtendedContentArea(Composite parent) { |
447 |
if(getNewWizardLinkText() != null){ |
|
451 |
String newWizardLinkText = getNewWizardLinkText(); |
|
452 |
if(newWizardLinkText != null){ |
|
448 | 453 |
Link link = new Link(parent, SWT.NONE); |
449 |
link.setText(getNewWizardLinkText());
|
|
454 |
link.setText(newWizardLinkText);
|
|
450 | 455 |
link.addSelectionListener(getNewWizardLinkSelectionListener()); |
451 | 456 |
return link; |
452 | 457 |
} |
453 | 458 |
return null; |
454 | 459 |
} |
455 |
|
|
460 |
|
|
456 | 461 |
protected SelectionListener getNewWizardLinkSelectionListener(){ |
457 | 462 |
return new SelectionAdapter() { |
458 |
|
|
463 |
|
|
459 | 464 |
/* (non-Javadoc) |
460 | 465 |
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
461 | 466 |
*/ |
462 | 467 |
@Override |
463 | 468 |
public void widgetSelected(SelectionEvent e) { |
464 |
|
|
469 |
|
|
465 | 470 |
AbstractNewEntityWizard wizard = getNewEntityWizard(e.text); |
466 | 471 |
wizard.init(null, null); |
467 | 472 |
WizardDialog dialog = new WizardDialog(getShell(), wizard); |
468 | 473 |
int status = dialog.open(); |
469 |
|
|
474 |
|
|
470 | 475 |
if (status == IStatus.OK) { |
471 |
|
|
476 |
|
|
472 | 477 |
T entity = (T) wizard.getEntity(); |
473 |
|
|
478 |
|
|
474 | 479 |
// addObjectToModel(teamOrPerson); |
475 | 480 |
refresh(); |
476 | 481 |
setPattern(entity); |
... | ... | |
479 | 484 |
} |
480 | 485 |
}; |
481 | 486 |
} |
482 |
|
|
487 |
|
|
483 | 488 |
/** |
484 | 489 |
* <p>getConversationHolder</p> |
485 | 490 |
* |
486 | 491 |
* @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object. |
487 | 492 |
*/ |
488 |
public ConversationHolder getConversationHolder() { |
|
493 |
@Override |
|
494 |
public ConversationHolder getConversationHolder() { |
|
489 | 495 |
return conversation; |
490 | 496 |
} |
491 |
|
|
497 |
|
|
492 | 498 |
/** {@inheritDoc} */ |
493 |
public void update(CdmDataChangeMap changeEvents) {} |
|
499 |
@Override |
|
500 |
public void update(CdmDataChangeMap changeEvents) {} |
|
494 | 501 |
|
495 | 502 |
/** |
496 |
* Don't want to add for example a taxon or synonym to itself
|
|
497 |
* so filter the list to remove the taxon in question
|
|
503 |
* Don't want to add for example a taxon or synonym to itself |
|
504 |
* so filter the list to remove the taxon in question |
|
498 | 505 |
* (<code>cdmBaseToBeFiltered</code>) |
499 | 506 |
* so it is not available in the filtered list. |
500 | 507 |
*/ |
501 | 508 |
private void filterExcludedObjects() { |
502 | 509 |
if (model != null && cdmBaseToBeFiltered != null) { |
503 |
|
|
510 |
|
|
504 | 511 |
UuidAndTitleCache uuidAndTitleCacheToRemove = null; |
505 |
|
|
512 |
|
|
506 | 513 |
for (UuidAndTitleCache uuidAndTitleCache : model){ |
507 | 514 |
if ((cdmBaseToBeFiltered.getUuid()).equals(uuidAndTitleCache.getUuid())) { |
508 | 515 |
uuidAndTitleCacheToRemove = uuidAndTitleCache; |
509 |
}
|
|
516 |
} |
|
510 | 517 |
} |
511 | 518 |
model.remove(uuidAndTitleCacheToRemove); |
512 | 519 |
} |
Also available in: Unified diff