package com.redhat.ceylon.test.eclipse.plugin.launch; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getProjectDeclaredSourceModules; import static com.redhat.ceylon.test.eclipse.plugin.CeylonTestPlugin.PREF_SHOW_COMPLETE_DESCRIPTION; import static com.redhat.ceylon.test.eclipse.plugin.util.CeylonTestUtil.getAllMethods; import static com.redhat.ceylon.test.eclipse.plugin.util.CeylonTestUtil.getProjects; import static com.redhat.ceylon.test.eclipse.plugin.util.CeylonTestUtil.getWorkspaceRoot; import static com.redhat.ceylon.test.eclipse.plugin.util.CeylonTestUtil.isTestable; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.jdt.internal.corext.util.Strings; import org.eclipse.jdt.internal.ui.util.SWTUtil; import org.eclipse.jdt.internal.ui.viewsupport.FilteredElementTreeSelectionDialog; import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator; import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; 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.Shell; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import com.redhat.ceylon.eclipse.code.complete.CodeCompletions; import com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider; import com.redhat.ceylon.model.typechecker.model.ClassOrInterface; import com.redhat.ceylon.model.typechecker.model.Declaration; import com.redhat.ceylon.model.typechecker.model.Module; import com.redhat.ceylon.model.typechecker.model.Package; import com.redhat.ceylon.test.eclipse.plugin.CeylonTestMessages; import com.redhat.ceylon.test.eclipse.plugin.CeylonTestPlugin; import com.redhat.ceylon.test.eclipse.plugin.util.MethodWithContainer; @SuppressWarnings("restriction") public class CeylonTestSelectionDialog extends FilteredElementTreeSelectionDialog { private static final java.lang.Class<?>[] ACCEPTED_TYPES = { IProject.class, Module.class, Package.class, Declaration.class, MethodWithContainer.class }; private final CeylonTestSelectionDialogLabelProvider labelProvider; private Composite buttonPanel; private Button buttonShowCompleteDescription; public CeylonTestSelectionDialog(Shell parent) { this(parent, new CeylonTestSelectionDialogLabelProvider(true), new CeylonTestSelectionDialogContentProvider()); } public CeylonTestSelectionDialog(Shell parent, CeylonTestSelectionDialogLabelProvider labelProvider, CeylonTestSelectionDialogContentProvider contentProvider) { super(parent, labelProvider, contentProvider); this.labelProvider = labelProvider; setTitle(CeylonTestMessages.testSelectDialogTitle); setMessage(CeylonTestMessages.testSelectDialogMessage); setHelpAvailable(false); setInput(getWorkspaceRoot()); setComparator(new ViewerComparator(Collator.getInstance())); setValidator(new TypedElementSelectionValidator(ACCEPTED_TYPES, true) { @Override protected boolean isSelectedValid(Object element) { return isTestable(element); } }); } @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); createButtonPanel(composite); createButtonShowCompleteDescription(); loadSettings(); getTreeViewer().addFilter(new CeylonTestSelectionDialogViewerFilter()); update(); return composite; } private void createButtonPanel(Composite composite) { buttonPanel = new Composite(composite, SWT.NONE); buttonPanel.setLayout(new GridLayout(1, false)); buttonPanel.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).create()); } private void createButtonShowCompleteDescription() { buttonShowCompleteDescription = new Button(buttonPanel, SWT.CHECK); buttonShowCompleteDescription.setText(CeylonTestMessages.testSelectDialogShowComplateDescription); buttonShowCompleteDescription.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { update(); } }); } @Override protected TreeViewer doCreateTreeViewer(Composite parent, int style) { // copy from FilteredElementTreeSelectionDialog, but without FilteredTreeWithFilter, which disabled auto-expansion FilteredTree tree = new FilteredTree(parent, style, new PatternFilter(), true); tree.setLayoutData(new GridData(GridData.FILL_BOTH)); applyDialogFont(tree); SWTUtil.setAccessibilityText(tree.getViewer().getControl(), Strings.removeMnemonicIndicator(getMessage())); return tree.getViewer(); } @Override public boolean close() { saveSettings(); return super.close(); } @Override protected void computeResult() { ITreeSelection treeSelection = (ITreeSelection) getTreeViewer().getSelection(); TreePath[] treePaths = treeSelection.getPaths(); List<CeylonTestLaunchConfigEntry> result = new ArrayList<CeylonTestLaunchConfigEntry>(); for(TreePath treePath : treePaths) { result.add(CeylonTestLaunchConfigEntry.buildFromTreePath(treePath)); } setResult(result); } private void loadSettings() { IDialogSettings dialogSettings = CeylonTestPlugin.getDefault().getDialogSettings(); buttonShowCompleteDescription.setSelection(dialogSettings.getBoolean(PREF_SHOW_COMPLETE_DESCRIPTION)); } private void saveSettings() { IDialogSettings dialogSettings = CeylonTestPlugin.getDefault().getDialogSettings(); dialogSettings.put(PREF_SHOW_COMPLETE_DESCRIPTION, buttonShowCompleteDescription.getSelection()); } private void update() { labelProvider.setShowCompleteDescription(buttonShowCompleteDescription.getSelection()); getTreeViewer().refresh(); } public static class CeylonTestSelectionDialogContentProvider implements ITreeContentProvider { @Override public Object[] getChildren(Object parent) { List<?> children = Collections.emptyList(); if (parent instanceof IWorkspaceRoot) { children = getProjects(); } else if( parent instanceof IProject ) { Collection<Module> modules = getProjectDeclaredSourceModules((IProject)parent); List<Module> childrenModules = new ArrayList<Module>(modules.size()); childrenModules.addAll(modules); children = childrenModules; } else if( parent instanceof Module) { children = ((Module) parent).getPackages(); } else if( parent instanceof Package ) { children = ((Package) parent).getMembers(); } else if( parent instanceof ClassOrInterface ) { children = getAllMethods((ClassOrInterface) parent); } return children.toArray(); } @Override public Object getParent(Object element) { return null; } @Override public boolean hasChildren(Object element) { return getChildren(element).length > 0; } @Override public Object[] getElements(Object element) { return getChildren(element); } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // noop } @Override public void dispose() { // noop } } public static class CeylonTestSelectionDialogLabelProvider extends CeylonLabelProvider { public CeylonTestSelectionDialogLabelProvider(boolean includePackage) { super(includePackage); } private boolean showCompleteDescription; public boolean isShowCompleteDescription() { return showCompleteDescription; } public void setShowCompleteDescription(boolean showCompleteDescription) { this.showCompleteDescription = showCompleteDescription; } @Override public Image getImage(Object element) { if (element instanceof Declaration) { return getImageForDeclaration((Declaration) element); } else if (element instanceof MethodWithContainer) { return getImageForDeclaration(((MethodWithContainer) element).getMethod()); } return super.getImage(element); } @Override public StyledString getStyledText(Object element) { StyledString styledText; if (element instanceof Declaration) { Declaration declaration = (Declaration) element; if (showCompleteDescription) { styledText = CodeCompletions.getStyledDescriptionFor(declaration); } else { styledText = new StyledString(declaration.getName()); } } else if (element instanceof MethodWithContainer) { Declaration declaration = ((MethodWithContainer) element).getMethod(); if (showCompleteDescription) { styledText = CodeCompletions.getStyledDescriptionFor(declaration); } else { styledText = new StyledString(declaration.getName()); } } else if (element instanceof Package || element instanceof Module) { // default package color from CeylonLabelProvider is gray, we want black styledText = new StyledString(super.getStyledText(element).getString()); } else { styledText = super.getStyledText(element); } if( !isTestable(element) ) { styledText = new StyledString(styledText.getString(), StyledString.QUALIFIER_STYLER); } return styledText; } } public static class CeylonTestSelectionDialogViewerFilter extends TypedViewerFilter { public CeylonTestSelectionDialogViewerFilter() { super(ACCEPTED_TYPES); } @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof Declaration) { Declaration d = (Declaration) element; if (d.isNative() && d.isNativeImplementation()) { return false; } } return isTestable(element); } } }