/******************************************************************************* * Copyright (c) 2010-2015 Henshin developers. 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: * TU Berlin, University of Luxembourg, SES S.A. *******************************************************************************/ package de.tub.tfs.henshin.editor.ui.dialog.resources; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; 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.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.part.DrillDownComposite; /** * Workbench-level composite for choosing a {@link IResource}. */ public class ResourceSelectionGroup extends Composite implements ISelectionChangedListener, ModifyListener { /** The Constant DEFAULT_HEIGHT. */ private static final int DEFAULT_HEIGHT = 300; /** The Constant DEFAULT_MSG_SELECT. */ private static final String DEFAULT_MSG_SELECT = "Resource:"; // sizing constants /** The Constant DEFAULT_WIDTH. */ private static final int DEFAULT_WIDTH = 320; /** The allow new resource. */ protected boolean allowNewResource = false; /** The error message. */ protected String errorMessage; /** The resource input. */ protected Text resourceInput; /** The tree viewer. */ protected TreeViewer treeViewer; // Last selection made by user /** The selected res. */ protected IResource selectedRes; /** The is valid. */ protected boolean isValid = false; // The listener to notify of events /** The listener. */ private Listener listener; /** The validator. */ protected IResourceValidator validator = null; /** * Instantiates a new resource selection group. * * @param composite * the composite * @param listener * the listener * @param allowNew * the allow new */ public ResourceSelectionGroup(Composite composite, Listener listener, boolean allowNew) { this(composite, listener, allowNew, null, DEFAULT_HEIGHT, DEFAULT_WIDTH); } /** * Instantiates a new resource selection group. * * @param parent * the parent * @param listener * the listener * @param allowNewResource * the allow new resource * @param validator * the validator */ public ResourceSelectionGroup(Composite parent, Listener listener, boolean allowNewResource, IResourceValidator validator) { this(parent, listener, allowNewResource, validator, DEFAULT_MSG_SELECT, DEFAULT_HEIGHT, DEFAULT_WIDTH); } /** * Instantiates a new resource selection group. * * @param parent * the parent * @param listener * the listener * @param allowNewResource * the allow new resource * @param validator * the validator * @param msg * the msg */ public ResourceSelectionGroup(Composite parent, Listener listener, boolean allowNewResource, IResourceValidator validator, String msg) { this(parent, listener, allowNewResource, validator, msg, DEFAULT_HEIGHT, DEFAULT_WIDTH); } /** * Instantiates a new resource selection group. * * @param parent * the parent * @param listener * the listener * @param allowNewResource * the allow new resource * @param validator * the validator * @param message * the message * @param hHint * the h hint * @param wHint * the w hint */ public ResourceSelectionGroup(Composite parent, Listener listener, boolean allowNewResource, IResourceValidator validator, String message, int hHint, int wHint) { super(parent, SWT.NONE); this.listener = listener; this.allowNewResource = allowNewResource; this.validator = validator; createContents(message == null ? DEFAULT_MSG_SELECT : message, hHint <= 0 ? DEFAULT_HEIGHT : hHint, Math.max(wHint, DEFAULT_WIDTH)); setInitialFocus(); } /** * Instantiates a new resource selection group. * * @param parent * the parent * @param listener * the listener * @param allowNew * the allow new * @param message * the message * @param heightHint * the height hint * @param widthHint * the width hint */ public ResourceSelectionGroup(Composite parent, Listener listener, boolean allowNew, String message, int heightHint, int widthHint) { this(parent, listener, allowNew, null, message, heightHint, widthHint); } /** * Instantiates a new resource selection group. * * @param composite * the composite * @param listener * the listener * @param allowNew * the allow new * @param msg * the msg */ public ResourceSelectionGroup(Composite composite, Listener listener, boolean allowNew, String msg) { this(composite, listener, allowNew, msg, DEFAULT_HEIGHT, DEFAULT_WIDTH); } /** * Gets the error message. * * @return the errorMessage */ public String getErrorMessage() { return errorMessage; } /** * Checks if is valid. * * @return the isValid */ public boolean isValid() { return isValid; } /* * (non-Javadoc) * * @see * org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events * .ModifyEvent) */ @Override public void modifyText(ModifyEvent e) { validate(); notifyListener(); } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged( * org.eclipse.jface.viewers.SelectionChangedEvent) */ @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event .getSelection(); selectedRes = (IResource) selection.getFirstElement(); if (selectedRes != null && allowNewResource) { resourceInput.removeModifyListener(this); resourceInput.setText(selectedRes.getFullPath().makeRelative() .toString()); resourceInput.addModifyListener(this); } validate(); notifyListener(); } /** * Gives focus to one of the widgets in the group, as determined by the * group. */ public void setInitialFocus() { if (allowNewResource) { resourceInput.setFocus(); } else { treeViewer.getTree().setFocus(); } } /** * Sets the selected existing resource. * * @param res * the new selected resource */ public void setSelectedResource(IResource res) { selectedRes = res; treeViewer.setSelection(new StructuredSelection(res), true); } /** * Sets the validator. * * @param validator * the validator to set */ public void setValidator(IResourceValidator validator) { this.validator = validator; ((ResourceContentProvider) treeViewer.getContentProvider()) .setContentValidator(validator); } /** * Creates the contents of the composite. * * @param message * the message * @param heightHint * the height hint * @param widthHint * the width hint */ protected void createContents(String message, int heightHint, int widthHint) { GridLayout layout = new GridLayout(); layout.marginWidth = 0; setLayout(layout); setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); createTreeViewer(heightHint, widthHint); layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; if (allowNewResource) { Composite searchComposite = new Composite(this, SWT.NONE); searchComposite.setLayout(layout); searchComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); new Label(searchComposite, SWT.SHADOW_OUT).setText(message); resourceInput = new Text(searchComposite, SWT.SINGLE | SWT.BORDER | SWT.SEARCH); resourceInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); resourceInput.addModifyListener(this); } Dialog.applyDialogFont(this); } /** * Returns a new drill down viewer for this dialog. * * @param heightHint * height hint for the drill down composite * @param widthHint * the width hint */ protected void createTreeViewer(int heightHint, int widthHint) { GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true); spec.widthHint = widthHint; spec.heightHint = heightHint; DrillDownComposite drillDown = new DrillDownComposite(this, SWT.NONE); drillDown.setLayoutData(spec); // Create tree viewer inside drill down. treeViewer = new TreeViewer(drillDown, SWT.BORDER); drillDown.setChildTree(treeViewer); treeViewer.setContentProvider(new ResourceContentProvider(validator)); treeViewer.setLabelProvider(WorkbenchLabelProvider .getDecoratingWorkbenchLabelProvider()); treeViewer.setComparator(new ViewerComparator()); treeViewer.setUseHashlookup(true); treeViewer.addSelectionChangedListener(this); treeViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { Object item = ((IStructuredSelection) selection) .getFirstElement(); if (item == null) { return; } if (treeViewer.getExpandedState(item)) { treeViewer.collapseToLevel(item, 1); } else { treeViewer.expandToLevel(item, 1); } } } }); // This has to be done after the viewer has been laid out treeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); } /** * Validate. */ protected void validate() { isValid = (!allowNewResource && selectedRes != null) || (allowNewResource && !resourceInput.getText().isEmpty()); if (!isValid) { errorMessage = "No resource is specified."; } } /** * Gets the resource full path. * * @return the resource full path */ public IPath getResourceFullPath() { if (allowNewResource) { return new Path(resourceInput.getText()); } return selectedRes.getFullPath(); } /** * Notify listener. */ protected void notifyListener() { // fire an event so the parent can update its controls if (listener != null) { Event changeEvent = new Event(); changeEvent.type = SWT.Selection; changeEvent.widget = this; listener.handleEvent(changeEvent); } } }