blob: 0771c6c27a2e09a6b731177e7fd6a90e6543bac3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2015 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
* Remy Chi Jian Suen <remy.suen@gmail.com> - Provide more structure, safety, and convenience for ID-based references between extension points (id hell)
* Brian de Alwis (MTI) - bug 429420
*******************************************************************************/
package org.eclipse.pde.internal.ui.editor.plugin;
import java.util.ArrayList;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IModelChangedEvent;
import org.eclipse.pde.core.plugin.*;
import org.eclipse.pde.internal.core.ischema.*;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.editor.*;
import org.eclipse.pde.internal.ui.editor.plugin.rows.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.widgets.*;
public class ExtensionElementDetails extends AbstractPluginElementDetails {
private IPluginElement input;
private ISchemaElement schemaElement;
private ArrayList<ExtensionAttributeRow> rows;
private Section section;
/**
* @param masterSection
* @param schemaElement
*/
public ExtensionElementDetails(PDESection masterSection, ISchemaElement schemaElement) {
super(masterSection);
this.schemaElement = schemaElement;
rows = new ArrayList<>();
}
@Override
public String getContextId() {
return PluginInputContext.CONTEXT_ID;
}
@Override
public void fireSaveNeeded() {
markDirty();
getPage().getPDEEditor().fireSaveNeeded(getContextId(), false);
}
@Override
public PDEFormPage getPage() {
return (PDEFormPage) getManagedForm().getContainer();
}
@Override
public boolean isEditable() {
return getPage().getPDEEditor().getAggregateModel().isEditable();
}
@Override
public void createContents(Composite parent) {
parent.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
FormToolkit toolkit = getManagedForm().getToolkit();
section = toolkit.createSection(parent, ExpandableComposite.TITLE_BAR | Section.DESCRIPTION);
section.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
section.setText(PDEUIMessages.ExtensionElementDetails_title);
section.setDescription(""); //$NON-NLS-1$
section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
section.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING));
// Align the master and details section headers (misalignment caused
// by section toolbar icons)
getPage().alignSectionHeaders(getMasterSection().getSection(), section);
Composite client = toolkit.createComposite(section);
int span = 2;
GridLayout glayout = FormLayoutFactory.createSectionClientGridLayout(false, span);
client.setLayout(glayout);
client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if (schemaElement != null) {
ISchemaAttribute atts[] = schemaElement.getAttributes();
if (isEditable()) {
// Compute horizontal span
for (int i = 0; i < atts.length; i++) {
if (atts[i].getKind() == IMetaAttribute.JAVA || atts[i].getKind() == IMetaAttribute.RESOURCE || atts[i].getKind() == IMetaAttribute.IDENTIFIER) {
span = 3;
break;
}
}
}
glayout.numColumns = span;
// Add required attributes first
for (int i = 0; i < atts.length; i++) {
if (atts[i].getUse() == ISchemaAttribute.REQUIRED)
rows.add(createAttributeRow(atts[i], client, toolkit, span));
}
// Add the non-required attributes
for (int i = 0; i < atts.length; i++) {
if (atts[i].getUse() != ISchemaAttribute.REQUIRED)
rows.add(createAttributeRow(atts[i], client, toolkit, span));
}
createSpacer(toolkit, client, span);
} else {
// no schema - delay until input is set
}
toolkit.paintBordersFor(client);
section.setClient(client);
// Dynamically add focus listeners to all the section client's
// children in order to track the last focus control
getPage().addLastFocusListeners(client);
IPluginModelBase model = (IPluginModelBase) getPage().getModel();
model.addModelChangedListener(this);
markDetailsPart(section);
}
private ExtensionAttributeRow createAttributeRow(ISchemaAttribute att, Composite parent, FormToolkit toolkit, int span) {
ExtensionAttributeRow row;
if (att.getKind() == IMetaAttribute.JAVA)
row = new ClassAttributeRow(this, att);
else if (att.getKind() == IMetaAttribute.RESOURCE)
row = new ResourceAttributeRow(this, att);
else if (att.getKind() == IMetaAttribute.IDENTIFIER)
row = new IdAttributeRow(this, att);
else if (att.isTranslatable())
row = new TranslatableAttributeRow(this, att);
else {
ISchemaSimpleType type = att.getType();
if (type.getName().equals("boolean")) //$NON-NLS-1$
row = new BooleanAttributeRow(this, att);
else {
ISchemaRestriction restriction = type.getRestriction();
if (restriction != null)
row = new ChoiceAttributeRow(this, att);
else
row = new TextAttributeRow(this, att);
}
}
row.createContents(parent, toolkit, span);
return row;
}
private ExtensionAttributeRow createAttributeRow(IPluginAttribute att, Composite parent, FormToolkit toolkit, int span) {
ExtensionAttributeRow row;
row = new TextAttributeRow(this, att);
row.createContents(parent, toolkit, span);
return row;
}
@Override
public void selectionChanged(IFormPart masterPart, ISelection selection) {
IStructuredSelection ssel = (IStructuredSelection) selection;
if (ssel.size() == 1) {
input = (IPluginElement) ssel.getFirstElement();
} else
input = null;
update();
}
@Override
public void modelChanged(IModelChangedEvent e) {
if (e.getChangeType() == IModelChangedEvent.CHANGE) {
Object obj = e.getChangedObjects()[0];
if (obj.equals(input)) {
// do smart update (update only the row whose property changed
String property = e.getChangedProperty();
if (property != null) {
for (int i = 0; i < rows.size(); i++) {
ExtensionAttributeRow row = rows.get(i);
ISchemaAttribute attribute = row.getAttribute();
if (attribute == null) {
continue;
}
String name = attribute.getName();
if (name == null) {
continue;
}
if (name.equals(property)) {
row.setInput(input);
}
}
} else
refresh();
}
}
}
private void update() {
updateDescription();
if (schemaElement == null)
updateRows();
for (int i = 0; i < rows.size(); i++) {
ExtensionAttributeRow row = rows.get(i);
row.setInput(input);
}
}
private void updateRows() {
if (input == null)
return;
IPluginAttribute[] atts = input.getAttributes();
FormToolkit toolkit = getManagedForm().getToolkit();
boolean rowsAdded = false;
for (int i = 0; i < atts.length; i++) {
if (!hasAttribute(atts[i].getName())) {
rows.add(createAttributeRow(atts[i], (Composite) section.getClient(), toolkit, 2));
rowsAdded = true;
}
}
if (rowsAdded) {
((Composite) section.getClient()).layout(true);
section.layout(true);
section.getParent().layout(true);
reflow();
}
}
private void reflow() {
Composite parent = section.getParent();
while (parent != null) {
if (parent instanceof SharedScrolledComposite) {
((SharedScrolledComposite) parent).reflow(true);
return;
}
parent = parent.getParent();
}
}
private boolean hasAttribute(String attName) {
for (int i = 0; i < rows.size(); i++) {
ExtensionAttributeRow row = rows.get(i);
if (row.getName().equals(attName))
return true;
}
return false;
}
private void updateDescription() {
if (input != null) {
String iname = input.getName();
String label = null;
if (0 == input.getAttributeCount()) {
label = PDEUIMessages.ExtensionElementDetails_descNoAttributes;
} else if (schemaElement != null && schemaElement.hasDeprecatedAttributes()) {
label = NLS.bind(PDEUIMessages.ExtensionElementDetails_setDescDepr, iname);
} else {
label = NLS.bind(PDEUIMessages.ExtensionElementDetails_setDesc, iname);
}
if (schemaElement != null && schemaElement.isDeprecated()) {
label += "\n\n"; //$NON-NLS-1$
label += NLS.bind(PDEUIMessages.ElementIsDeprecated, iname);
}
section.setDescription(label);
} else {
// no extensions = no description
section.setDescription(""); //$NON-NLS-1$
}
section.layout();
}
@Override
public void commit(boolean onSave) {
for (int i = 0; i < rows.size(); i++) {
ExtensionAttributeRow row = rows.get(i);
row.commit();
}
super.commit(onSave);
}
@Override
public void setFocus() {
if (rows.size() > 0)
rows.get(0).setFocus();
}
@Override
public void dispose() {
for (int i = 0; i < rows.size(); i++) {
ExtensionAttributeRow row = rows.get(i);
row.dispose();
}
IPluginModelBase model = (IPluginModelBase) getPage().getModel();
if (model != null)
model.removeModelChangedListener(this);
super.dispose();
}
@Override
public void refresh() {
update();
super.refresh();
}
}