001: /*******************************************************************************
002: * Copyright (c) 2000, 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.editor.plugin;
011:
012: import org.eclipse.core.resources.IContainer;
013: import org.eclipse.core.resources.IFile;
014: import org.eclipse.core.resources.IProject;
015: import org.eclipse.core.resources.IResource;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Path;
019: import org.eclipse.core.runtime.Status;
020: import org.eclipse.jface.viewers.ISelection;
021: import org.eclipse.jface.viewers.IStructuredSelection;
022: import org.eclipse.jface.viewers.Viewer;
023: import org.eclipse.jface.viewers.ViewerFilter;
024: import org.eclipse.jface.window.Window;
025: import org.eclipse.jface.wizard.WizardDialog;
026: import org.eclipse.pde.core.IBaseModel;
027: import org.eclipse.pde.core.IModelChangedEvent;
028: import org.eclipse.pde.core.plugin.IPluginBase;
029: import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
030: import org.eclipse.pde.core.plugin.IPluginModelBase;
031: import org.eclipse.pde.internal.ui.IPDEUIConstants;
032: import org.eclipse.pde.internal.ui.PDEPlugin;
033: import org.eclipse.pde.internal.ui.PDEPluginImages;
034: import org.eclipse.pde.internal.ui.PDEUIMessages;
035: import org.eclipse.pde.internal.ui.editor.FormEntryAdapter;
036: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
037: import org.eclipse.pde.internal.ui.editor.PDEDetails;
038: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
039: import org.eclipse.pde.internal.ui.editor.actions.OpenSchemaAction;
040: import org.eclipse.pde.internal.ui.parts.FormEntry;
041: import org.eclipse.pde.internal.ui.search.FindReferencesAction;
042: import org.eclipse.pde.internal.ui.search.ShowDescriptionAction;
043: import org.eclipse.pde.internal.ui.util.SWTUtil;
044: import org.eclipse.pde.internal.ui.wizards.extension.NewSchemaFileWizard;
045: import org.eclipse.swt.SWT;
046: import org.eclipse.swt.custom.BusyIndicator;
047: import org.eclipse.swt.layout.GridData;
048: import org.eclipse.swt.widgets.Composite;
049: import org.eclipse.swt.widgets.Display;
050: import org.eclipse.ui.IWorkbenchWindow;
051: import org.eclipse.ui.PartInitException;
052: import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
053: import org.eclipse.ui.dialogs.ISelectionStatusValidator;
054: import org.eclipse.ui.forms.IFormPart;
055: import org.eclipse.ui.forms.events.HyperlinkAdapter;
056: import org.eclipse.ui.forms.events.HyperlinkEvent;
057: import org.eclipse.ui.forms.widgets.ExpandableComposite;
058: import org.eclipse.ui.forms.widgets.FormText;
059: import org.eclipse.ui.forms.widgets.FormToolkit;
060: import org.eclipse.ui.forms.widgets.Section;
061: import org.eclipse.ui.model.WorkbenchContentProvider;
062: import org.eclipse.ui.model.WorkbenchLabelProvider;
063: import org.eclipse.ui.part.FileEditorInput;
064: import org.eclipse.ui.views.navigator.ResourceComparator;
065:
066: public class ExtensionPointDetails extends PDEDetails {
067: private IPluginExtensionPoint fInput;
068: private FormEntry fIdEntry;
069: private FormEntry fNameEntry;
070: private FormEntry fSchemaEntry;
071: private FormText fRichText;
072: private String fRichTextData;
073:
074: private static final String SCHEMA_RTEXT_DATA = PDEUIMessages.ExtensionPointDetails_schemaLinks;
075: private static final String NO_SCHEMA_RTEXT_DATA = PDEUIMessages.ExtensionPointDetails_noSchemaLinks;
076:
077: public ExtensionPointDetails() {
078: }
079:
080: public String getContextId() {
081: return PluginInputContext.CONTEXT_ID;
082: }
083:
084: public void fireSaveNeeded() {
085: markDirty();
086: getPage().getPDEEditor().fireSaveNeeded(getContextId(), false);
087: }
088:
089: public PDEFormPage getPage() {
090: return (PDEFormPage) getManagedForm().getContainer();
091: }
092:
093: public boolean isEditable() {
094: return getPage().getPDEEditor().getAggregateModel()
095: .isEditable();
096: }
097:
098: /*
099: * (non-Javadoc)
100: *
101: * @see org.eclipse.ui.forms.IDetailsPage#createContents(org.eclipse.swt.widgets.Composite)
102: */
103: public void createContents(Composite parent) {
104: parent.setLayout(FormLayoutFactory.createDetailsGridLayout(
105: false, 1));
106: FormToolkit toolkit = getManagedForm().getToolkit();
107: Section section = toolkit.createSection(parent,
108: Section.DESCRIPTION | ExpandableComposite.TITLE_BAR);
109: section.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
110: section.setText(PDEUIMessages.ExtensionPointDetails_title);
111: section
112: .setDescription(PDEUIMessages.ExtensionPointDetails_desc);
113: section.setLayout(FormLayoutFactory.createClearGridLayout(
114: false, 1));
115: section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
116: | GridData.VERTICAL_ALIGN_BEGINNING));
117:
118: Composite client = toolkit.createComposite(section);
119: client.setLayout(FormLayoutFactory
120: .createSectionClientGridLayout(false, 3));
121: client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
122:
123: fIdEntry = new FormEntry(client, toolkit,
124: PDEUIMessages.ExtensionPointDetails_id, null, false);
125: fIdEntry.setFormEntryListener(new FormEntryAdapter(this ) {
126: public void textValueChanged(FormEntry entry) {
127: if (fInput != null) {
128: try {
129: fInput.setId(fIdEntry.getValue());
130: } catch (CoreException e) {
131: PDEPlugin.logException(e);
132: }
133: }
134: }
135: });
136: fNameEntry = new FormEntry(client, toolkit,
137: PDEUIMessages.ExtensionPointDetails_name, null, false);
138: fNameEntry.setFormEntryListener(new FormEntryAdapter(this ) {
139: public void textValueChanged(FormEntry entry) {
140: if (fInput != null)
141: try {
142: fInput.setName(fNameEntry.getValue());
143: } catch (CoreException e) {
144: PDEPlugin.logException(e);
145: }
146: }
147: });
148: boolean editable = getPage().getModel().isEditable();
149: fSchemaEntry = new FormEntry(client, toolkit,
150: PDEUIMessages.ExtensionPointDetails_schema,
151: PDEUIMessages.ExtensionPointDetails_browse, editable); //
152: fSchemaEntry.setFormEntryListener(new FormEntryAdapter(this ) {
153: public void textValueChanged(FormEntry entry) {
154: if (fInput != null) {
155: try {
156: fInput.setSchema(fSchemaEntry.getValue());
157: } catch (CoreException e) {
158: PDEPlugin.logException(e);
159: }
160: updateRichText();
161: }
162: }
163:
164: public void linkActivated(HyperlinkEvent e) {
165: IProject project = getPage().getPDEEditor()
166: .getCommonProject();
167: if (fSchemaEntry.getValue() == null
168: || fSchemaEntry.getValue().length() == 0) {
169: generateSchema();
170: return;
171: }
172: IFile file = project.getFile(fSchemaEntry.getValue());
173: if (file.exists())
174: openSchemaFile(file);
175: else
176: generateSchema();
177: }
178:
179: public void browseButtonSelected(FormEntry entry) {
180: final IProject project = getPage().getPDEEditor()
181: .getCommonProject();
182: ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
183: PDEPlugin.getActiveWorkbenchShell(),
184: new WorkbenchLabelProvider(),
185: new WorkbenchContentProvider());
186: dialog
187: .setTitle(PDEUIMessages.ManifestEditor_ExtensionPointDetails_schemaLocation_title);
188: dialog
189: .setMessage(PDEUIMessages.ManifestEditor_ExtensionPointDetails_schemaLocation_desc);
190: dialog.setDoubleClickSelects(false);
191: dialog.setAllowMultiple(false);
192: dialog.addFilter(new ViewerFilter() {
193: public boolean select(Viewer viewer, Object parent,
194: Object element) {
195: if (element instanceof IFile) {
196: String ext = ((IFile) element)
197: .getFullPath().getFileExtension();
198: return "exsd".equals(ext) || "mxsd".equals(ext); //$NON-NLS-1$ //$NON-NLS-2$
199: } else if (element instanceof IContainer) { // i.e. IProject, IFolder
200: try {
201: IResource[] resources = ((IContainer) element)
202: .members();
203: for (int i = 0; i < resources.length; i++) {
204: if (select(viewer, parent,
205: resources[i]))
206: return true;
207: }
208: } catch (CoreException e) {
209: PDEPlugin.logException(e);
210: }
211: }
212: return false;
213: }
214: });
215: dialog.setValidator(new ISelectionStatusValidator() {
216: public IStatus validate(Object[] selection) {
217: IPluginModelBase model = (IPluginModelBase) getPage()
218: .getPDEEditor().getAggregateModel();
219: String pluginName = model.getPluginBase()
220: .getId();
221:
222: if (selection == null || selection.length != 1
223: || !(selection[0] instanceof IFile))
224: return new Status(
225: IStatus.ERROR,
226: pluginName,
227: IStatus.ERROR,
228: PDEUIMessages.ManifestEditor_ExtensionPointDetails_validate_errorStatus,
229: null);
230: IFile file = (IFile) selection[0];
231: String ext = file.getFullPath()
232: .getFileExtension();
233: if ("exsd".equals(ext) || "mxsd".equals(ext)) //$NON-NLS-1$ //$NON-NLS-2$
234: return new Status(IStatus.OK, pluginName,
235: IStatus.OK, "", null); //$NON-NLS-1$
236: return new Status(
237: IStatus.ERROR,
238: pluginName,
239: IStatus.ERROR,
240: PDEUIMessages.ManifestEditor_ExtensionPointDetails_validate_errorStatus,
241: null);
242: }
243: });
244: dialog.setDoubleClickSelects(true);
245: dialog.setStatusLineAboveButtons(true);
246: dialog.setInput(project);
247: dialog.setComparator(new ResourceComparator(
248: ResourceComparator.NAME));
249: String filePath = fSchemaEntry.getValue();
250: if (filePath != null && filePath.length() != 0
251: && project.exists(new Path(filePath)))
252: dialog.setInitialSelection(project
253: .getFile(new Path(filePath)));
254: else
255: dialog.setInitialSelection(null);
256: if (dialog.open() == Window.OK) {
257: Object[] elements = dialog.getResult();
258: if (elements.length > 0) {
259: IResource elem = (IResource) elements[0];
260: fSchemaEntry.setValue(elem
261: .getProjectRelativePath().toString());
262: }
263: }
264: }
265: });
266: createSpacer(toolkit, client, 2);
267:
268: Composite container = toolkit.createComposite(parent, SWT.NONE);
269: container.setLayout(FormLayoutFactory
270: .createSectionClientGridLayout(false, 1));
271: container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
272: | GridData.VERTICAL_ALIGN_BEGINNING));
273:
274: fRichText = toolkit.createFormText(container, true);
275: fRichText.setImage(
276: "open", PDEPlugin.getDefault().getLabelProvider().get( //$NON-NLS-1$
277: PDEPluginImages.DESC_SCHEMA_OBJ));
278: fRichText.setImage(
279: "desc", PDEPlugin.getDefault().getLabelProvider().get( //$NON-NLS-1$
280: PDEPluginImages.DESC_DOC_SECTION_OBJ));
281: fRichText
282: .setImage(
283: "search", PDEPlugin.getDefault().getLabelProvider().get( //$NON-NLS-1$
284: PDEPluginImages.DESC_PSEARCH_OBJ));
285: fRichText.addHyperlinkListener(new HyperlinkAdapter() {
286: public void linkActivated(HyperlinkEvent e) {
287: IBaseModel model = getPage().getPDEEditor()
288: .getAggregateModel();
289: String pointID = null;
290: IPluginBase base = ((IPluginModelBase) model)
291: .getPluginBase();
292: String pluginID = base.getId();
293: if (Double.parseDouble(base.getSchemaVersion()) >= 3.2) {
294: if (fInput.getId().indexOf('.') != -1)
295: pointID = fInput.getId();
296: }
297: if (pointID == null)
298: pointID = pluginID + "." + fInput.getId(); //$NON-NLS-1$
299: if (e.getHref().equals("search")) { //$NON-NLS-1$
300: new FindReferencesAction(fInput, pluginID).run();
301: } else if (e.getHref().equals("open")) { //$NON-NLS-1$
302: OpenSchemaAction action = new OpenSchemaAction();
303: action.setInput(pointID);
304: action.setEnabled(true);
305: action.run();
306: } else {
307: new ShowDescriptionAction(pointID).run();
308: }
309: }
310: });
311:
312: fIdEntry.setEditable(isEditable());
313: fNameEntry.setEditable(isEditable());
314: fSchemaEntry.setEditable(isEditable());
315: toolkit.paintBordersFor(client);
316: section.setClient(client);
317: IPluginModelBase model = (IPluginModelBase) getPage()
318: .getModel();
319: model.addModelChangedListener(this );
320: markDetailsPart(section);
321: }
322:
323: public void dispose() {
324: IPluginModelBase model = (IPluginModelBase) getPage()
325: .getModel();
326: if (model != null)
327: model.removeModelChangedListener(this );
328: super .dispose();
329: }
330:
331: public void modelChanged(IModelChangedEvent e) {
332: if (e.getChangeType() == IModelChangedEvent.CHANGE) {
333: Object obj = e.getChangedObjects()[0];
334: if (obj.equals(fInput))
335: refresh();
336: }
337: }
338:
339: private void update() {
340: fIdEntry.setValue(
341: fInput != null && fInput.getId() != null ? fInput
342: .getId() : "", //$NON-NLS-1$
343: true);
344: fNameEntry.setValue(
345: fInput != null && fInput.getName() != null ? fInput
346: .getName() : "", true); //$NON-NLS-1$
347: fSchemaEntry.setValue(
348: fInput != null && fInput.getSchema() != null ? fInput
349: .getSchema() : "", true); //$NON-NLS-1$
350: updateRichText();
351: }
352:
353: public void cancelEdit() {
354: fIdEntry.cancelEdit();
355: fNameEntry.cancelEdit();
356: fSchemaEntry.cancelEdit();
357: updateRichText();
358: super .cancelEdit();
359: }
360:
361: private void updateRichText() {
362: boolean hasSchema = fSchemaEntry.getValue().length() > 0;
363: if (hasSchema && fRichTextData == SCHEMA_RTEXT_DATA)
364: return;
365: if (!hasSchema && fRichTextData == NO_SCHEMA_RTEXT_DATA)
366: return;
367: fRichTextData = hasSchema ? SCHEMA_RTEXT_DATA
368: : NO_SCHEMA_RTEXT_DATA;
369: fRichText.setText(fRichTextData, true, false);
370: getManagedForm().getForm().reflow(true);
371: }
372:
373: private void openSchemaFile(final IFile file) {
374: final IWorkbenchWindow ww = PDEPlugin
375: .getActiveWorkbenchWindow();
376:
377: Display d = ww.getShell().getDisplay();
378: d.asyncExec(new Runnable() {
379: public void run() {
380: try {
381: String editorId = IPDEUIConstants.SCHEMA_EDITOR_ID;
382: ww.getActivePage().openEditor(
383: new FileEditorInput(file), editorId);
384: } catch (PartInitException e) {
385: PDEPlugin.logException(e);
386: }
387: }
388: });
389: }
390:
391: private void generateSchema() {
392: final IProject project = getPage().getPDEEditor()
393: .getCommonProject();
394: BusyIndicator.showWhile(
395: getPage().getPartControl().getDisplay(),
396: new Runnable() {
397: public void run() {
398: NewSchemaFileWizard wizard = new NewSchemaFileWizard(
399: project, fInput, true);
400: WizardDialog dialog = new WizardDialog(
401: PDEPlugin.getActiveWorkbenchShell(),
402: wizard);
403: dialog.create();
404: SWTUtil.setDialogSize(dialog, 400, 450);
405: if (dialog.open() == Window.OK)
406: update();
407: }
408: });
409: }
410:
411: /*
412: * (non-Javadoc)
413: *
414: * @see org.eclipse.ui.forms.IDetailsPage#inputChanged(org.eclipse.jface.viewers.IStructuredSelection)
415: */
416: public void selectionChanged(IFormPart masterPart,
417: ISelection selection) {
418: IStructuredSelection ssel = (IStructuredSelection) selection;
419: if (ssel.size() == 1) {
420: fInput = (IPluginExtensionPoint) ssel.getFirstElement();
421: } else
422: fInput = null;
423: update();
424: }
425:
426: /*
427: * (non-Javadoc)
428: *
429: * @see org.eclipse.ui.forms.IDetailsPage#commit()
430: */
431: public void commit(boolean onSave) {
432: fIdEntry.commit();
433: fNameEntry.commit();
434: fSchemaEntry.commit();
435: super .commit(onSave);
436: }
437:
438: /*
439: * (non-Javadoc)
440: *
441: * @see org.eclipse.ui.forms.IDetailsPage#setFocus()
442: */
443: public void setFocus() {
444: fIdEntry.getText().setFocus();
445: }
446:
447: /*
448: * (non-Javadoc)
449: *
450: * @see org.eclipse.ui.forms.IDetailsPage#refresh()
451: */
452: public void refresh() {
453: update();
454: super.refresh();
455: }
456:
457: }
|