| /******************************************************************************* |
| * Copyright (c) 2008, 2011 Obeo. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.emf.eef.runtime.ui.widgets; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.eef.runtime.impl.utils.ModelViewerHelper; |
| import org.eclipse.emf.eef.runtime.ui.utils.EEFLabelProvider; |
| import org.eclipse.emf.eef.runtime.ui.utils.EEFRuntimeUIMessages; |
| import org.eclipse.emf.eef.runtime.ui.widgets.referencestable.ReferencesTableSettings; |
| import org.eclipse.emf.eef.runtime.ui.widgets.settings.AdvancedEEFEditorContentProvider; |
| import org.eclipse.emf.eef.runtime.ui.widgets.settings.EEFEditorSettings; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.viewers.AbstractTreeViewer; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.dialogs.FilteredTree; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| |
| /** |
| * This dialog shows the tree of all owned element by taking in account a filter |
| * |
| * @author Patrick Tessier |
| * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a> |
| * @author <a href="mailto:stephane.bouchet@obeo.fr">Stephane Bouchet</a> |
| * @author <a href="mailto:stephane.thibaudeau@obeo.fr">Stephane Thibaudeau</a> |
| */ |
| public abstract class ElementSelectionDialog extends Dialog implements IPropertiesFilteredWidget { |
| |
| /** |
| * the label |
| */ |
| protected Label label; |
| |
| /** |
| * The selection tree. |
| */ |
| protected Tree tree; |
| |
| /** title of the window */ |
| protected String title = EEFRuntimeUIMessages.TabElementTreeSelectionDialog_title; |
| |
| /** |
| * filters |
| */ |
| private List<ViewerFilter> viewerFilters; |
| |
| /** |
| * business rules filters |
| */ |
| private List<ViewerFilter> brFilters; |
| |
| /** |
| * The adapter factory. |
| */ |
| protected AdapterFactory adapterFactory; |
| |
| private Composite parent; |
| |
| private Object input; |
| |
| private IStructuredSelection selection; |
| |
| /** |
| * Constructor with parent shell and Element. |
| * |
| * @param parentElement |
| * the element where we look for a children |
| * @param filters |
| * this is an array of filter see {@link ViewerFilter} or an example {@link OperationFilter} |
| * @param title |
| * title of the window |
| * @param createElement |
| * this is the listener to create an element |
| * @param abstractElement |
| * it used to inform about if the element is abstract in this case the creation button does not |
| * appear |
| * @param mainResource |
| * the main resource. |
| */ |
| public ElementSelectionDialog(Object input, List<ViewerFilter> filters, |
| List<ViewerFilter> brFilters, String title, AdapterFactory adapterFactory) { |
| super(Display.getDefault().getActiveShell()); |
| // add the resize ability to the window |
| setShellStyle(SWT.RESIZE | super.getShellStyle()); |
| this.input = input; |
| this.viewerFilters = filters; |
| this.brFilters = brFilters; |
| this.title = title; |
| this.adapterFactory = adapterFactory; |
| } |
| |
| /** |
| * Creates the dialog area. |
| * |
| * @param parent |
| * composite. |
| * @return control Control. |
| */ |
| protected Control createDialogArea(Composite parent) { |
| this.parent = parent; |
| |
| return fillModelpage(parent); |
| } |
| |
| /** |
| * Used to display a page |
| * |
| * @param parent |
| * composite which contains the tree |
| * @return the composite of this page |
| */ |
| public Control fillModelpage(Composite parent) { |
| Composite composite = new Composite(parent, SWT.None); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| composite.setLayout(layout); |
| |
| // use pattern filter |
| PatternFilter patternFilter = new TreeSelectionPatternFilter(); |
| patternFilter.setIncludeLeadingWildcard(true); |
| |
| FilteredTree filteredTree = new FilteredTree(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL |
| | SWT.RESIZE, patternFilter, true); |
| // use of EMF facilities |
| final TreeViewer treeViewer = filteredTree.getViewer(); |
| treeViewer.setFilters(new ViewerFilter[0]); |
| treeViewer.setUseHashlookup(true); |
| if (input instanceof EEFEditorSettings) |
| treeViewer.setContentProvider(new HideResourcesContentProvider(new AdvancedEEFEditorContentProvider(adapterFactory))); |
| else |
| treeViewer.setContentProvider(new HideResourcesContentProvider(new AdapterFactoryContentProvider(adapterFactory))); |
| |
| ArrayList<ViewerFilter> filters = new ArrayList<ViewerFilter>(); |
| if (viewerFilters != null && !viewerFilters.isEmpty()) { |
| for (ViewerFilter filter : viewerFilters) { |
| filters.add(filter); |
| } |
| } |
| // for now, add the businessRuleFilters to the 'normal' filters |
| if (brFilters != null && !brFilters.isEmpty()) { |
| for (ViewerFilter filter : brFilters) { |
| filters.add(filter); |
| } |
| } |
| filters.add(patternFilter); |
| ViewerFilter[] v = filters.toArray(new ViewerFilter[filters.size()]); |
| treeViewer.setFilters(v); |
| treeViewer.setLabelProvider(new EEFLabelProvider() { |
| |
| @Override |
| public Color getForeground(Object element) { |
| if (input instanceof ReferencesTableSettings && element instanceof EObject && ((ReferencesTableSettings) input).contains((EObject) element)) { |
| return getShell().getDisplay() |
| .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); |
| } |
| |
| return super.getForeground(element); |
| } |
| |
| }); |
| |
| filteredTree.setLayoutData(new GridData(550, 300)); |
| // handle selection change |
| if (input instanceof EEFEditorSettings) { |
| treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| if (event.getSelection() instanceof IStructuredSelection) { |
| // Check selection |
| IStructuredSelection structuredSelection = (IStructuredSelection)event.getSelection(); |
| if (structuredSelection != null && !structuredSelection.isEmpty()) { |
| Object o = structuredSelection.getFirstElement(); |
| // Check type matching |
| Button okButton = getButton(IDialogConstants.OK_ID); |
| if (((List<?>)((EEFEditorSettings)input).choiceOfValues(adapterFactory)).contains(o)) { |
| if (input instanceof ReferencesTableSettings) { |
| if (o instanceof EObject && !((ReferencesTableSettings) input).contains((EObject) o)) { |
| selection = structuredSelection; |
| if (okButton != null) { |
| okButton.setEnabled(true); |
| } |
| } else { |
| // Reject selection |
| if (okButton != null) { |
| okButton.setEnabled(false); |
| } |
| } |
| } else { |
| selection = structuredSelection; |
| if (okButton != null) { |
| okButton.setEnabled(true); |
| } |
| } |
| } else { |
| // Reject selection |
| if (okButton != null) { |
| okButton.setEnabled(false); |
| } |
| } |
| } |
| |
| } |
| } |
| }); |
| |
| // handle double click to validate |
| treeViewer.addDoubleClickListener(new IDoubleClickListener() { |
| public void doubleClick(DoubleClickEvent event) { |
| if (selection != null && !selection.isEmpty()) { |
| Object o = selection.getFirstElement(); |
| if (((List<?>)((EEFEditorSettings)input).choiceOfValues(adapterFactory)).contains(o) && input instanceof ReferencesTableSettings && o instanceof EObject && !((ReferencesTableSettings) input).contains((EObject) o)) { |
| okPressed(); |
| } |
| } |
| } |
| }); |
| } |
| treeViewer.setInput(input); |
| |
| // Init selected element |
| if (selection != null) { |
| treeViewer.setSelection(selection); |
| } |
| |
| return composite; |
| |
| } |
| |
| /** |
| * ContentProvider which delegates almost everything to another ContentProvider. |
| * The purpose is to hide the Resource and display only their contents |
| * |
| */ |
| private class HideResourcesContentProvider implements ITreeContentProvider { |
| private ITreeContentProvider delegateContentProvider; |
| |
| public HideResourcesContentProvider(ITreeContentProvider delegateContentProvider) { |
| this.delegateContentProvider = delegateContentProvider; |
| } |
| |
| public Object[] getElements(Object inputElement) { |
| // Retrieve elements provided by the delegate content provider |
| Object[] elements = delegateContentProvider.getElements(inputElement); |
| List<Object> newElements = new ArrayList<Object>(); |
| for (Object element : elements) { |
| // When an element is a resource, return its contents instead of the resource itself |
| if (element instanceof Resource) { |
| newElements.addAll(((Resource)element).getContents()); |
| } else { |
| newElements.add(element); |
| } |
| } |
| return newElements.toArray(); |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| delegateContentProvider.inputChanged(viewer, oldInput, newInput); |
| } |
| |
| public Object[] getChildren(Object parentElement) { |
| return delegateContentProvider.getChildren(parentElement); |
| } |
| |
| public Object getParent(Object element) { |
| return delegateContentProvider.getParent(element); |
| } |
| |
| public boolean hasChildren(Object element) { |
| return delegateContentProvider.hasChildren(element); |
| } |
| |
| public void dispose() { |
| delegateContentProvider.dispose(); |
| } |
| } |
| |
| private class TreeSelectionPatternFilter extends PatternFilter { |
| @Override |
| protected boolean isParentMatch(Viewer viewer, Object element) { |
| Object[] children = ((ITreeContentProvider)((AbstractTreeViewer)viewer).getContentProvider()) |
| .getChildren(element); |
| // apply all filters |
| if (viewerFilters != null && !viewerFilters.isEmpty() && children != null) { |
| // if one child match, show the parent in tree |
| for (ViewerFilter viewerFilter : viewerFilters) { |
| for (Object child : children) { |
| if (viewerFilter.select(viewer, null, child)) { |
| return super.isParentMatch(viewer, element); |
| } |
| } |
| } |
| return false; |
| } else { |
| return super.isParentMatch(viewer, element); |
| } |
| } |
| |
| @Override |
| protected boolean isLeafMatch(Viewer viewer, Object element) { |
| if (element instanceof EObject) { |
| String labelText = ((EObject)element).toString(); |
| if (labelText != null) { |
| return wordMatches(labelText); |
| } |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Sets or clears the input for this dialog. |
| */ |
| public void setInput(Object input) { |
| this.input = input; |
| this.refresh(); |
| } |
| |
| public void refresh() { |
| parent.pack(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| shell.setText(EEFRuntimeUIMessages.TabElementTreeSelectionDialog_shell_title + this.title); |
| } |
| |
| /** |
| * @see org.eclipse.jface.dialogs.Dialog#okPressed() |
| */ |
| @Override |
| protected void okPressed() { |
| if (selection != null && !selection.isEmpty()) { |
| process(selection); |
| ModelViewerHelper.setLastSelection(selection); |
| } |
| super.okPressed(); |
| } |
| |
| public void setSelection(IStructuredSelection selection) { |
| this.selection = selection; |
| } |
| |
| public abstract void process(IStructuredSelection selection); |
| |
| public void addBusinessRuleFilter(ViewerFilter filter) { |
| this.brFilters.add(filter); |
| } |
| |
| public void addFilter(ViewerFilter filter) { |
| this.viewerFilters.add(filter); |
| } |
| |
| public void removeBusinessRuleFilter(ViewerFilter filter) { |
| this.brFilters.remove(filter); |
| } |
| |
| public void removeFilter(ViewerFilter filter) { |
| this.viewerFilters.remove(filter); |
| } |
| |
| } |