blob: 80edffe97aeafd9e0f57e43ff7597b5939585dec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2016 IBM Corporation and others.
* 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:
* IBM Corporation - Initial API and implementation
* Martin Karpisek <martin.karpisek@gmail.com> - Bug 438509
*******************************************************************************/
package org.eclipse.pde.internal.ui.editor.product;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IModelChangedEvent;
import org.eclipse.pde.internal.core.iproduct.*;
import org.eclipse.pde.internal.core.iproduct.IProduct;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.editor.PDEFormPage;
import org.eclipse.pde.internal.ui.editor.TableSection;
import org.eclipse.pde.internal.ui.parts.TablePart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/**
* Displays a list of product properties set in the product configuration. The properties
* can be added, edited and removed.
*
* @see IConfigurationProperty
* @see ConfigurationPage
* @see ProductEditor
*
* @since 3.7
*/
public class PropertiesSection extends TableSection {
private class ContentProvider implements IStructuredContentProvider {
ContentProvider() {
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof IProduct) {
return ((IProduct) inputElement).getConfigurationProperties();
}
return new Object[0];
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class LabelProvider extends PDELabelProvider {
@Override
public Image getColumnImage(Object obj, int index) {
if (index == 0)
return get(PDEPluginImages.DESC_PROPERTIES);
return null;
}
@Override
public String getColumnText(Object obj, int index) {
IConfigurationProperty configuration = (IConfigurationProperty) obj;
switch (index) {
case 0 :
return configuration.getName();
//return super.getColumnText(PluginRegistry.findModel(configuration.getId()), index);
case 1 :
return configuration.getValue();
case 2 :
return configuration.getOs();
case 3 :
return configuration.getArch();
}
return null;
}
}
private class PropertyDialog extends StatusDialog {
private Text fName;
private Text fValue;
private Combo fOS;
private Combo fArch;
private IConfigurationProperty fEdit;
private Set<String> fExistingNames;
private String[] COMBO_OSLABELS = new String[] { PDEUIMessages.PropertiesSection_All, Platform.OS_LINUX,
Platform.OS_MACOSX, Platform.OS_WIN32 };
private String[] COMBO_ARCHLABELS = new String[] {PDEUIMessages.PropertiesSection_All, Platform.ARCH_X86, Platform.ARCH_X86_64, Platform.ARCH_PPC, Platform.ARCH_IA64, Platform.ARCH_IA64_32, Platform.ARCH_PA_RISC, Platform.ARCH_SPARC};
public PropertyDialog(Shell shell, IConfigurationProperty property, Set<String> existingNames) {
super(shell);
fEdit = property;
fExistingNames = existingNames;
setTitle(PDEUIMessages.PropertiesSection_PropertyDialogTitle);
}
@Override
protected Control createDialogArea(Composite parent) {
Composite comp = (Composite) super.createDialogArea(parent);
((GridLayout) comp.getLayout()).numColumns = 2;
SWTFactory.createLabel(comp, PDEUIMessages.PropertiesSection_Name, 1);
fName = SWTFactory.createSingleText(comp, 1);
fName.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
validate();
}
});
SWTFactory.createLabel(comp, PDEUIMessages.PropertiesSection_Value, 1);
fValue = SWTFactory.createSingleText(comp, 1);
fValue.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
validate();
}
});
SWTFactory.createLabel(comp, PDEUIMessages.PropertiesSection_OS, 1);
fOS = SWTFactory.createCombo(comp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY, 1, COMBO_OSLABELS);
fOS.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
updateStatus(Status.OK_STATUS);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
updateStatus(Status.OK_STATUS);
}
});
SWTFactory.createLabel(comp, PDEUIMessages.PropertiesSection_Arch, 1);
fArch = SWTFactory.createCombo(comp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY, 1, COMBO_ARCHLABELS);
fArch.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
updateStatus(Status.OK_STATUS);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
updateStatus(Status.OK_STATUS);
}
});
if (fEdit != null) {
if (fEdit.getName() != null) {
fName.setText(fEdit.getName());
}
if (fEdit.getValue() != null) {
fValue.setText(fEdit.getValue());
}
int index = Arrays.asList(COMBO_OSLABELS).indexOf(fEdit.getOs());
if (index >= 0) {
fOS.select(index);
} else {
fOS.select(0); // "All"
}
index = Arrays.asList(COMBO_ARCHLABELS).indexOf(fEdit.getArch());
if (index >= 0) {
fArch.select(index);
} else {
fArch.select(0); // "All"
}
}
// Disable ok button on startup
updateStatus(new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, "")); //$NON-NLS-1$
return comp;
}
protected void validate() {
String name = fName.getText().trim();
if (name.length() == 0) {
updateStatus(new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, PDEUIMessages.PropertiesSection_ErrorPropertyNoName));
} else if (fExistingNames.contains(name)) {
updateStatus(new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, NLS.bind(PDEUIMessages.PropertiesSection_ErrorPropertyExists, name)));
} else {
updateStatus(Status.OK_STATUS);
}
}
@Override
protected void okPressed() {
if (fEdit != null) {
// Product properties are stored in a map that isn't updated on edit, remove the property and add a new one
getProduct().removeConfigurationProperties(new IConfigurationProperty[] {fEdit});
}
IProductModelFactory factory = getModel().getFactory();
fEdit = factory.createConfigurationProperty();
fEdit.setName(fName.getText().trim());
fEdit.setValue(fValue.getText().trim());
int index = fOS.getSelectionIndex();
fEdit.setOs(index == 0 ? "" : COMBO_OSLABELS[index]); //$NON-NLS-1$
index = fArch.getSelectionIndex();
fEdit.setArch(index == 0 ? "" : COMBO_ARCHLABELS[index]); //$NON-NLS-1$
getProduct().addConfigurationProperties(new IConfigurationProperty[] {fEdit});
super.okPressed();
}
@Override
protected Control createHelpControl(Composite parent) {
return parent;
}
/**
* @return a configuration property containing the values set in the dialog or <code>null</code>
*/
public IConfigurationProperty getResult() {
return fEdit;
}
}
class ValueCellModifier implements ICellModifier {
@Override
public boolean canModify(Object element, String property) {
return element instanceof IConfigurationProperty;
}
@Override
public Object getValue(Object element, String property) {
return ((IConfigurationProperty) element).getValue();
}
@Override
public void modify(Object item, String property, Object value) {
Object data = ((TableItem) item).getData();
if (data instanceof IConfigurationProperty) {
String newValue = ((String) value).trim();
((IConfigurationProperty) data).setValue(newValue);
fPropertiesTable.refresh(data);
}
}
}
private TableViewer fPropertiesTable;
public PropertiesSection(PDEFormPage page, Composite parent) {
super(page, parent, Section.DESCRIPTION, getButtonLabels());
}
private static String[] getButtonLabels() {
String[] labels = new String[3];
labels[0] = PDEUIMessages.PropertiesSection_Add;
labels[1] = PDEUIMessages.PropertiesSection_Edit;
labels[2] = PDEUIMessages.PropertiesSection_Remove;
return labels;
}
@Override
protected void buttonSelected(int index) {
switch (index) {
case 0 :
handleAdd();
break;
case 1 :
handleEdit();
break;
case 2 :
handleRemove();
break;
}
}
@Override
protected void createClient(Section section, FormToolkit toolkit) {
section.setText(PDEUIMessages.PropertiesSection_PropertiesSectionTitle);
section.setDescription(PDEUIMessages.PropertiesSection_PropertiesSectionDescription);
GridData sectionData = new GridData(SWT.FILL, SWT.FILL, true, true);
sectionData.horizontalSpan = 2;
section.setLayoutData(sectionData);
Composite container = createClientContainer(section, 3, toolkit);
createViewerPartControl(container, SWT.MULTI | SWT.FULL_SELECTION, 3, toolkit);
fPropertiesTable = getTablePart().getTableViewer();
fPropertiesTable.setSorter(new ViewerSorter());
fPropertiesTable.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
handleEdit();
}
});
fPropertiesTable.getTable().addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.keyCode == SWT.DEL) {
handleRemove();
}
}
});
final Table table = fPropertiesTable.getTable();
final TableColumn nameColumn = new TableColumn(table, SWT.LEFT);
nameColumn.setText(PDEUIMessages.PropertiesSection_NameColumn);
nameColumn.setWidth(160);
final TableColumn valueColumn = new TableColumn(table, SWT.LEFT);
valueColumn.setText(PDEUIMessages.PropertiesSection_ValueColumn);
valueColumn.setWidth(220);
final TableColumn osColumn = new TableColumn(table, SWT.LEFT);
osColumn.setText(PDEUIMessages.PropertiesSection_OSColumn);
osColumn.setWidth(60);
final TableColumn archColumn = new TableColumn(table, SWT.LEFT);
archColumn.setText(PDEUIMessages.PropertiesSection_ArchColumn);
archColumn.setWidth(60);
table.addControlListener(new ControlListener() {
@Override
public void controlMoved(ControlEvent e) {
}
@Override
public void controlResized(ControlEvent e) {
int size = table.getSize().x;
nameColumn.setWidth(size / 9 * 3);
valueColumn.setWidth(size / 9 * 4);
osColumn.setWidth(size / 9 * 1);
archColumn.setWidth(size / 9 * 1);
}
});
TextCellEditor cellEditor = new TextCellEditor(table);
cellEditor.getControl().pack();
fPropertiesTable.setCellEditors(new CellEditor[] {null, cellEditor});
fPropertiesTable.setColumnProperties(new String[] {"0", "1"}); // You must enter column properties to have cell editors //$NON-NLS-1$//$NON-NLS-2$
fPropertiesTable.setCellModifier(new ValueCellModifier());
table.setHeaderVisible(true);
toolkit.paintBordersFor(container);
fPropertiesTable.setLabelProvider(new LabelProvider());
fPropertiesTable.setContentProvider(new ContentProvider());
fPropertiesTable.setInput(getProduct());
section.setClient(container);
getModel().addModelChangedListener(this);
getTablePart().setButtonEnabled(0, isEditable());
updateButtons();
}
private void handleAdd() {
PropertyDialog dialog = new PropertyDialog(PDEPlugin.getActiveWorkbenchShell(), null, getExistingNames());
if (dialog.open() == Window.OK) {
IConfigurationProperty result = dialog.getResult();
if (result != null) {
fPropertiesTable.refresh();
fPropertiesTable.setSelection(new StructuredSelection(result));
updateButtons();
}
}
}
private void handleEdit() {
IStructuredSelection ssel = (IStructuredSelection) fPropertiesTable.getSelection();
if (ssel.size() > 0 && ssel.getFirstElement() instanceof IConfigurationProperty) {
IConfigurationProperty propertyToEdit = (IConfigurationProperty) ssel.getFirstElement();
Set<String> existing = getExistingNames();
existing.remove(propertyToEdit.getName());
PropertyDialog dialog = new PropertyDialog(PDEPlugin.getActiveWorkbenchShell(), propertyToEdit, existing);
if (dialog.open() == Window.OK) {
IConfigurationProperty result = dialog.getResult();
if (result != null) {
fPropertiesTable.refresh();
fPropertiesTable.setSelection(new StructuredSelection(result));
updateButtons();
}
}
}
}
/**
* @return A list of property names currently in use by the product, possibly empty
*/
private Set<String> getExistingNames() {
Set<String> result = new HashSet<>();
IConfigurationProperty[] properties = getProduct().getConfigurationProperties();
for (int i = 0; i < properties.length; i++) {
result.add(properties[i].getName());
}
return result;
}
private void handleRemove() {
IStructuredSelection ssel = (IStructuredSelection) fPropertiesTable.getSelection();
if (ssel.size() > 0) {
Object[] objects = ssel.toArray();
IConfigurationProperty[] properties = new IConfigurationProperty[objects.length];
System.arraycopy(objects, 0, properties, 0, objects.length);
getProduct().removeConfigurationProperties(properties);
fPropertiesTable.refresh(false);
}
}
@Override
protected void selectionChanged(IStructuredSelection selection) {
updateButtons();
}
/**
* @return the product object that is currently being edited
*/
private IProduct getProduct() {
return getModel().getProduct();
}
/**
* @return the product model currently being edited
*/
private IProductModel getModel() {
return (IProductModel) getPage().getPDEEditor().getAggregateModel();
}
@Override
public void modelChanged(IModelChangedEvent e) {
// No need to call super, handling world changed event here
fPropertiesTable.setInput(getProduct());
fPropertiesTable.refresh();
updateButtons();
}
private void updateButtons() {
TablePart tablePart = getTablePart();
ISelection selection = getViewerSelection();
tablePart.setButtonEnabled(0, isEditable());
tablePart.setButtonEnabled(1, isEditable() && !selection.isEmpty());
tablePart.setButtonEnabled(2, isEditable() && !selection.isEmpty());
}
}