001: /*******************************************************************************
002: * Copyright (c) 2003, 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 java.io.File;
013:
014: import org.eclipse.core.resources.IFile;
015: import org.eclipse.core.resources.IProject;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.NullProgressMonitor;
019: import org.eclipse.jface.action.Action;
020: import org.eclipse.jface.action.IMenuManager;
021: import org.eclipse.jface.action.Separator;
022: import org.eclipse.jface.dialogs.MessageDialog;
023: import org.eclipse.jface.viewers.ISelection;
024: import org.eclipse.jface.viewers.IStructuredContentProvider;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.viewers.StructuredSelection;
027: import org.eclipse.jface.viewers.TableViewer;
028: import org.eclipse.jface.wizard.WizardDialog;
029: import org.eclipse.osgi.util.NLS;
030: import org.eclipse.pde.core.IBaseModel;
031: import org.eclipse.pde.core.IModelChangeProvider;
032: import org.eclipse.pde.core.IModelChangedEvent;
033: import org.eclipse.pde.core.plugin.IPluginBase;
034: import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
035: import org.eclipse.pde.core.plugin.IPluginModelBase;
036: import org.eclipse.pde.core.plugin.ISharedExtensionsModel;
037: import org.eclipse.pde.internal.core.PDECore;
038: import org.eclipse.pde.internal.core.SourceLocationManager;
039: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
040: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
041: import org.eclipse.pde.internal.ui.PDEPlugin;
042: import org.eclipse.pde.internal.ui.PDEUIMessages;
043: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
044: import org.eclipse.pde.internal.ui.editor.SystemFileEditorInput;
045: import org.eclipse.pde.internal.ui.editor.TableSection;
046: import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
047: import org.eclipse.pde.internal.ui.parts.TablePart;
048: import org.eclipse.pde.internal.ui.search.PluginSearchActionGroup;
049: import org.eclipse.pde.internal.ui.util.SWTUtil;
050: import org.eclipse.pde.internal.ui.wizards.extension.NewExtensionPointWizard;
051: import org.eclipse.swt.SWT;
052: import org.eclipse.swt.custom.BusyIndicator;
053: import org.eclipse.swt.widgets.Composite;
054: import org.eclipse.swt.widgets.Table;
055: import org.eclipse.swt.widgets.TableItem;
056: import org.eclipse.ui.IEditorInput;
057: import org.eclipse.ui.IFileEditorInput;
058: import org.eclipse.ui.actions.ActionContext;
059: import org.eclipse.ui.actions.ActionFactory;
060: import org.eclipse.ui.forms.widgets.ExpandableComposite;
061: import org.eclipse.ui.forms.widgets.FormToolkit;
062: import org.eclipse.ui.forms.widgets.Section;
063:
064: public class ExtensionPointsSection extends TableSection {
065: private TableViewer pointTable;
066:
067: class TableContentProvider extends DefaultContentProvider implements
068: IStructuredContentProvider {
069: public Object[] getElements(Object parent) {
070: IPluginModelBase model = (IPluginModelBase) getPage()
071: .getModel();
072: IPluginBase pluginBase = model.getPluginBase();
073: if (pluginBase != null)
074: return pluginBase.getExtensionPoints();
075: return new Object[0];
076: }
077: }
078:
079: public ExtensionPointsSection(PDEFormPage page, Composite parent) {
080: super (
081: page,
082: parent,
083: ExpandableComposite.TITLE_BAR | Section.DESCRIPTION,
084: new String[] { PDEUIMessages.ManifestEditor_DetailExtensionPointSection_new });
085: getSection()
086: .setText(
087: PDEUIMessages.ManifestEditor_DetailExtensionPointSection_title);
088: getSection()
089: .setDescription(
090: PDEUIMessages.ExtensionPointsSection_sectionDescAllExtensionPoints);
091: fHandleDefaultButton = false;
092: getTablePart().setEditable(false);
093: }
094:
095: public void createClient(Section section, FormToolkit toolkit) {
096: Composite container = createClientContainer(section, 2, toolkit);
097: TablePart tablePart = getTablePart();
098: createViewerPartControl(container, SWT.MULTI, 2, toolkit);
099: pointTable = tablePart.getTableViewer();
100: pointTable.setContentProvider(new TableContentProvider());
101: pointTable.setLabelProvider(PDEPlugin.getDefault()
102: .getLabelProvider());
103: toolkit.paintBordersFor(container);
104: section.setClient(container);
105: pointTable.setInput(getPage());
106: selectFirstExtensionPoint();
107: IBaseModel model = getPage().getModel();
108: if (model instanceof IModelChangeProvider)
109: ((IModelChangeProvider) model)
110: .addModelChangedListener(this );
111: tablePart.setButtonEnabled(0, model.isEditable());
112: }
113:
114: private void selectFirstExtensionPoint() {
115: Table table = pointTable.getTable();
116: TableItem[] items = table.getItems();
117: if (items.length == 0)
118: return;
119: TableItem firstItem = items[0];
120: Object obj = firstItem.getData();
121: pointTable.setSelection(new StructuredSelection(obj));
122: }
123:
124: void fireSelection() {
125: pointTable.setSelection(pointTable.getSelection());
126: }
127:
128: public void dispose() {
129: IBaseModel model = getPage().getModel();
130: if (model instanceof IModelChangeProvider)
131: ((IModelChangeProvider) model)
132: .removeModelChangedListener(this );
133: super .dispose();
134: }
135:
136: public boolean doGlobalAction(String actionId) {
137:
138: if (!isEditable()) {
139: return false;
140: }
141:
142: if (actionId.equals(ActionFactory.DELETE.getId())) {
143: handleDelete();
144: return true;
145: }
146: if (actionId.equals(ActionFactory.CUT.getId())) {
147: // delete here and let the editor transfer
148: // the selection to the clipboard
149: handleDelete();
150: return false;
151: }
152: if (actionId.equals(ActionFactory.PASTE.getId())) {
153: doPaste();
154: return true;
155: }
156: return false;
157: }
158:
159: public void refresh() {
160: pointTable.refresh();
161: getManagedForm().fireSelectionChanged(this ,
162: pointTable.getSelection());
163: super .refresh();
164: }
165:
166: public boolean setFormInput(Object object) {
167: if (object instanceof IPluginExtensionPoint) {
168: pointTable.setSelection(new StructuredSelection(object),
169: true);
170: return true;
171: }
172: return false;
173: }
174:
175: protected void selectionChanged(IStructuredSelection selection) {
176: getPage().getPDEEditor().setSelection(selection);
177: super .selectionChanged(selection);
178: }
179:
180: public void modelChanged(IModelChangedEvent event) {
181: if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
182: markStale();
183: return;
184: }
185: Object changeObject = event.getChangedObjects()[0];
186: if (changeObject instanceof IPluginExtensionPoint) {
187: if (event.getChangeType() == IModelChangedEvent.INSERT) {
188: pointTable.add(changeObject);
189: pointTable.setSelection(new StructuredSelection(
190: changeObject), true);
191: pointTable.getTable().setFocus();
192: } else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
193: pointTable.remove(changeObject);
194: } else {
195: pointTable.update(changeObject, null);
196: }
197: }
198: }
199:
200: protected void fillContextMenu(IMenuManager manager) {
201: ISelection selection = pointTable.getSelection();
202:
203: Action newAction = new Action(
204: PDEUIMessages.ManifestEditor_DetailExtensionPointSection_newExtensionPoint) {
205: public void run() {
206: handleNew();
207: }
208: };
209: newAction.setEnabled(isEditable());
210: manager.add(newAction);
211:
212: if (selection.isEmpty()) {
213: getPage().getPDEEditor().getContributor()
214: .contextMenuAboutToShow(manager);
215: return;
216: }
217: manager.add(new Separator());
218: IBaseModel model = getPage().getPDEEditor().getAggregateModel();
219: PluginSearchActionGroup actionGroup = new PluginSearchActionGroup();
220: actionGroup.setBaseModel(model);
221: actionGroup.setContext(new ActionContext(selection));
222: actionGroup.fillContextMenu(manager);
223: manager.add(new Separator());
224:
225: Action deleteAction = new Action(
226: PDEUIMessages.Actions_delete_label) {
227: public void run() {
228: handleDelete();
229: }
230: };
231: deleteAction.setEnabled(isEditable());
232: manager.add(deleteAction);
233: getPage().getPDEEditor().getContributor()
234: .contextMenuAboutToShow(manager);
235: }
236:
237: protected void buttonSelected(int index) {
238: if (index == 0)
239: handleNew();
240: }
241:
242: private void handleDelete() {
243: Object[] selection = ((IStructuredSelection) pointTable
244: .getSelection()).toArray();
245: for (int i = 0; i < selection.length; i++) {
246: Object object = selection[i];
247: if (object != null
248: && object instanceof IPluginExtensionPoint) {
249: IStructuredSelection newSelection = null;
250: IPluginExtensionPoint ep = (IPluginExtensionPoint) object;
251: IPluginBase plugin = ep.getPluginBase();
252: IPluginExtensionPoint[] points = plugin
253: .getExtensionPoints();
254: int index = getNewSelectionIndex(getArrayIndex(points,
255: ep), points.length);
256: if (index != -1)
257: newSelection = new StructuredSelection(
258: points[index]);
259: try {
260: String schema = ep.getSchema();
261: IProject project = ep.getModel()
262: .getUnderlyingResource().getProject();
263: IFile schemaFile = project.getFile(schema);
264: if (schemaFile.exists())
265: if (MessageDialog
266: .openQuestion(
267: getSection().getShell(),
268: PDEUIMessages.ExtensionPointsSection_title,
269: NLS
270: .bind(
271: PDEUIMessages.ExtensionPointsSection_message1,
272: schemaFile
273: .getProjectRelativePath()
274: .toString())))
275: schemaFile.delete(true, true,
276: new NullProgressMonitor());
277: plugin.remove(ep);
278: if (newSelection != null)
279: pointTable.setSelection(newSelection);
280:
281: } catch (CoreException e) {
282: PDEPlugin.logException(e);
283: }
284: }
285: }
286: }
287:
288: private void handleNew() {
289: IFile file = ((IFileEditorInput) getPage().getPDEEditor()
290: .getEditorInput()).getFile();
291: final IProject project = file.getProject();
292: BusyIndicator.showWhile(pointTable.getTable().getDisplay(),
293: new Runnable() {
294: public void run() {
295: NewExtensionPointWizard wizard = new NewExtensionPointWizard(
296: project, (IPluginModelBase) getPage()
297: .getModel(),
298: (ManifestEditor) getPage()
299: .getPDEEditor());
300: WizardDialog dialog = new WizardDialog(
301: PDEPlugin.getActiveWorkbenchShell(),
302: wizard);
303: dialog.create();
304: SWTUtil.setDialogSize(dialog, 400, 450);
305: dialog.open();
306: }
307: });
308: }
309:
310: public static IEditorInput getSchemaFromSourceExtension(
311: IPluginBase plugin, IPath path) {
312: SourceLocationManager mgr = PDECore.getDefault()
313: .getSourceLocationManager();
314: File file = mgr.findSourceFile(plugin, path);
315: return (file != null && file.exists() && file.isFile()) ? new SystemFileEditorInput(
316: file)
317: : null;
318: }
319:
320: /**
321: * @return
322: */
323: private IPluginModelBase getPluginModelBase() {
324: // Note: This method will work with fragments as long as a fragment.xml
325: // is defined first. Otherwise, paste will not work out of the box.
326: // Get the model
327: IPluginModelBase model = (IPluginModelBase) getPage()
328: .getModel();
329: // Ensure the model is a bundle plugin model
330: if ((model instanceof IBundlePluginModelBase) == false) {
331: return null;
332: }
333: // Get the extension model
334: ISharedExtensionsModel extensionModel = ((IBundlePluginModelBase) model)
335: .getExtensionsModel();
336: // Ensure the extension model is defined
337: if ((extensionModel == null)
338: || ((extensionModel instanceof IPluginModelBase) == false)) {
339: return null;
340: }
341: return ((IPluginModelBase) extensionModel);
342: }
343:
344: /* (non-Javadoc)
345: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(java.lang.Object, java.lang.Object[])
346: */
347: protected void doPaste(Object targetObject, Object[] sourceObjects) {
348: // By default, fragment.xml does not exist until the first extension
349: // or extension point is created.
350: // Ensure the file exists before pasting because the model will be
351: // null and the paste will fail if it does not exist
352: ((ManifestEditor) getPage().getEditor())
353: .ensurePluginContextPresence();
354: // Get the model
355: IPluginModelBase model = getPluginModelBase();
356: // Ensure an editable model was actually retrieved
357: if (model == null) {
358: return;
359: }
360: IPluginBase pluginBase = model.getPluginBase();
361: try {
362: // Paste all source objects
363: // Since, the extension points are a flat non-hierarchical list,
364: // the target object is not needed
365: for (int i = 0; i < sourceObjects.length; i++) {
366: Object sourceObject = sourceObjects[i];
367:
368: if ((sourceObject instanceof IPluginExtensionPoint)
369: && (pluginBase instanceof IDocumentElementNode)) {
370: // Extension point object
371: IDocumentElementNode extensionPoint = (IDocumentElementNode) sourceObject;
372: // Adjust all the source object transient field values to
373: // acceptable values
374: extensionPoint.reconnect(
375: (IDocumentElementNode) pluginBase, model);
376: // Add the extension point to the plug-in
377: pluginBase
378: .add((IPluginExtensionPoint) extensionPoint);
379: }
380: }
381: } catch (CoreException e) {
382: PDEPlugin.logException(e);
383: }
384: }
385:
386: /* (non-Javadoc)
387: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(java.lang.Object, java.lang.Object[])
388: */
389: protected boolean canPaste(Object targetObject,
390: Object[] sourceObjects) {
391: // All source objects must be extension points
392: // No restriction on duplicates
393: for (int i = 0; i < sourceObjects.length; i++) {
394: if ((sourceObjects[i] instanceof IPluginExtensionPoint) == false) {
395: return false;
396: }
397: }
398: return true;
399: }
400:
401: protected void selectExtensionPoint(ISelection selection) {
402: pointTable.setSelection(selection, true);
403: }
404: }
|