package org.bndtools.core.ui.wizards.blueprint; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import org.bndtools.api.ILogger; import org.bndtools.api.Logger; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; public class WizardBndFileSelector extends WizardPage { private static final ILogger logger = Logger.getLogger(WizardBndFileSelector.class); private CheckboxTreeViewer checkboxTreeViewer; protected WizardBndFileSelector() { super("selectBndPage", "Select Bnd files to update", null); setPageComplete(false); } @Override public void setVisible(boolean visible) { setPageComplete(true); super.setVisible(visible); } @Override public void createControl(Composite composite) { checkboxTreeViewer = new CheckboxTreeViewer(composite); checkboxTreeViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { Object element = event.getElement(); ITreeContentProvider contentProvider = (ITreeContentProvider) checkboxTreeViewer.getContentProvider(); alterChildren(element, contentProvider, event.getChecked()); alterParents(element, contentProvider); } private void alterChildren(Object element, ITreeContentProvider contentProvider, boolean checked) { Queue<Object> toRecurse = new LinkedList<Object>(); toRecurse.offer(element); while (!toRecurse.isEmpty()) { Object o = toRecurse.poll(); for (Object child : contentProvider.getChildren(o)) { if (contentProvider.hasChildren(child)) toRecurse.offer(child); checkboxTreeViewer.setChecked(child, checked); checkboxTreeViewer.setGrayed(child, false); } } } private void alterParents(Object element, ITreeContentProvider contentProvider) { Object parent = contentProvider.getParent(element); while (parent != null) { boolean allChecked = true; boolean noneChecked = true; for (Object child : contentProvider.getChildren(parent)) { boolean checked = checkboxTreeViewer.getChecked(child); boolean grayed = checkboxTreeViewer.getGrayed(child); allChecked &= checked & !grayed; noneChecked &= !checked; } if (allChecked) { checkboxTreeViewer.setChecked(parent, true); checkboxTreeViewer.setGrayed(parent, false); } else if (noneChecked) { checkboxTreeViewer.setGrayChecked(parent, false); } else { checkboxTreeViewer.setGrayChecked(parent, true); } parent = contentProvider.getParent(parent); } } }); setControl(checkboxTreeViewer.getControl()); } public IFile[] getSelectedBndFiles() { List<IFile> files = new ArrayList<IFile>(); for (Object o : checkboxTreeViewer.getCheckedElements()) { if (o instanceof IFile) files.add((IFile) o); } return files.toArray(new IFile[0]); } public void updateControls(IPath containerFullPath) { String selectedProjectName = containerFullPath.segment(0); final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(selectedProjectName); final List<IResource> bndFiles = new ArrayList<IResource>(); try { project.accept(new IResourceProxyVisitor() { @Override public boolean visit(IResourceProxy res) throws CoreException { if (res.getType() == IResource.FILE && res.getName().endsWith(".bnd")) { bndFiles.add(res.requestResource()); } return true; } }, 0); } catch (CoreException e) { logger.logError(String.format("Unable to locate bnd files for project: %s", project.getName()), e); } setupTree(bndFiles); checkboxTreeViewer.setInput(project); if (bndFiles.size() == 1) checkboxTreeViewer.setCheckedElements(bndFiles.toArray()); checkboxTreeViewer.refresh(true); checkboxTreeViewer.getControl().redraw(); } private void setupTree(final List<IResource> bndFiles) { checkboxTreeViewer.setContentProvider(new WorkbenchContentProvider() { @Override public Object[] getChildren(Object element) { Object[] children = super.getChildren(element); List<IResource> resources = new ArrayList<IResource>(); for (Object o : children) { IPath child = ((IResource) o).getProjectRelativePath(); for (IResource bndFile : bndFiles) { if (child.isPrefixOf(bndFile.getProjectRelativePath()) || child.equals(bndFile.getProjectRelativePath())) { resources.add((IResource) o); break; } } } return resources.toArray(); } }); checkboxTreeViewer.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider()); checkboxTreeViewer.expandAll(); } }