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.feature;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014:
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.jface.action.Action;
017: import org.eclipse.jface.action.IMenuManager;
018: import org.eclipse.jface.action.Separator;
019: import org.eclipse.jface.action.ToolBarManager;
020: import org.eclipse.jface.viewers.ISelection;
021: import org.eclipse.jface.viewers.IStructuredContentProvider;
022: import org.eclipse.jface.viewers.IStructuredSelection;
023: import org.eclipse.jface.viewers.StructuredSelection;
024: import org.eclipse.jface.viewers.TableViewer;
025: import org.eclipse.jface.window.Window;
026: import org.eclipse.pde.core.IModel;
027: import org.eclipse.pde.core.IModelChangedEvent;
028: import org.eclipse.pde.core.plugin.IPluginBase;
029: import org.eclipse.pde.core.plugin.IPluginModelBase;
030: import org.eclipse.pde.core.plugin.ModelEntry;
031: import org.eclipse.pde.core.plugin.PluginRegistry;
032: import org.eclipse.pde.internal.core.IPluginModelListener;
033: import org.eclipse.pde.internal.core.PDECore;
034: import org.eclipse.pde.internal.core.PluginModelDelta;
035: import org.eclipse.pde.internal.core.feature.FeaturePlugin;
036: import org.eclipse.pde.internal.core.ifeature.IFeature;
037: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
038: import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
039: import org.eclipse.pde.internal.core.util.CoreUtility;
040: import org.eclipse.pde.internal.ui.PDEPlugin;
041: import org.eclipse.pde.internal.ui.PDEUIMessages;
042: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
043: import org.eclipse.pde.internal.ui.editor.ModelDataTransfer;
044: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
045: import org.eclipse.pde.internal.ui.editor.TableSection;
046: import org.eclipse.pde.internal.ui.editor.actions.SortAction;
047: import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
048: import org.eclipse.pde.internal.ui.parts.TablePart;
049: import org.eclipse.pde.internal.ui.wizards.ListUtil;
050: import org.eclipse.pde.internal.ui.wizards.PluginSelectionDialog;
051: import org.eclipse.swt.SWT;
052: import org.eclipse.swt.custom.BusyIndicator;
053: import org.eclipse.swt.dnd.Clipboard;
054: import org.eclipse.swt.events.DisposeEvent;
055: import org.eclipse.swt.events.DisposeListener;
056: import org.eclipse.swt.graphics.Cursor;
057: import org.eclipse.swt.layout.GridData;
058: import org.eclipse.swt.widgets.Composite;
059: import org.eclipse.swt.widgets.Display;
060: import org.eclipse.swt.widgets.ToolBar;
061: import org.eclipse.ui.actions.ActionFactory;
062: import org.eclipse.ui.forms.widgets.FormToolkit;
063: import org.eclipse.ui.forms.widgets.Section;
064:
065: public class PluginSection extends TableSection implements
066: IPluginModelListener {
067: private OpenReferenceAction fOpenAction;
068:
069: private TableViewer fPluginViewer;
070:
071: private Action fNewAction;
072:
073: private Action fDeleteAction;
074:
075: private SortAction fSortAction;
076:
077: class PluginContentProvider extends DefaultContentProvider
078: implements IStructuredContentProvider {
079: public Object[] getElements(Object parent) {
080: if (parent instanceof IFeature) {
081: return ((IFeature) parent).getPlugins();
082: }
083: return new Object[0];
084: }
085: }
086:
087: public PluginSection(PDEFormPage page, Composite parent) {
088: super (page, parent, Section.DESCRIPTION, new String[] {
089: PDEUIMessages.FeatureEditor_PluginSection_new, null,
090: PDEUIMessages.FeatureEditor_SpecSection_synchronize });
091: getSection().setText(
092: PDEUIMessages.FeatureEditor_PluginSection_pluginTitle);
093: getSection().setDescription(
094: PDEUIMessages.FeatureEditor_PluginSection_pluginDesc);
095: getTablePart().setEditable(false);
096: }
097:
098: public void commit(boolean onSave) {
099: super .commit(onSave);
100: }
101:
102: public void createClient(Section section, FormToolkit toolkit) {
103:
104: section.setLayout(FormLayoutFactory.createClearGridLayout(
105: false, 1));
106: GridData data = new GridData(GridData.FILL_BOTH);
107: section.setLayoutData(data);
108:
109: Composite container = createClientContainer(section, 2, toolkit);
110:
111: createViewerPartControl(container, SWT.MULTI, 2, toolkit);
112: TablePart tablePart = getTablePart();
113: fPluginViewer = tablePart.getTableViewer();
114: fPluginViewer.setContentProvider(new PluginContentProvider());
115: fPluginViewer.setLabelProvider(PDEPlugin.getDefault()
116: .getLabelProvider());
117: fPluginViewer.setComparator(ListUtil.NAME_COMPARATOR);
118: toolkit.paintBordersFor(container);
119: makeActions();
120: section.setClient(container);
121: initialize();
122: createSectionToolbar(section, toolkit);
123: }
124:
125: /**
126: * @param section
127: * @param toolkit
128: */
129: private void createSectionToolbar(Section section,
130: FormToolkit toolkit) {
131:
132: ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
133: ToolBar toolbar = toolBarManager.createControl(section);
134: final Cursor handCursor = new Cursor(Display.getCurrent(),
135: SWT.CURSOR_HAND);
136: toolbar.setCursor(handCursor);
137: // Cursor needs to be explicitly disposed
138: toolbar.addDisposeListener(new DisposeListener() {
139: public void widgetDisposed(DisposeEvent e) {
140: if ((handCursor != null)
141: && (handCursor.isDisposed() == false)) {
142: handCursor.dispose();
143: }
144: }
145: });
146: // Add sort action to the tool bar
147: fSortAction = new SortAction(getStructuredViewerPart()
148: .getViewer(),
149: PDEUIMessages.FeatureEditor_PluginSection_sortAlpha,
150: ListUtil.NAME_COMPARATOR, null, null);
151:
152: toolBarManager.add(fSortAction);
153:
154: toolBarManager.update(true);
155:
156: section.setTextClient(toolbar);
157: }
158:
159: protected void handleDoubleClick(IStructuredSelection selection) {
160: fOpenAction.run();
161: }
162:
163: protected void buttonSelected(int index) {
164: if (index == 0)
165: handleNew();
166: if (index == 2)
167: handleSynchronize();
168: }
169:
170: public void dispose() {
171: IFeatureModel model = (IFeatureModel) getPage().getModel();
172: if (model != null)
173: PDECore.getDefault().getModelManager()
174: .removePluginModelListener(this );
175: super .dispose();
176: }
177:
178: public boolean setFormInput(Object object) {
179: if (object instanceof IFeaturePlugin) {
180: fPluginViewer.setSelection(new StructuredSelection(object),
181: true);
182: return true;
183: }
184: return false;
185: }
186:
187: protected void fillContextMenu(IMenuManager manager) {
188: manager.add(fOpenAction);
189: // add new
190: manager.add(new Separator());
191: manager.add(fNewAction);
192: manager.add(fDeleteAction);
193: // add delete
194:
195: getPage().getPDEEditor().getContributor()
196: .contextMenuAboutToShow(manager);
197: }
198:
199: private void handleNew() {
200: BusyIndicator.showWhile(fPluginViewer.getTable().getDisplay(),
201: new Runnable() {
202: public void run() {
203: IPluginModelBase[] allModels = PluginRegistry
204: .getActiveModels();
205: ArrayList newModels = new ArrayList();
206: for (int i = 0; i < allModels.length; i++) {
207: if (canAdd(allModels[i]))
208: newModels.add(allModels[i]);
209: }
210: IPluginModelBase[] candidateModels = (IPluginModelBase[]) newModels
211: .toArray(new IPluginModelBase[newModels
212: .size()]);
213: PluginSelectionDialog dialog = new PluginSelectionDialog(
214: fPluginViewer.getTable().getShell(),
215: candidateModels, true);
216: if (dialog.open() == Window.OK) {
217: Object[] models = dialog.getResult();
218: try {
219: doAdd(models);
220: } catch (CoreException e) {
221: PDEPlugin.log(e);
222: }
223: }
224: }
225: });
226: }
227:
228: private void doAdd(Object[] candidates) throws CoreException {
229: IFeatureModel model = (IFeatureModel) getPage().getModel();
230: IFeature feature = model.getFeature();
231: IFeaturePlugin[] added = new IFeaturePlugin[candidates.length];
232: for (int i = 0; i < candidates.length; i++) {
233: IPluginModelBase candidate = (IPluginModelBase) candidates[i];
234: FeaturePlugin fplugin = (FeaturePlugin) model.getFactory()
235: .createPlugin();
236: fplugin.loadFrom(candidate.getPluginBase());
237: fplugin.setVersion("0.0.0"); //$NON-NLS-1$
238: fplugin.setUnpack(CoreUtility.guessUnpack(candidate
239: .getBundleDescription()));
240: added[i] = fplugin;
241: }
242: feature.addPlugins(added);
243: }
244:
245: private boolean canAdd(IPluginModelBase candidate) {
246: IPluginBase plugin = candidate.getPluginBase();
247:
248: IFeatureModel model = (IFeatureModel) getPage().getModel();
249: IFeaturePlugin[] fplugins = model.getFeature().getPlugins();
250:
251: for (int i = 0; i < fplugins.length; i++) {
252: if (fplugins[i].getId().equals(plugin.getId()))
253: return false;
254: }
255: return true;
256: }
257:
258: private void handleSelectAll() {
259: IStructuredContentProvider provider = (IStructuredContentProvider) fPluginViewer
260: .getContentProvider();
261: Object[] elements = provider.getElements(fPluginViewer
262: .getInput());
263: StructuredSelection ssel = new StructuredSelection(elements);
264: fPluginViewer.setSelection(ssel);
265: }
266:
267: private void handleDelete() {
268: IStructuredSelection ssel = (IStructuredSelection) fPluginViewer
269: .getSelection();
270:
271: if (ssel.isEmpty())
272: return;
273: IFeatureModel model = (IFeatureModel) getPage().getModel();
274: if (!model.isEditable()) {
275: return;
276: }
277: IFeature feature = model.getFeature();
278:
279: try {
280: IFeaturePlugin[] removed = new IFeaturePlugin[ssel.size()];
281: int i = 0;
282: for (Iterator iter = ssel.iterator(); iter.hasNext();) {
283: IFeaturePlugin iobj = (IFeaturePlugin) iter.next();
284: removed[i++] = iobj;
285: }
286: feature.removePlugins(removed);
287: } catch (CoreException e) {
288: PDEPlugin.logException(e);
289: }
290: }
291:
292: private void handleSynchronize() {
293: final FeatureEditorContributor contributor = (FeatureEditorContributor) getPage()
294: .getPDEEditor().getContributor();
295: BusyIndicator.showWhile(
296: fPluginViewer.getControl().getDisplay(),
297: new Runnable() {
298: public void run() {
299: contributor.getSynchronizeAction().run();
300: }
301: });
302: }
303:
304: public boolean doGlobalAction(String actionId) {
305: if (actionId.equals(ActionFactory.DELETE.getId())) {
306: BusyIndicator.showWhile(fPluginViewer.getTable()
307: .getDisplay(), new Runnable() {
308: public void run() {
309: handleDelete();
310: }
311: });
312: return true;
313: }
314: if (actionId.equals(ActionFactory.CUT.getId())) {
315: // delete here and let the editor transfer
316: // the selection to the clipboard
317: handleDelete();
318: return false;
319: }
320: if (actionId.equals(ActionFactory.PASTE.getId())) {
321: doPaste();
322: return true;
323: }
324: if (actionId.equals(ActionFactory.SELECT_ALL.getId())) {
325: BusyIndicator.showWhile(fPluginViewer.getTable()
326: .getDisplay(), new Runnable() {
327: public void run() {
328: handleSelectAll();
329: }
330: });
331: return true;
332: }
333: return false;
334: }
335:
336: protected void selectionChanged(IStructuredSelection selection) {
337: getPage().getPDEEditor().setSelection(selection);
338: }
339:
340: public void initialize() {
341: IFeatureModel model = (IFeatureModel) getPage().getModel();
342: refresh();
343: getTablePart().setButtonEnabled(0, model.isEditable());
344: getTablePart().setButtonEnabled(2, model.isEditable());
345: model.addModelChangedListener(this );
346: PDECore.getDefault().getModelManager().addPluginModelListener(
347: this );
348: }
349:
350: public void modelChanged(IModelChangedEvent e) {
351: if (e.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
352: markStale();
353: return;
354: }
355: Object obj = e.getChangedObjects()[0];
356: if (obj instanceof IFeaturePlugin) {
357: if (e.getChangeType() == IModelChangedEvent.CHANGE) {
358: fPluginViewer.update(obj, null);
359: } else if (e.getChangeType() == IModelChangedEvent.INSERT) {
360: fPluginViewer.add(e.getChangedObjects());
361: if (e.getChangedObjects().length > 0) {
362: fPluginViewer.setSelection(new StructuredSelection(
363: e.getChangedObjects()[0]));
364: }
365: } else if (e.getChangeType() == IModelChangedEvent.REMOVE) {
366: fPluginViewer.remove(e.getChangedObjects());
367: }
368: }
369: }
370:
371: private void makeActions() {
372: IModel model = (IModel) getPage().getModel();
373: fNewAction = new Action() {
374: public void run() {
375: handleNew();
376: }
377: };
378: fNewAction.setText(PDEUIMessages.Menus_new_label);
379: fNewAction.setEnabled(model.isEditable());
380:
381: fDeleteAction = new Action() {
382: public void run() {
383: BusyIndicator.showWhile(fPluginViewer.getTable()
384: .getDisplay(), new Runnable() {
385: public void run() {
386: handleDelete();
387: }
388: });
389: }
390: };
391: fDeleteAction.setText(PDEUIMessages.Actions_delete_label);
392: fDeleteAction.setEnabled(model.isEditable());
393: fOpenAction = new OpenReferenceAction(fPluginViewer);
394: }
395:
396: public void modelsChanged(final PluginModelDelta delta) {
397: getSection().getDisplay().asyncExec(new Runnable() {
398: public void run() {
399: if (getSection().isDisposed()) {
400: return;
401: }
402: ModelEntry[] added = delta.getAddedEntries();
403: ModelEntry[] removed = delta.getRemovedEntries();
404: ModelEntry[] changed = delta.getChangedEntries();
405: if (hasPluginModels(added) || hasPluginModels(removed)
406: || hasPluginModels(changed))
407: markStale();
408: }
409: });
410: }
411:
412: private boolean hasPluginModels(ModelEntry[] entries) {
413: if (entries == null)
414: return false;
415: return true;
416: }
417:
418: public void setFocus() {
419: if (fPluginViewer != null)
420: fPluginViewer.getTable().setFocus();
421: }
422:
423: public void refresh() {
424: IFeatureModel model = (IFeatureModel) getPage().getModel();
425: IFeature feature = model.getFeature();
426: fPluginViewer.setInput(feature);
427: super .refresh();
428: }
429:
430: /**
431: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(Clipboard)
432: */
433: public boolean canPaste(Clipboard clipboard) {
434: Object[] objects = (Object[]) clipboard
435: .getContents(ModelDataTransfer.getInstance());
436: if (objects != null && objects.length > 0) {
437: return canPaste(null, objects);
438: }
439: return false;
440: }
441:
442: /**
443: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#canPaste(Object,
444: * Object[])
445: */
446: protected boolean canPaste(Object target, Object[] objects) {
447: for (int i = 0; i < objects.length; i++) {
448: if (!(objects[i] instanceof FeaturePlugin))
449: return false;
450: }
451: return true;
452: }
453:
454: /**
455: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste()
456: */
457: protected void doPaste() {
458: Clipboard clipboard = getPage().getPDEEditor().getClipboard();
459: Object[] objects = (Object[]) clipboard
460: .getContents(ModelDataTransfer.getInstance());
461: if (objects != null && canPaste(null, objects))
462: doPaste(null, objects);
463: }
464:
465: /**
466: * @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#doPaste(Object,
467: * Object[])
468: */
469: protected void doPaste(Object target, Object[] objects) {
470: IFeatureModel model = (IFeatureModel) getPage().getModel();
471: if (!model.isEditable()) {
472: return;
473: }
474: IFeature feature = model.getFeature();
475: FeaturePlugin[] fPlugins = new FeaturePlugin[objects.length];
476: try {
477: for (int i = 0; i < objects.length; i++) {
478: FeaturePlugin fPlugin = (FeaturePlugin) objects[i];
479: fPlugin.setModel(model);
480: fPlugin.setParent(feature);
481: fPlugins[i] = fPlugin;
482: }
483: feature.addPlugins(fPlugins);
484: } catch (CoreException e) {
485: PDEPlugin.logException(e);
486: }
487: }
488:
489: void fireSelection() {
490: ISelection sel = fPluginViewer.getSelection();
491: if (!sel.isEmpty()) {
492: fPluginViewer.setSelection(fPluginViewer.getSelection());
493: } else if (fPluginViewer.getElementAt(0) != null) {
494: fPluginViewer.setSelection(new StructuredSelection(
495: fPluginViewer.getElementAt(0)));
496: }
497: }
498:
499: protected boolean createCount() {
500: return true;
501: }
502:
503: }
|