001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.ide.dialogs;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.ArrayList;
014:
015: import org.eclipse.core.resources.IProject;
016: import org.eclipse.core.resources.IProjectDescription;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.resources.IWorkspace;
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IProgressMonitor;
021: import org.eclipse.core.runtime.IStatus;
022: import org.eclipse.core.runtime.Status;
023: import org.eclipse.jface.dialogs.ErrorDialog;
024: import org.eclipse.jface.operation.IRunnableWithProgress;
025: import org.eclipse.jface.preference.PreferencePage;
026: import org.eclipse.jface.viewers.CheckStateChangedEvent;
027: import org.eclipse.jface.viewers.CheckboxTableViewer;
028: import org.eclipse.jface.viewers.ICheckStateListener;
029: import org.eclipse.jface.viewers.IStructuredContentProvider;
030: import org.eclipse.jface.viewers.ViewerComparator;
031: import org.eclipse.osgi.util.NLS;
032: import org.eclipse.swt.SWT;
033: import org.eclipse.swt.graphics.Font;
034: import org.eclipse.swt.graphics.FontData;
035: import org.eclipse.swt.layout.GridData;
036: import org.eclipse.swt.layout.GridLayout;
037: import org.eclipse.swt.widgets.Composite;
038: import org.eclipse.swt.widgets.Control;
039: import org.eclipse.swt.widgets.Label;
040: import org.eclipse.ui.PlatformUI;
041: import org.eclipse.ui.dialogs.PropertyPage;
042: import org.eclipse.ui.internal.ide.DialogUtil;
043: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
044: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
045: import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
046: import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
047: import org.eclipse.ui.model.WorkbenchContentProvider;
048: import org.eclipse.ui.model.WorkbenchLabelProvider;
049:
050: /**
051: * A property page for viewing and modifying the set
052: * of projects referenced by a given project.
053: */
054: public class ProjectReferencePage extends PropertyPage {
055: private IProject project;
056:
057: private boolean modified = false;
058:
059: //widgets
060: private CheckboxTableViewer listViewer;
061:
062: private static final int PROJECT_LIST_MULTIPLIER = 30;
063:
064: /**
065: * Creates a new ProjectReferencePage.
066: */
067: public ProjectReferencePage() {
068: //Do nothing on creation
069: }
070:
071: /**
072: * @see PreferencePage#createContents
073: */
074: protected Control createContents(Composite parent) {
075:
076: PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
077: IIDEHelpContextIds.PROJECT_REFERENCE_PROPERTY_PAGE);
078: Font font = parent.getFont();
079:
080: Composite composite = new Composite(parent, SWT.NONE);
081: GridLayout layout = new GridLayout();
082: composite.setLayout(layout);
083: composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
084: composite.setFont(font);
085:
086: initialize();
087:
088: Label description = createDescriptionLabel(composite);
089: description.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
090: false));
091:
092: listViewer = CheckboxTableViewer.newCheckList(composite,
093: SWT.TOP | SWT.BORDER);
094: listViewer.getTable().setFont(font);
095: GridData data = new GridData(GridData.FILL_BOTH);
096: data.grabExcessHorizontalSpace = true;
097:
098: if (!project.isOpen())
099: listViewer.getControl().setEnabled(false);
100:
101: //Only set a height hint if it will not result in a cut off dialog
102: if (DialogUtil.inRegularFontMode(parent)) {
103: data.heightHint = getDefaultFontHeight(listViewer
104: .getTable(), PROJECT_LIST_MULTIPLIER);
105: }
106: listViewer.getTable().setLayoutData(data);
107: listViewer.getTable().setFont(font);
108:
109: listViewer.setLabelProvider(WorkbenchLabelProvider
110: .getDecoratingWorkbenchLabelProvider());
111: listViewer.setContentProvider(getContentProvider(project));
112: listViewer.setComparator(new ViewerComparator());
113: listViewer.setInput(project.getWorkspace());
114: try {
115: listViewer.setCheckedElements(project.getDescription()
116: .getReferencedProjects());
117: } catch (CoreException e) {
118: //don't initial-check anything
119: }
120:
121: //check for initial modification to avoid work if no changes are made
122: listViewer.addCheckStateListener(new ICheckStateListener() {
123: public void checkStateChanged(CheckStateChangedEvent event) {
124: modified = true;
125: }
126: });
127:
128: return composite;
129: }
130:
131: /**
132: * Returns a content provider for the list dialog. It
133: * will return all projects in the workspace except
134: * the given project, plus any projects referenced
135: * by the given project which do no exist in the
136: * workspace.
137: * @param project the project to provide content for
138: * @return the content provider that shows the project content
139: */
140: protected IStructuredContentProvider getContentProvider(
141: final IProject project) {
142: return new WorkbenchContentProvider() {
143: public Object[] getChildren(Object o) {
144: if (!(o instanceof IWorkspace)) {
145: return new Object[0];
146: }
147:
148: // Collect all the projects in the workspace except the given project
149: IProject[] projects = ((IWorkspace) o).getRoot()
150: .getProjects();
151: ArrayList referenced = new ArrayList(projects.length);
152: boolean found = false;
153: for (int i = 0; i < projects.length; i++) {
154: if (!found && projects[i].equals(project)) {
155: found = true;
156: continue;
157: }
158: referenced.add(projects[i]);
159: }
160:
161: // Add any referenced that do not exist in the workspace currently
162: try {
163: projects = project.getDescription()
164: .getReferencedProjects();
165: for (int i = 0; i < projects.length; i++) {
166: if (!referenced.contains(projects[i])) {
167: referenced.add(projects[i]);
168: }
169: }
170: } catch (CoreException e) {
171: //Ignore core exceptions
172: }
173:
174: return referenced.toArray();
175: }
176: };
177: }
178:
179: /**
180: * Get the defualt widget height for the supplied control.
181: * @return int
182: * @param control - the control being queried about fonts
183: * @param lines - the number of lines to be shown on the table.
184: */
185: private static int getDefaultFontHeight(Control control, int lines) {
186: FontData[] viewerFontData = control.getFont().getFontData();
187: int fontHeight = 10;
188:
189: //If we have no font data use our guess
190: if (viewerFontData.length > 0) {
191: fontHeight = viewerFontData[0].getHeight();
192: }
193: return lines * fontHeight;
194:
195: }
196:
197: /**
198: * Handle the exception thrown when saving.
199: * @param e the exception
200: */
201: protected void handle(InvocationTargetException e) {
202: IStatus error;
203: Throwable target = e.getTargetException();
204: if (target instanceof CoreException) {
205: error = ((CoreException) target).getStatus();
206: } else {
207: String msg = target.getMessage();
208: if (msg == null) {
209: msg = IDEWorkbenchMessages.Internal_error;
210: }
211: error = new Status(IStatus.ERROR,
212: IDEWorkbenchPlugin.IDE_WORKBENCH, 1, msg, target);
213: }
214: ErrorDialog.openError(getControl().getShell(), null, null,
215: error);
216: }
217:
218: /**
219: * Initializes a ProjectReferencePage.
220: */
221: private void initialize() {
222: project = (IProject) getElement().getAdapter(IResource.class);
223: noDefaultAndApplyButton();
224: setDescription(NLS.bind(
225: IDEWorkbenchMessages.ProjectReferencesPage_label,
226: project.getName()));
227: }
228:
229: /**
230: * @see PreferencePage#performOk
231: */
232: public boolean performOk() {
233: if (!modified) {
234: return true;
235: }
236: Object[] checked = listViewer.getCheckedElements();
237: final IProject[] refs = new IProject[checked.length];
238: System.arraycopy(checked, 0, refs, 0, checked.length);
239: IRunnableWithProgress runnable = new IRunnableWithProgress() {
240: public void run(IProgressMonitor monitor)
241: throws InvocationTargetException {
242:
243: try {
244: IProjectDescription description = project
245: .getDescription();
246: description.setReferencedProjects(refs);
247: project.setDescription(description, monitor);
248: } catch (CoreException e) {
249: throw new InvocationTargetException(e);
250: }
251: }
252: };
253: try {
254: new ProgressMonitorJobsDialog(getControl().getShell()).run(
255: true, true, runnable);
256: } catch (InterruptedException e) {
257: //Ignore interrupted exceptions
258: } catch (InvocationTargetException e) {
259: handle(e);
260: return false;
261: }
262: return true;
263: }
264: }
|