/******************************************************************************* * Copyright (c) 2009 SpringSource, a divison of VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SpringSource, a division of VMware, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.virgo.ide.ui.editors; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.pde.core.IBaseModel; import org.eclipse.pde.core.IModelChangeProvider; import org.eclipse.pde.core.IModelChangedEvent; import org.eclipse.pde.core.IModelChangedListener; import org.eclipse.pde.internal.core.ibundle.IBundle; import org.eclipse.pde.internal.core.ibundle.IBundleModel; import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject; import org.eclipse.pde.internal.core.text.bundle.PDEManifestElement; import org.eclipse.pde.internal.ui.PDEUIMessages; import org.eclipse.pde.internal.ui.editor.FormLayoutFactory; import org.eclipse.pde.internal.ui.editor.PDEFormPage; import org.eclipse.pde.internal.ui.editor.TableSection; import org.eclipse.pde.internal.ui.editor.context.InputContextManager; import org.eclipse.pde.internal.ui.editor.plugin.BundleInputContext; import org.eclipse.pde.internal.ui.parts.TablePart; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; /** * Abstract class with common functionality for Eclipse Forms sections that * display and edit a list of artifacts -- Import Package, Import Bundle, and * Import Library. Originally based on <code>PDESection</code>. * @author Christian Dupuis */ public abstract class AbstractImportSection extends TableSection implements IModelChangedListener { protected TableViewer fViewer; private Action fAddAction; private Action fRemoveAction; private Action fPropertiesAction; public AbstractImportSection(PDEFormPage page, Composite parent) { this(page, parent, Section.DESCRIPTION, new String[] { PDEUIMessages.ImportPackageSection_add, PDEUIMessages.ImportPackageSection_remove, PDEUIMessages.ImportPackageSection_properties }); } public AbstractImportSection(PDEFormPage formPage, Composite parent, int style, String[] buttonLabels) { super(formPage, parent, style, true, buttonLabels); } @Override protected void createClient(Section section, FormToolkit toolkit) { section.setText(PDEUIMessages.ImportPackageSection_required); section.setDescription(PDEUIMessages.ImportPackageSection_desc); Composite container = createClientContainer(section, 2, toolkit); createViewerPartControl(container, SWT.MULTI, 2, toolkit); TablePart tablePart = getTablePart(); fViewer = tablePart.getTableViewer(); fViewer.setContentProvider(getContentProvider()); fViewer.setLabelProvider(getLabelProvider()); fViewer.setComparator(new ViewerComparator() { @Override public int compare(Viewer viewer, Object e1, Object e2) { String s1 = e1.toString(); String s2 = e2.toString(); if (s1.indexOf(" ") != -1) { s1 = s1.substring(0, s1.indexOf(" ")); //$NON-NLS-1$ } if (s2.indexOf(" ") != -1) { s2 = s2.substring(0, s2.indexOf(" ")); //$NON-NLS-1$ } return super.compare(viewer, s1, s2); } }); toolkit.paintBordersFor(container); section.setClient(container); section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1)); section.setLayoutData(new GridData(GridData.FILL_BOTH)); makeActions(); IBundleModel model = getBundleModel(); fViewer.setInput(model); model.addModelChangedListener(this); updateButtons(); } protected abstract ITableLabelProvider getLabelProvider(); protected abstract IContentProvider getContentProvider(); @Override public boolean doGlobalAction(String actionId) { if (!isEditable()) { return false; } if (actionId.equals(ActionFactory.DELETE.getId())) { handleRemove(); return true; } if (actionId.equals(ActionFactory.CUT.getId())) { // delete here and let the editor transfer // the selection to the clipboard handleRemove(); return false; } if (actionId.equals(ActionFactory.PASTE.getId())) { doPaste(); return true; } return false; } @Override public void dispose() { IBundleModel model = getBundleModel(); if (model != null) { model.removeModelChangedListener(this); } super.dispose(); } @Override protected void selectionChanged(IStructuredSelection sel) { getPage().getPDEEditor().setSelection(sel); updateButtons(); } protected void updateButtons() { Object[] selected = ((IStructuredSelection) fViewer.getSelection()).toArray(); int size = selected.length; TablePart tablePart = getTablePart(); tablePart.setButtonEnabled(getAddIndex(), isEditable()); tablePart.setButtonEnabled(getRemoveIndex(), isEditable() && size > 0); tablePart.setButtonEnabled(getPropertiesIndex(), shouldEnableProperties(selected)); } @Override protected void buttonSelected(int index) { if (index == getAddIndex()) { handleAdd(); } else if (index == getRemoveIndex()) { handleRemove(); } else if (index == getPropertiesIndex()) { handleOpenProperties(); } } protected abstract int getAddIndex(); protected abstract int getRemoveIndex(); protected abstract int getPropertiesIndex(); protected abstract void handleRemove(); protected abstract void handleAdd(); protected abstract void handleOpenProperties(); @Override public void refresh() { fViewer.refresh(); super.refresh(); } protected void makeActions() { fAddAction = new Action(PDEUIMessages.RequiresSection_add) { @Override public void run() { handleAdd(); } }; fAddAction.setEnabled(isEditable()); fRemoveAction = new Action(PDEUIMessages.RequiresSection_delete) { @Override public void run() { handleRemove(); } }; fRemoveAction.setEnabled(isEditable()); fPropertiesAction = new Action(PDEUIMessages.ImportPackageSection_propertyAction) { @Override public void run() { handleOpenProperties(); } }; } @Override protected void fillContextMenu(IMenuManager manager) { final ISelection selection = fViewer.getSelection(); manager.add(fAddAction); manager.add(new Separator()); if (!selection.isEmpty()) { manager.add(fRemoveAction); } getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager); if (shouldEnableProperties(((IStructuredSelection) fViewer.getSelection()).toArray())) { manager.add(new Separator()); manager.add(fPropertiesAction); } } private BundleInputContext getBundleContext() { InputContextManager manager = getPage().getPDEEditor().getContextManager(); return (BundleInputContext) manager.findContext(BundleInputContext.CONTEXT_ID); } protected IBundleModel getBundleModel() { BundleInputContext context = getBundleContext(); return (context != null) ? (IBundleModel) context.getModel() : null; } protected IBundle getBundle() { IBundleModel model = getBundleModel(); return (model != null) ? model.getBundle() : null; } @Override protected boolean createCount() { return true; } protected boolean shouldEnableProperties(Object[] selected) { if (selected.length == 0) { return false; } if (selected.length == 1) { return true; } String version = ((ImportPackageObject) selected[0]).getVersion(); boolean optional = ((ImportPackageObject) selected[0]).isOptional(); for (int i = 1; i < selected.length; i++) { ImportPackageObject object = (ImportPackageObject) selected[i]; if (version == null) { if (object.getVersion() != null || !(optional == object.isOptional())) { return false; } } else if (!version.equals(object.getVersion()) || !(optional == object.isOptional())) { return false; } } return true; } protected abstract String getHeaderConstant(); @Override public void modelChanged(IModelChangedEvent event) { IBaseModel model = getPage().getModel(); if (model instanceof IModelChangeProvider) { ((IModelChangeProvider) model).fireModelChanged(event); } if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) { markStale(); return; } if (getHeaderConstant().equals(event.getChangedProperty())) { refresh(); return; } Object[] objects = event.getChangedObjects(); for (Object element : objects) { if (element instanceof PDEManifestElement && ((PDEManifestElement) element).getHeader().getName().equals(getHeaderConstant())) { switch (event.getChangeType()) { case IModelChangedEvent.INSERT: fViewer.add(element); fViewer.setSelection(new StructuredSelection(element)); fViewer.getTable().setFocus(); break; case IModelChangedEvent.REMOVE: Table table = fViewer.getTable(); int index = table.getSelectionIndex(); fViewer.remove(element); table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1); break; default: fViewer.refresh(element); } } } } protected abstract class AbstractSectionViewerLabelProvider implements ITableLabelProvider { public abstract Image getColumnImage(Object element, int columnIndex); public abstract String getColumnText(Object element, int columnIndex); public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } protected class ImportListSelectionDialog extends ElementListSelectionDialog { private Object[] fElements; public ImportListSelectionDialog(Shell parent, ILabelProvider renderer) { super(parent, renderer); } @Override protected Control createDialogArea(Composite parent) { Composite comp = (Composite) super.createDialogArea(parent); final Object[] allElements = new Object[fElements.length]; if (fElements != null) { System.arraycopy(fElements, 0, allElements, 0, fElements.length); } return comp; } @Override public void setElements(Object[] elements) { super.setElements(elements); fElements = elements; } } }