2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
.ui
.dialog
.selection
;
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
;
20 import java
.util
.UUID
;
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
;
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
;
58 * <p>Abstract AbstractFilteredCdmResourceSelectionDialog class.</p>
64 public abstract class AbstractFilteredCdmResourceSelectionDialog
<T
extends ICdmBase
> extends
65 SearchDialog
{//implements IConversationEnabled {
67 // private final ConversationHolder conversation = null;
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;
74 private T selectedObject
;
76 protected T cdmBaseToBeFiltered
;
80 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
82 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
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.
90 protected AbstractFilteredCdmResourceSelectionDialog(Shell shell
, //ConversationHolder conversation,
91 String title
, boolean multi
, String settings
, T cdmObject
) {
93 setShellStyle(SWT
.DIALOG_TRIM
);
95 setMessage(Messages
.SearchDialog_patternLabel
);
96 this.settings
= settings
;
98 this.cdmBaseToBeFiltered
= cdmObject
;
99 Cursor cursor
= shell
.getCursor();
100 shell
.setCursor(shell
.getDisplay().getSystemCursor(SWT
.CURSOR_WAIT
));
102 shell
.setCursor(cursor
);
103 setListLabelProvider(createListLabelProvider());
108 * By default, we are returning the standard list label provider
110 * Override in subclasses if you want different behavior
114 protected ILabelProvider
createDetailsLabelProvider() {
115 return createListLabelProvider();
122 protected ILabelProvider
createListLabelProvider() {
123 return new FilteredCdmResourceLabelProvider();
127 * Override in subclasses.
128 * Will run before initModel()
130 protected void init() {
135 * <p>getSelectionFromDialog</p>
137 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
138 * @param <TYPE> a TYPE object.
139 * @return a TYPE object.
141 protected static <TYPE
extends CdmBase
> TYPE
getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog
<TYPE
> dialog
) {
142 int result
= dialog
.open();
144 if (result
== Window
.CANCEL
) {
148 UuidAndTitleCache uuid
= dialog
.getSelectedUuidAndTitleCache();
152 return dialog
.getCdmObjectByUuid(uuid
.getUuid());
156 * Check if object was created during the life of this dialog. If not,
157 * retrieve it from the CdmStore.
159 * @param cdmUuid a {@link java.util.UUID} object.
160 * @return a T object.
162 protected T
getCdmObjectByUuid(UUID cdmUuid
) {
163 for (T cdmObject
: transientCdmObjects
) {
164 if (cdmObject
.getUuid().equals(cdmUuid
)) {
168 return getPersistentObject(cdmUuid
);
172 * <p>getPersistentObject</p>
174 * @param uuid a {@link java.util.UUID} object.
175 * @return a T object.
177 abstract protected T
getPersistentObject(UUID uuid
);
181 * <p>isObjectTransient</p>
183 * @param cdmObject a T object.
186 protected boolean isObjectTransient(T cdmObject
) {
187 return (getPersistentObject(cdmObject
.getUuid()) == null);
193 * @param cdmObject a T object.
194 * @return a {@link java.lang.String} object.
196 protected String
getTitle(T cdmObject
) {
197 if(cdmObject
== null){
201 if (cdmObject
instanceof IIdentifiableEntity
) {
202 return ((IIdentifiableEntity
) cdmObject
).getTitleCache();
205 throw new IllegalArgumentException("Generic method only" +
206 " supports cdmObject of type IIdentifiableEntity." +
207 " Please implement specific method in subclass.");
213 * Set the filter input to the Agent's title cache
215 * @param cdmObject a T object.
217 protected void setPattern(T cdmObject
) {
218 String pattern
= getTitle(cdmObject
);
219 getSearchField().setText(pattern
);
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)
230 protected void fillContentProvider(IProgressMonitor progressMonitor
)
234 model
= new ArrayList
<UuidAndTitleCache
<T
>>();
237 if (progressMonitor
!= null){
238 progressMonitor
.beginTask("Looking for entities", model
.size());
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
);
250 if (progressMonitor
!= null){
251 if (progressMonitor
.isCanceled()) {
254 progressMonitor
.worked(1);
260 MessagingUtils
.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
264 if (progressMonitor
!= null) {
265 progressMonitor
.done();
271 protected void sort() {
272 Collections
.sort(model
, getItemsComparator());
276 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
280 protected IDialogSettings
getDialogSettings() {
281 IDialogSettings settings
= TaxeditorStorePlugin
.getDefault().getDialogSettings().getSection(getSettings());
283 if (settings
== null) {
284 settings
= TaxeditorStorePlugin
.getDefault().getDialogSettings().addNewSection(getSettings());
290 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
294 public String
getElementName(Object item
) {
295 return ((UuidAndTitleCache
) item
).getTitleCache();
299 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
304 protected Comparator
getItemsComparator() {
305 return new Comparator
<UuidAndTitleCache
>() {
307 public int compare(UuidAndTitleCache entity1
,
308 UuidAndTitleCache entity2
) {
309 Collator collator
= Collator
.getInstance();
310 if (entity1
== entity2
){
314 if (entity1
== null && entity2
!= null){
317 if (entity2
== null && entity1
!= null){
320 if (entity1
.getUuid().equals(entity2
.getUuid())){
323 if (entity1
.getTitleCache() == null && entity2
.getTitleCache() != null){
326 if (entity2
.getTitleCache() == null){
329 int result
= collator
.compare(entity1
.getTitleCache(), entity2
.getTitleCache());
331 result
= entity1
.getUuid().compareTo(entity2
.getUuid());
340 * <p>getSelectedUuidAndTitleCache</p>
342 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
344 protected UuidAndTitleCache
getSelectedUuidAndTitleCache() {
345 Object result
= getResult();
346 if (result
instanceof UuidAndTitleCache
){
347 return (UuidAndTitleCache
) result
;
355 private Object
getResult() {
356 StructuredSelection selection
= getCurrentSelection();
357 if (selection
== null){
360 return selection
.getFirstElement();
364 * <p>Getter for the field <code>settings</code>.</p>
366 * @return a {@link java.lang.String} object.
368 public String
getSettings() {
369 if(settings
== null){
370 throw new IllegalStateException("No SETTINGS set.");
378 * <p>getNewWizardLinkText</p>
380 * @return a {@link java.lang.String} object.
382 protected abstract String
[] getNewWizardText();
385 * <p>getNewEntityWizard</p>
387 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
389 protected abstract AbstractNewEntityWizard
getNewEntityWizard(String parameter
);
391 public class FilteredCdmResourceLabelProvider
extends LabelProvider
{
393 public String
getText(Object element
) {
394 if (element
== null) {
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()+"]";
407 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
412 // protected Control createExtendedContentArea(Composite parent) {
413 // String newWizardLinkText = getNewWizardLinkText();
414 //// if(newWizardLinkText != null){
415 //// newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
417 //// newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
418 //// return newButton1;
424 protected void createButtonsForButtonBar(Composite parent
) {
425 String
[] newButtonText
= getNewWizardText();
427 if (newButtonText
!= null){
428 this.newButton1
= createButton(parent
, this.new_id
, newButtonText
[0], false);
429 newButton1
.addSelectionListener(getNewWizardButtonSelectionListener());
432 if (newButtonText
.length
> 1){
433 newButton2
= createButton(parent
, this.new_id2
, newButtonText
[1], false);
434 newButton2
.addSelectionListener(getNewWizardButtonSelectionListener());
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;
451 gridLayout
.numColumns
=2;
453 parent
.setLayout(gridLayout
);
455 super.createButtonsForButtonBar(parent
);
458 protected SelectionListener
getNewWizardButtonSelectionListener(){
459 return new SelectionAdapter() {
462 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
465 public void widgetSelected(SelectionEvent e
) {
466 Object source
= e
.getSource();
468 if (source
instanceof Button
){
469 Button sourceButton
= (Button
) source
;
470 text
= sourceButton
.getText();
472 AbstractNewEntityWizard wizard
= getNewEntityWizard(text
);
474 wizard
.init(null, null);
475 if(wizard
.getEntity() != null) {
476 WizardDialog dialog
= new WizardDialog(getShell(), wizard
);
477 int status
= dialog
.open();
479 if (status
== IStatus
.OK
) {
481 T entity
= (T
) wizard
.getEntity();
484 // if (getConversationHolder() != null){
485 // getConversationHolder().bind();
488 //FIXME : Need to make sure this is a stable fix (ticket 3822)
489 // if (getConversationHolder() != null){
490 // getConversationHolder().commit();
499 * <p>getConversationHolder</p>
501 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
504 // public ConversationHolder getConversationHolder() {
505 // return conversation;
510 // public void update(CdmDataChangeMap changeEvents) {}
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.
518 private void filterExcludedObjects() {
519 if (model
!= null && cdmBaseToBeFiltered
!= null) {
521 UuidAndTitleCache uuidAndTitleCacheToRemove
= null;
523 for (UuidAndTitleCache uuidAndTitleCache
: model
){
524 if ((cdmBaseToBeFiltered
.getUuid()).equals(uuidAndTitleCache
.getUuid())) {
525 uuidAndTitleCacheToRemove
= uuidAndTitleCache
;
528 model
.remove(uuidAndTitleCacheToRemove
);
532 void createFilterButton(Composite searchAndFilter
){
533 //as default no filter button available
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("?")){
545 }else if (StringUtils
.isNotBlank(pattern
)){
546 callService(pattern
);
548 fillContentProvider(null);
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);
558 abstract void callService(String pattern
);