/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation 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: * IBM Corporation - initial API and implementation * Sebastian Davids <sdavids@gmx.de> - Bug 137478 [Preferences] ProjectReferencePage has too wide left margin *******************************************************************************/ package org.eclipse.ui.internal.ide.dialogs; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; import org.eclipse.ui.internal.ide.IIDEHelpContextIds; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.progress.IProgressService; /** * A property page for viewing and modifying the set * of projects referenced by a given project. */ public class ProjectReferencePage extends PropertyPage { private IProject project; private boolean modified = false; //widgets private CheckboxTableViewer listViewer; /* * @see PreferencePage#createContents */ @Override protected Control createContents(Composite parent) { PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IIDEHelpContextIds.PROJECT_REFERENCE_PROPERTY_PAGE); Composite composite = new Composite(parent, SWT.NONE); initialize(); createDescriptionLabel(composite); listViewer = CheckboxTableViewer.newCheckList(composite, SWT.TOP | SWT.BORDER); if(!project.isOpen()) listViewer.getControl().setEnabled(false); listViewer.setLabelProvider(WorkbenchLabelProvider .getDecoratingWorkbenchLabelProvider()); listViewer.setContentProvider(getContentProvider(project)); listViewer.setComparator(new ViewerComparator()); listViewer.setInput(project.getWorkspace()); try { listViewer.setCheckedElements(project.getDescription() .getReferencedProjects()); } catch (CoreException e) { //don't initial-check anything } //check for initial modification to avoid work if no changes are made listViewer.addCheckStateListener(event -> modified = true); applyDialogFont(composite); GridLayoutFactory.fillDefaults().generateLayout(composite); return composite; } /** * Returns a content provider for the list dialog. It * will return all projects in the workspace except * the given project, plus any projects referenced * by the given project which do no exist in the * workspace. * @param project the project to provide content for * @return the content provider that shows the project content */ protected IStructuredContentProvider getContentProvider( final IProject project) { return new WorkbenchContentProvider() { @Override public Object[] getChildren(Object o) { if (!(o instanceof IWorkspace)) { return new Object[0]; } // Collect all the projects in the workspace except the given project IProject[] projects = ((IWorkspace) o).getRoot().getProjects(); ArrayList referenced = new ArrayList(projects.length); boolean found = false; for (IProject currentProject : projects) { if (!found && currentProject.equals(project)) { found = true; continue; } referenced.add(currentProject); } // Add any referenced that do not exist in the workspace currently try { projects = project.getDescription().getReferencedProjects(); for (int i = 0; i < projects.length; i++) { if (!referenced.contains(projects[i])) { referenced.add(projects[i]); } } } catch (CoreException e) { //Ignore core exceptions } return referenced.toArray(); } }; } /** * Handle the exception thrown when saving. * @param e the exception */ protected void handle(InvocationTargetException e) { IStatus error; Throwable target = e.getTargetException(); if (target instanceof CoreException) { error = ((CoreException) target).getStatus(); } else { String msg = target.getMessage(); if (msg == null) { msg = IDEWorkbenchMessages.Internal_error; } error = new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, 1, msg, target); } ErrorDialog.openError(getControl().getShell(), null, null, error); } /** * Initializes a ProjectReferencePage. */ private void initialize() { project = Adapters.adapt(getElement(), IProject.class); if (project == null) { IResource resource = Adapters.adapt(getElement(), IResource.class); Assert.isNotNull(resource, "unable to adapt element to a project"); //$NON-NLS-1$ project = resource.getProject(); } noDefaultAndApplyButton(); setDescription(NLS.bind(IDEWorkbenchMessages.ProjectReferencesPage_label, project.getName())); } /** * @see PreferencePage#performOk */ @Override public boolean performOk() { if (!modified) { return true; } Object[] checked = listViewer.getCheckedElements(); final IProject[] refs = new IProject[checked.length]; System.arraycopy(checked, 0, refs, 0, checked.length); IRunnableWithProgress runnable = monitor -> { try { IProjectDescription description = project.getDescription(); description.setReferencedProjects(refs); project.setDescription(description, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } }; IProgressService service = PlatformUI.getWorkbench().getProgressService(); try { service.run(false, false, runnable); } catch (InterruptedException e) { //Ignore interrupted exceptions } catch (InvocationTargetException e) { handle(e); return false; } return true; } }