blob: 1bcde0320bb1aa2e583218912ce0cbfcf6694931 [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2009, 2012 SpringSource, a division of VMware, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
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();
this.fViewer = tablePart.getTableViewer();
this.fViewer.setContentProvider(getContentProvider());
this.fViewer.setLabelProvider(getLabelProvider());
this.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();
this.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) this.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() {
this.fViewer.refresh();
super.refresh();
}
protected void makeActions() {
this.fAddAction = new Action(PDEUIMessages.RequiresSection_add) {
@Override
public void run() {
handleAdd();
}
};
this.fAddAction.setEnabled(isEditable());
this.fRemoveAction = new Action(PDEUIMessages.RequiresSection_delete) {
@Override
public void run() {
handleRemove();
}
};
this.fRemoveAction.setEnabled(isEditable());
this.fPropertiesAction = new Action(PDEUIMessages.ImportPackageSection_propertyAction) {
@Override
public void run() {
handleOpenProperties();
}
};
}
@Override
protected void fillContextMenu(IMenuManager manager) {
final ISelection selection = this.fViewer.getSelection();
manager.add(this.fAddAction);
manager.add(new Separator());
if (!selection.isEmpty()) {
manager.add(this.fRemoveAction);
}
getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager);
if (shouldEnableProperties(((IStructuredSelection) this.fViewer.getSelection()).toArray())) {
manager.add(new Separator());
manager.add(this.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:
this.fViewer.add(element);
this.fViewer.setSelection(new StructuredSelection(element));
this.fViewer.getTable().setFocus();
break;
case IModelChangedEvent.REMOVE:
Table table = this.fViewer.getTable();
int index = table.getSelectionIndex();
this.fViewer.remove(element);
table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1);
break;
default:
this.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[this.fElements.length];
if (this.fElements != null) {
System.arraycopy(this.fElements, 0, allElements, 0, this.fElements.length);
}
return comp;
}
@Override
public void setElements(Object[] elements) {
super.setElements(elements);
this.fElements = elements;
}
}
}