| /******************************************************************************* |
| * Copyright (c) 2010, 2012 Tasktop Technologies and others. |
| * 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: |
| * Tasktop Technologies - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.builds.ui.spi; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.layout.GridLayoutFactory; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.CheckboxTreeViewer; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.ICheckStateProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerSorter; |
| import org.eclipse.mylyn.builds.core.IBuildPlan; |
| import org.eclipse.mylyn.builds.core.IBuildServer; |
| import org.eclipse.mylyn.builds.core.IBuildServerConfiguration; |
| import org.eclipse.mylyn.builds.core.spi.BuildServerConfiguration; |
| import org.eclipse.mylyn.builds.internal.core.BuildPlan; |
| import org.eclipse.mylyn.builds.internal.core.BuildServer; |
| import org.eclipse.mylyn.builds.internal.core.operations.RefreshConfigurationOperation; |
| import org.eclipse.mylyn.commons.core.StatusHandler; |
| import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; |
| import org.eclipse.mylyn.commons.core.operations.IOperationMonitor.OperationFlag; |
| import org.eclipse.mylyn.commons.core.operations.OperationUtil; |
| import org.eclipse.mylyn.commons.repositories.core.RepositoryValidator; |
| import org.eclipse.mylyn.commons.repositories.ui.RepositoryLocationPart; |
| import org.eclipse.mylyn.commons.workbench.SubstringPatternFilter; |
| import org.eclipse.mylyn.internal.builds.ui.BuildServerValidator; |
| import org.eclipse.mylyn.internal.builds.ui.BuildsUiInternal; |
| import org.eclipse.mylyn.internal.builds.ui.BuildsUiPlugin; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.ui.dialogs.FilteredTree; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| import org.eclipse.ui.forms.events.ExpansionAdapter; |
| import org.eclipse.ui.forms.events.ExpansionEvent; |
| import org.eclipse.ui.forms.widgets.ExpandableComposite; |
| |
| /** |
| * @author Steffen Pingel |
| */ |
| public class BuildServerPart extends RepositoryLocationPart { |
| |
| private class CheckboxFilteredTree extends FilteredTree { |
| |
| public CheckboxFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { |
| super(parent, treeStyle, filter, true); |
| } |
| |
| @Override |
| protected TreeViewer doCreateTreeViewer(Composite parent, int style) { |
| return new CheckboxTreeViewer(parent, style); |
| } |
| |
| public CheckboxTreeViewer getCheckboxTreeViewer() { |
| return getViewer(); |
| } |
| |
| @Override |
| public CheckboxTreeViewer getViewer() { |
| return (CheckboxTreeViewer) super.getViewer(); |
| } |
| |
| } |
| |
| private class Validator extends BuildServerValidator { |
| |
| private IBuildServerConfiguration configuration; |
| |
| public Validator(IBuildServer server) { |
| super(server); |
| } |
| |
| public IBuildServerConfiguration getConfiguration() { |
| return configuration; |
| } |
| |
| @Override |
| public IStatus run(IProgressMonitor monitor) { |
| IOperationMonitor progress = OperationUtil.convert(monitor, "Validating repository", 3); |
| progress.addFlag(OperationFlag.BACKGROUND); |
| try { |
| IBuildServer server = getServer(); |
| IStatus result = ((BuildServer) server).validate(progress.newChild(1)); |
| if (result.isOK()) { |
| RefreshConfigurationOperation op = new RefreshConfigurationOperation( |
| Collections.singletonList(server)); |
| op.doRefresh((BuildServer) server, progress.newChild(2)); |
| result = op.getStatus(); |
| configuration = server.getConfiguration(); |
| } |
| return result; |
| } catch (CoreException e) { |
| return new Status(IStatus.ERROR, BuildsUiPlugin.ID_PLUGIN, NLS.bind("Server validation failed: {0}", |
| e.getMessage()), e); |
| } |
| } |
| |
| } |
| |
| private final IBuildServer model; |
| |
| private CheckboxTreeViewer planViewer; |
| |
| private List<IBuildPlan> selectedPlans; |
| |
| public BuildServerPart(IBuildServer model) { |
| super(model.getLocation()); |
| this.model = model; |
| this.selectedPlans = Collections.emptyList(); |
| setNeedsProxy(true); |
| setNeedsHttpAuth(true); |
| setNeedsCertificateAuth(true); |
| } |
| |
| @Override |
| protected void applyValidatorResult(RepositoryValidator validator) { |
| super.applyValidatorResult(validator); |
| if (!validator.getResult().isOK()) { |
| StatusHandler.log(validator.getResult()); |
| } |
| IBuildServerConfiguration configuration = ((Validator) validator).getConfiguration(); |
| if (configuration != null) { |
| // update available plans |
| setInput(configuration, getSelectedPlans()); |
| } |
| } |
| |
| protected void setInput(IBuildServerConfiguration configuration, Collection<IBuildPlan> selectedPlans) { |
| Set<String> selectedIds = BuildsUiInternal.toSetOfIds(selectedPlans); |
| for (IBuildPlan plan : configuration.getPlans()) { |
| ((BuildPlan) plan).setSelected(selectedIds.contains(plan.getId())); |
| } |
| planViewer.setInput(configuration); |
| planViewer.expandAll(); |
| } |
| |
| @Override |
| public boolean canValidate() { |
| return true; |
| } |
| |
| private void createButtons(Composite section) { |
| Button refreshButton = new Button(section, SWT.PUSH); |
| GridDataFactory.fillDefaults().grab(true, false).applyTo(refreshButton); |
| refreshButton.setText("&Refresh"); |
| refreshButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| validate(); |
| } |
| }); |
| |
| Button selectAllButton = new Button(section, SWT.PUSH); |
| GridDataFactory.fillDefaults().grab(true, false).applyTo(selectAllButton); |
| selectAllButton.setText("&Select All"); |
| selectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| TreeItem[] items = planViewer.getTree().getItems(); |
| for (TreeItem item : items) { |
| if (item.getData() instanceof BuildPlan) { |
| ((BuildPlan) item.getData()).setSelected(true); |
| } |
| } |
| planViewer.refresh(); |
| } |
| }); |
| |
| Button deselectAllButton = new Button(section, SWT.PUSH); |
| GridDataFactory.fillDefaults().grab(true, false).applyTo(deselectAllButton); |
| deselectAllButton.setText("&Deselect All"); |
| deselectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| TreeItem[] items = planViewer.getTree().getItems(); |
| for (TreeItem item : items) { |
| if (item.getData() instanceof BuildPlan) { |
| ((BuildPlan) item.getData()).setSelected(false); |
| } |
| } |
| planViewer.refresh(); |
| } |
| }); |
| |
| // XXX spacer to make layout consistent |
| Button dummyButton = new Button(section, SWT.CHECK); |
| dummyButton.setVisible(false); |
| dummyButton.setText("Save Password"); |
| } |
| |
| @Override |
| public Control createContents(Composite parent) { |
| Control control = super.createContents(parent); |
| try { |
| IBuildServerConfiguration configuration = getModel().getConfiguration(); |
| setInput(configuration, selectedPlans); |
| } catch (CoreException e) { |
| // ignore |
| } |
| return control; |
| } |
| |
| @Override |
| protected Control createAdditionalContents(final Composite parent) { |
| // SectionComposite sectionComposite = new SectionComposite(parent, SWT.NONE); |
| // //sectionComposite.setMinHeight(150); |
| // sectionComposite.setExpandVertical(false); |
| |
| final ExpandableComposite section = new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE |
| | ExpandableComposite.CLIENT_INDENT | ExpandableComposite.COMPACT | ExpandableComposite.EXPANDED); |
| section.clientVerticalSpacing = 0; |
| section.setBackground(parent.getBackground()); |
| section.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT)); |
| section.addExpansionListener(new ExpansionAdapter() { |
| @Override |
| public void expansionStateChanged(ExpansionEvent e) { |
| if (section.getLayoutData() instanceof GridData) { |
| ((GridData) section.getLayoutData()).grabExcessVerticalSpace = e.getState(); |
| } |
| parent.layout(true); |
| } |
| }); |
| section.setText("Build Plans"); |
| // ExpandableComposite section = section.createSection("Build Plans"); |
| // section.setExpanded(true); |
| // if (section.getLayoutData() instanceof GridData) { |
| // GridData gd = ((GridData) section.getLayoutData()); |
| // gd.grabExcessVerticalSpace = true; |
| // gd.verticalAlignment = SWT.FILL; |
| // gd.minimumHeight = 150; |
| // } |
| |
| Composite composite = new Composite(section, SWT.NONE); |
| section.setClient(composite); |
| GridLayoutFactory.fillDefaults().numColumns(2).margins(0, 5).applyTo(composite); |
| |
| CheckboxFilteredTree filteredTree = new CheckboxFilteredTree(composite, SWT.FULL_SELECTION | SWT.BORDER, |
| new SubstringPatternFilter()); |
| GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 200).applyTo(filteredTree); |
| planViewer = filteredTree.getCheckboxTreeViewer();//new CheckboxTreeViewer(composite, SWT.FULL_SELECTION | SWT.BORDER); |
| planViewer.addCheckStateListener(new ICheckStateListener() { |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| BuildPlan plan = (BuildPlan) event.getElement(); |
| plan.setSelected(event.getChecked()); |
| } |
| }); |
| planViewer.setCheckStateProvider(new ICheckStateProvider() { |
| public boolean isChecked(Object element) { |
| return ((IBuildPlan) element).isSelected(); |
| } |
| |
| public boolean isGrayed(Object element) { |
| for (IBuildPlan child : ((IBuildPlan) element).getChildren()) { |
| if (!child.isSelected()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| }); |
| planViewer.setLabelProvider(new LabelProvider() { |
| @Override |
| public String getText(Object element) { |
| return ((IBuildPlan) element).getName(); |
| } |
| }); |
| planViewer.setContentProvider(new ITreeContentProvider() { |
| private BuildServerConfiguration configuration; |
| |
| private final Object[] EMPTY_ARRAY = new Object[0]; |
| |
| public void dispose() { |
| // ignore |
| } |
| |
| public Object[] getChildren(Object parentElement) { |
| return EMPTY_ARRAY; |
| } |
| |
| public Object[] getElements(Object inputElement) { |
| return configuration.getPlans().toArray(); |
| } |
| |
| public Object getParent(Object element) { |
| return null; |
| } |
| |
| public boolean hasChildren(Object element) { |
| return false; |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| configuration = (BuildServerConfiguration) newInput; |
| } |
| }); |
| planViewer.setSorter(new ViewerSorter()); |
| |
| Composite buttonComposite = new Composite(composite, SWT.NONE); |
| GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.TOP).applyTo(buttonComposite); |
| GridLayoutFactory.fillDefaults() |
| .numColumns(1) |
| .margins(0, 0) |
| .extendedMargins(0, 0, 0, 0) |
| .applyTo(buttonComposite); |
| createButtons(buttonComposite); |
| |
| return section; |
| } |
| |
| public final IBuildServer getModel() { |
| return model; |
| } |
| |
| public List<IBuildPlan> getSelectedPlans() { |
| if (planViewer.getInput() instanceof BuildServerConfiguration) { |
| BuildServerConfiguration configuration = (BuildServerConfiguration) planViewer.getInput(); |
| List<IBuildPlan> selectedPlans = new ArrayList<IBuildPlan>(); |
| for (IBuildPlan plan : configuration.getPlans()) { |
| if (plan.isSelected()) { |
| selectedPlans.add(plan); |
| } |
| } |
| return selectedPlans; |
| } |
| return Collections.emptyList(); |
| } |
| |
| @Override |
| protected RepositoryValidator getValidator() { |
| return new Validator(getModel()); |
| } |
| |
| public void initSelectedPlans(List<IBuildPlan> selectedPlans) { |
| Assert.isNotNull(selectedPlans); |
| this.selectedPlans = selectedPlans; |
| } |
| |
| } |