001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 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.pde.internal.ui.preferences;
011:
012: import java.io.File;
013: import java.util.ArrayList;
014: import java.util.Arrays;
015:
016: import org.eclipse.core.runtime.IConfigurationElement;
017: import org.eclipse.core.runtime.IExtension;
018: import org.eclipse.core.runtime.IPath;
019: import org.eclipse.core.runtime.Path;
020: import org.eclipse.core.runtime.Preferences;
021: import org.eclipse.core.runtime.spi.RegistryContributor;
022: import org.eclipse.jface.dialogs.Dialog;
023: import org.eclipse.jface.resource.ImageDescriptor;
024: import org.eclipse.jface.viewers.ISelectionChangedListener;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.viewers.ITreeContentProvider;
027: import org.eclipse.jface.viewers.LabelProvider;
028: import org.eclipse.jface.viewers.SelectionChangedEvent;
029: import org.eclipse.jface.viewers.StructuredSelection;
030: import org.eclipse.jface.viewers.TreeViewer;
031: import org.eclipse.osgi.service.resolver.BundleDescription;
032: import org.eclipse.osgi.service.resolver.State;
033: import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
034: import org.eclipse.pde.core.plugin.IPluginModelBase;
035: import org.eclipse.pde.internal.core.ICoreConstants;
036: import org.eclipse.pde.internal.core.PDECore;
037: import org.eclipse.pde.internal.core.SourceLocation;
038: import org.eclipse.pde.internal.core.SourceLocationManager;
039: import org.eclipse.pde.internal.core.itarget.ITarget;
040: import org.eclipse.pde.internal.ui.IHelpContextIds;
041: import org.eclipse.pde.internal.ui.PDEPluginImages;
042: import org.eclipse.pde.internal.ui.PDEUIMessages;
043: import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
044: import org.eclipse.pde.internal.ui.search.ShowDescriptionAction;
045: import org.eclipse.pde.internal.ui.util.OverlayIcon;
046: import org.eclipse.pde.internal.ui.util.SWTUtil;
047: import org.eclipse.swt.SWT;
048: import org.eclipse.swt.events.KeyAdapter;
049: import org.eclipse.swt.events.KeyEvent;
050: import org.eclipse.swt.events.SelectionAdapter;
051: import org.eclipse.swt.events.SelectionEvent;
052: import org.eclipse.swt.graphics.Image;
053: import org.eclipse.swt.layout.GridData;
054: import org.eclipse.swt.layout.GridLayout;
055: import org.eclipse.swt.widgets.Button;
056: import org.eclipse.swt.widgets.Composite;
057: import org.eclipse.swt.widgets.Control;
058: import org.eclipse.swt.widgets.DirectoryDialog;
059: import org.eclipse.swt.widgets.Link;
060: import org.eclipse.ui.ISharedImages;
061: import org.eclipse.ui.PlatformUI;
062:
063: public class TargetSourceTab {
064: private Image fFolderImage;
065: private TreeViewer fTreeViewer;
066: private Image fExtensionImage;
067: private Image fUserImage;
068:
069: private SourceLocation[] fExtensionLocations = new SourceLocation[0];
070: private ArrayList fUserLocations = new ArrayList();
071: private NamedElement fSystemNode;
072: private NamedElement fUserNode;
073: private Button fAddButton;
074: private Button fRemoveButton;
075: private String fLastUserPath = null;
076:
077: private TargetPlatformPreferencePage fPage = null;
078:
079: class NamedElement {
080: String text;
081:
082: public NamedElement(String text) {
083: this .text = text;
084: }
085:
086: public String toString() {
087: return text;
088: }
089: }
090:
091: class SourceProvider extends DefaultContentProvider implements
092: ITreeContentProvider {
093: public Object[] getElements(Object input) {
094: return new Object[] { fSystemNode, fUserNode };
095: }
096:
097: public Object[] getChildren(Object element) {
098: if (element.equals(fUserNode))
099: return fUserLocations.toArray();
100: if (element.equals(fSystemNode))
101: return getSourceLocations();
102: return new Object[0];
103: }
104:
105: public Object getParent(Object element) {
106: if (element instanceof SourceLocation) {
107: SourceLocation loc = (SourceLocation) element;
108: return loc.isUserDefined() ? fUserNode : fSystemNode;
109: }
110: return null;
111: }
112:
113: public boolean hasChildren(Object element) {
114: if (element.equals(fSystemNode))
115: return true;
116: if (element.equals(fUserNode))
117: return fUserLocations.size() > 0;
118: return false;
119: }
120: }
121:
122: class SourceLabelProvider extends LabelProvider {
123: public String getText(Object obj) {
124: if (obj instanceof SourceLocation) {
125: SourceLocation location = (SourceLocation) obj;
126: return location.getPath().toOSString();
127: }
128: return super .getText(obj);
129: }
130:
131: public Image getImage(Object obj) {
132: if (obj instanceof SourceLocation)
133: return fFolderImage;
134:
135: return obj.equals(fUserNode) ? fUserImage : fExtensionImage;
136: }
137: }
138:
139: public TargetSourceTab(TargetPlatformPreferencePage page) {
140: initializeImages();
141: fSystemNode = new NamedElement(PDEUIMessages.SourceBlock_target);
142: fUserNode = new NamedElement(
143: PDEUIMessages.SourceBlock_additional);
144: SourceLocationManager manager = PDECore.getDefault()
145: .getSourceLocationManager();
146: fExtensionLocations = manager.getExtensionLocations();
147: fUserLocations
148: .addAll(Arrays.asList(manager.getUserLocations()));
149: fPage = page;
150: }
151:
152: private void initializeImages() {
153: fExtensionImage = PDEPluginImages.DESC_SOURCE_ATTACHMENT_OBJ
154: .createImage();
155: ImageDescriptor userDesc = new OverlayIcon(
156: PDEPluginImages.DESC_SOURCE_ATTACHMENT_OBJ,
157: new ImageDescriptor[][] { { PDEPluginImages.DESC_DOC_CO } });
158: fUserImage = userDesc.createImage();
159: fFolderImage = PlatformUI.getWorkbench().getSharedImages()
160: .getImage(ISharedImages.IMG_OBJ_FOLDER);
161: }
162:
163: public void resetExtensionLocations(IPluginModelBase[] models) {
164: fTreeViewer.getTree().getItem(0).setExpanded(false);
165: fTreeViewer.refresh(fSystemNode);
166: fExtensionLocations = null;
167: }
168:
169: private String encodeSourceLocations() {
170: StringBuffer buf = new StringBuffer();
171: for (int i = 0; i < fUserLocations.size(); i++) {
172: if (i > 0)
173: buf.append(File.pathSeparatorChar);
174: buf.append(((SourceLocation) fUserLocations.get(i))
175: .getPath().toOSString());
176: }
177: return buf.toString();
178: }
179:
180: public void dispose() {
181: fExtensionImage.dispose();
182: fUserImage.dispose();
183: }
184:
185: /**
186: * @see IPreferencePage#performOk()
187: */
188: public boolean performOk() {
189: Preferences preferences = PDECore.getDefault()
190: .getPluginPreferences();
191: preferences.setValue(ICoreConstants.P_SOURCE_LOCATIONS,
192: encodeSourceLocations());
193: // fExtensionLocations either equal actual locations or null. If null, by setting ExtensionLocations to null, the locations will be lazy loaded
194: PDECore.getDefault().getSourceLocationManager()
195: .setExtensionLocations(fExtensionLocations);
196: PDECore.getDefault().getJavadocLocationManager().reset();
197: return true;
198: }
199:
200: public void performDefaults() {
201: fUserLocations.clear();
202: fTreeViewer.refresh();
203: }
204:
205: protected void loadTargetProfile(ITarget target) {
206: // this tab should do nothing. It may later be removed altogether
207: }
208:
209: protected void handleAdd() {
210: String path = getDirectoryDialog(fLastUserPath).open();
211: if (path != null) {
212: SourceLocation location = new SourceLocation(new Path(path));
213: fUserLocations.add(location);
214: fTreeViewer.add(fUserNode, location);
215: fTreeViewer.setSelection(new StructuredSelection(location));
216: fLastUserPath = path;
217: }
218: }
219:
220: private DirectoryDialog getDirectoryDialog(String filterPath) {
221: DirectoryDialog dialog = new DirectoryDialog(fPage.getShell());
222: dialog
223: .setMessage(PDEUIMessages.SourcePreferencePage_dialogMessage);
224: if (filterPath != null)
225: dialog.setFilterPath(filterPath);
226: return dialog;
227: }
228:
229: protected void handleRemove() {
230: IStructuredSelection selection = (IStructuredSelection) fTreeViewer
231: .getSelection();
232: Object object = selection.getFirstElement();
233: if (object instanceof SourceLocation) {
234: SourceLocation location = (SourceLocation) object;
235: if (location.isUserDefined()) {
236: fUserLocations.remove(location);
237: fTreeViewer.remove(location);
238: }
239: }
240: }
241:
242: /**
243: * @see IDialogPage#createControl(Composite)
244: */
245: public Control createContents(Composite parent) {
246: Composite container = new Composite(parent, SWT.NULL);
247: GridLayout layout = new GridLayout();
248: layout.numColumns = 2;
249: layout.verticalSpacing = 10;
250: container.setLayout(layout);
251:
252: Link text = new Link(container, SWT.WRAP);
253: text.setText(PDEUIMessages.SourceBlock_desc);
254: GridData gd = new GridData();
255: gd.horizontalSpan = 2;
256: gd.widthHint = 400;
257: text.setLayoutData(gd);
258: text.addSelectionListener(new SelectionAdapter() {
259: public void widgetSelected(SelectionEvent e) {
260: IPluginExtensionPoint point = PDECore.getDefault()
261: .getExtensionsRegistry().findExtensionPoint(
262: "org.eclipse.pde.core.source"); //$NON-NLS-1$
263: if (point != null)
264: new ShowDescriptionAction(point, true).run();
265: }
266: });
267:
268: fTreeViewer = new TreeViewer(container, SWT.BORDER);
269: gd = new GridData(GridData.FILL_BOTH);
270: gd.widthHint = 1;
271: gd.heightHint = 1;
272: fTreeViewer.getTree().setLayoutData(gd);
273: fTreeViewer.setContentProvider(new SourceProvider());
274: fTreeViewer.setLabelProvider(new SourceLabelProvider());
275: fTreeViewer.setInput(this );
276: fTreeViewer.expandAll();
277: fTreeViewer
278: .addSelectionChangedListener(new ISelectionChangedListener() {
279: public void selectionChanged(
280: SelectionChangedEvent event) {
281: IStructuredSelection ssel = (IStructuredSelection) event
282: .getSelection();
283: boolean removeEnabled = false;
284: if (ssel != null && ssel.size() > 0) {
285: Object object = ssel.getFirstElement();
286: removeEnabled = (object instanceof SourceLocation && ((SourceLocation) object)
287: .isUserDefined());
288: }
289: fRemoveButton.setEnabled(removeEnabled);
290: }
291: });
292: fTreeViewer.getTree().addKeyListener(new KeyAdapter() {
293: public void keyPressed(KeyEvent event) {
294: if (event.character == SWT.DEL && event.stateMask == 0) {
295: handleRemove();
296: }
297: }
298: });
299:
300: Composite buttonContainer = new Composite(container, SWT.NONE);
301: layout = new GridLayout();
302: layout.marginWidth = layout.marginHeight = 0;
303: buttonContainer.setLayout(layout);
304: buttonContainer.setLayoutData(new GridData(
305: GridData.FILL_VERTICAL));
306:
307: fAddButton = new Button(buttonContainer, SWT.PUSH);
308: fAddButton.setText(PDEUIMessages.SourceBlock_add);
309: fAddButton.setLayoutData(new GridData(GridData.FILL
310: | GridData.VERTICAL_ALIGN_BEGINNING));
311: SWTUtil.setButtonDimensionHint(fAddButton);
312: fAddButton.addSelectionListener(new SelectionAdapter() {
313: public void widgetSelected(SelectionEvent e) {
314: handleAdd();
315: }
316: });
317:
318: fRemoveButton = new Button(buttonContainer, SWT.PUSH);
319: fRemoveButton.setText(PDEUIMessages.SourceBlock_remove);
320: fRemoveButton.setLayoutData(new GridData(GridData.FILL
321: | GridData.VERTICAL_ALIGN_BEGINNING));
322: SWTUtil.setButtonDimensionHint(fRemoveButton);
323: fRemoveButton.addSelectionListener(new SelectionAdapter() {
324: public void widgetSelected(SelectionEvent e) {
325: handleRemove();
326: }
327: });
328: fRemoveButton.setEnabled(false);
329:
330: Dialog.applyDialogFont(parent);
331: PlatformUI.getWorkbench().getHelpSystem().setHelp(container,
332: IHelpContextIds.SOURCE_PREFERENCE_PAGE);
333: return container;
334: }
335:
336: private SourceLocation[] getSourceLocations() {
337: if (fExtensionLocations == null) {
338: ArrayList result = new ArrayList();
339: IExtension[] extensions = fPage.getExtensionRegistry()
340: .findExtensions(PDECore.PLUGIN_ID + ".source"); //$NON-NLS-1$
341: State resolverState = fPage.getCurrentState().getState();
342: for (int i = 0; i < extensions.length; i++) {
343: long id = Long
344: .parseLong(((RegistryContributor) extensions[i]
345: .getContributor()).getId());
346: BundleDescription desc = resolverState.getBundle(id);
347: IPath path = new Path(desc.getLocation());
348: IConfigurationElement[] children = extensions[i]
349: .getConfigurationElements();
350: for (int j = 0; j < children.length; j++) {
351: if (children[j].getName().equals("location")) { //$NON-NLS-1$
352: String pathAttr = children[j]
353: .getAttribute("path"); //$NON-NLS-1$
354: path.append(pathAttr);
355: if (path.toFile().exists()) {
356: SourceLocation location = new SourceLocation(
357: path);
358: location.setUserDefined(false);
359: if (!result.contains(location))
360: result.add(location);
361: }
362: }
363: }
364: }
365: fExtensionLocations = (SourceLocation[]) result
366: .toArray(new SourceLocation[result.size()]);
367: }
368: return fExtensionLocations;
369: }
370:
371: }
|