/* This file is part of Green. * * Copyright (C) 2005 The Research Foundation of State University of New York * All Rights Under Copyright Reserved, The Research Foundation of S.U.N.Y. * * Green is free software, licensed under the terms of the Eclipse * Public License, version 1.0. The license is available at * http://www.eclipse.org/legal/epl-v10.html */ package edu.buffalo.cse.green.dialogs.wizards; import java.util.MissingResourceException; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeHierarchy; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.JavaElementLabelProvider; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.IColorProvider; 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.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import edu.buffalo.cse.green.GreenException; import edu.buffalo.cse.green.PlugIn; /** * A wizard that allows the user to choose a type from a list of types. * * @author rjtruban */ public class ChooseTypeWizard extends GreenWizard { private static final String ERROR_CONCRETE_CLASS = "The selected type must be a concrete class"; private static final String ERROR_SELECT_TYPE = "You must select a concrete type to instantiate"; protected ChooseTypeLabelProvider _labelProvider; protected IType _originalType; protected ITypeHierarchy _originalTypeHierarchy; protected IType _selectedType; public ChooseTypeWizard(IType originalType) { _originalType = originalType; try { _originalTypeHierarchy = _originalType.newTypeHierarchy(PlugIn .getEmptyProgressMonitor()); } catch (JavaModelException e) { e.printStackTrace(); throw new MissingResourceException("Can't load type hierarchy.", _originalType.getFullyQualifiedName(), "TypeHierarchy"); } } /** * @see edu.buffalo.cse.green.dialogs.wizards.GreenWizard#doFinish() */ public boolean doFinish() { try { if (_selectedType != null) { int flags = _selectedType.getFlags(); if (Flags.isAbstract(flags) || Flags.isInterface(flags)) { GreenException.illegalOperation(ERROR_CONCRETE_CLASS); } else { return true; } } else { GreenException.illegalOperation(ERROR_SELECT_TYPE); } } catch (JavaModelException e) { e.printStackTrace(); } return false; } /** * @see org.eclipse.jface.wizard.IWizard#addPages() */ public void addPages() { super.addPages(); ChooseTypeWizardPage page = new ChooseTypeWizardPage(); page.setMessage("The type \"" + _originalType.getElementName() + "\" cannot be used directly."); addPage(page); } /** * The page for the <code>ChooseTypeWizard</code>. * * @author bcmartin */ protected class ChooseTypeWizardPage extends WizardPage { private static final String DIALOG_TITLE = "Choose Concrete Type"; protected ChooseTypeWizardPage() { super(DIALOG_TITLE); setTitle(DIALOG_TITLE); setWindowTitle(DIALOG_TITLE); setMessage("The type cannot be used directly."); } /** * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); setControl(composite); composite.setLayout(new GridLayout()); composite.setLayoutData(new GridData()); addTreeComponent(composite); Dialog.applyDialogFont(composite); } /** * Tree-viewer that shows the allowable types in a tree view. Adapted * from * {@link org.eclipse.jdt.internal.ui.refactoring.ChangeTypeWizard$ChangeTypeInputPage} */ private void addTreeComponent(Composite parent) { TreeViewer fTreeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); GridData gd = new GridData(GridData.FILL_BOTH); gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; GC gc = null; try { gc = new GC(parent); gc.setFont(gc.getFont()); gd.heightHint = Dialog.convertHeightInCharsToPixels(gc .getFontMetrics(), 6); // 6 characters tall } finally { if (gc != null) { gc.dispose(); gc = null; } } fTreeViewer.getTree().setLayoutData(gd); fTreeViewer.setContentProvider(new ChooseTypeContentProvider()); _labelProvider = new ChooseTypeLabelProvider(); fTreeViewer.setLabelProvider(_labelProvider); ISelectionChangedListener listener = new ISelectionChangedListener() { /** * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) */ public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event .getSelection(); typeSelected((IType) selection.getFirstElement()); } }; fTreeViewer.addSelectionChangedListener(listener); // Don't use _originalType directly, because the tree will attempt // to get its children infinitely if the original type's children // includes itself. fTreeViewer.setInput(new Object[] { _originalType }); // How deep to get children (to prevent infinite loops) fTreeViewer.expandToLevel(10); } } /** * Called when a type is selected. * * @param selected - The selected type. */ protected void typeSelected(IType selected) { _selectedType = selected; } /** * @return The selected type. */ public IType getSelectedType() { return _selectedType; } /** * Content provider for <code>ChooseTypeWizardPage</code>. * * @author bcmartin */ class ChooseTypeContentProvider implements ITreeContentProvider { /** * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ public Object[] getChildren(Object parentElement) { return parentElement instanceof IType ? _originalTypeHierarchy .getSubtypes((IType) parentElement) : null; } /** * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ public Object getParent(Object element) { return element instanceof IType ? ((IType) element).getParent() .getAncestor(IJavaElement.TYPE) : null; } /** * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ public boolean hasChildren(Object element) { return getChildren(element).length != 0; } /** * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object inputElement) { if (!(inputElement instanceof Object[])) { GreenException.illegalOperation( "Root element of tree not original element."); } else { Object[] input = (Object[]) inputElement; if (input.length == 0 || !(input[0] == _originalType)) { GreenException.illegalOperation( "Root element of tree not original element."); } return new Object[] { _originalType }; } return null; } /** * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ public void dispose() { } /** * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } /** * A label provider for <code>ChooseTypeWizardPage</code>. * * @author bcmartin */ protected class ChooseTypeLabelProvider extends JavaElementLabelProvider implements IColorProvider { /** * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) */ public Color getForeground(Object element) { return null; } /** * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) */ public Color getBackground(Object element) { return null; } } }