/** * */ package org.nightlabs.jfire.issuetracking.ui.issuelink; import org.eclipse.core.runtime.ListenerList; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Composite; import org.nightlabs.base.ui.message.IErrorMessageDisplayer; /** * This class should be subclassed to create a composite that can contain the UI * for selecting the object to be linked to an issue. * <p> * Normally, The UI created in the adder composite is an instance of <link>SearchEntryViewer</link> * that has the seach button to do searching. * </p> * * @author Chairat Kongarayawetchakun - chairat at nightlabs dot de */ public abstract class AbstractIssueLinkAdder implements IssueLinkAdder { private IssueLinkHandlerFactory issueLinkHandlerFactory; private ListenerList selectionDoubleClickListeners = new ListenerList(); private IErrorMessageDisplayer errorMessageDisplayer; /** * */ public void init(IssueLinkHandlerFactory issueLinkHandlerFactory) { this.issueLinkHandlerFactory = issueLinkHandlerFactory; } /** * Gets the {@link IssueLinkHandlerFactory}. * @return the {@link IssueLinkHandlerFactory} */ public IssueLinkHandlerFactory getIssueLinkHandlerFactory() { return issueLinkHandlerFactory; } private Composite composite = null; /** * Creates the composite and then calls the search function to show elements for choosing. */ public Composite createComposite(Composite parent) { if (composite != null) throw new IllegalStateException("createComposite(...) has already been called! Have already a composite!"); //$NON-NLS-1$ composite = doCreateComposite(parent); // by default no search should be performed after having clicked just on a entry of the available // IssueLinkHandlers. Search can be a very expensive operation especially when no criteria is specified. (Daniel) // doSearch(); composite.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { ((Composite)e.getSource()).removeDisposeListener(this); onDispose(); } }); return composite; } /** * This method is called by {@link #createComposite(Composite)}. * Implement it and return a new instance * of <tt>Composite</tt>. * * @param parent The parent <tt>Composite</tt> for the new <tt>Composite</tt>. * @return The newly created <tt>Composite</tt>. */ protected abstract Composite doCreateComposite(Composite parent); /** * This method does searching thing to choose the object to be linked. * Implement it and do searching thing in its. */ protected abstract void doSearch(); public void dispose() { if (composite != null) composite.dispose(); } /** * {@inheritDoc} */ public Composite getComposite() { return composite; } public void onDispose() { composite = null; } private ListenerList selectionChangedListeners = new ListenerList(); @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.add(listener); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.remove(listener); } @Override public IStructuredSelection getSelection() { return new StructuredSelection(getLinkedObjectIDs()); } @Override public void setSelection(ISelection selection) { // no-op } protected void fireSelectionChangedEvent() { SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection()); for (Object l : selectionChangedListeners.getListeners()) ((ISelectionChangedListener ) l).selectionChanged(event); } /** * */ public void addIssueLinkDoubleClickListener(IssueLinkDoubleClickListener listener) { selectionDoubleClickListeners.add(listener); } /** * */ public void removeIssueLinkDoubleClickListener(IssueLinkDoubleClickListener listener) { selectionDoubleClickListeners.remove(listener); } public void notifyIssueLinkDoubleClickListeners() { Object[] listeners = selectionDoubleClickListeners.getListeners(); IssueLinkDoubleClickedEvent evt = new IssueLinkDoubleClickedEvent(this); for (Object l : listeners) { if (l instanceof IssueLinkDoubleClickListener) { ((IssueLinkDoubleClickListener) l).issueLinkDoubleClicked(evt); } } } @Override public void setErrorMessageDisplayer(IErrorMessageDisplayer displayer) { this.errorMessageDisplayer = displayer; } @Override public IErrorMessageDisplayer getErrorMessageDisplayer() { return errorMessageDisplayer; } }