blob: 705b544a35801dcda28165cfe027355b8af520c6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 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
*******************************************************************************/
package org.eclipse.pde.internal.ui.editor.schema;
import org.eclipse.jface.text.*;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.pde.core.IModelChangedEvent;
import org.eclipse.pde.internal.core.ischema.ISchemaCompositor;
import org.eclipse.pde.internal.core.ischema.ISchemaObject;
import org.eclipse.pde.internal.core.schema.SchemaObject;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.editor.*;
import org.eclipse.pde.internal.ui.parts.ComboPart;
import org.eclipse.pde.internal.ui.parts.PDESourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.widgets.*;
public abstract class AbstractSchemaDetails extends PDEDetails {
protected static final String[] BOOLS = new String[] {Boolean.toString(true), Boolean.toString(false)};
protected int minLabelWeight;
private Section fSection;
private SchemaDtdDetailsSection fDtdSection = null;
private ElementSection fElementSection;
private boolean fShowDTD;
private boolean fShowDescription;
private Spinner fMinOccurSpinner;
private Spinner fMaxOccurSpinner;
private Button fUnboundSelect;
private Label fMinLabel;
private Label fMaxLabel;
private PDESourceViewer fDescriptionViewer = null;
private boolean fBlockListeners = false;
private ISchemaObject fSchemaObject;
public AbstractSchemaDetails(ElementSection section, boolean showDTD, boolean showDescription) {
fElementSection = section;
fShowDTD = showDTD;
fShowDescription = showDescription;
}
public void modelChanged(IModelChangedEvent event) {
if ((event.getChangeType() == IModelChangedEvent.REMOVE) || (fShowDTD == false) || (fDtdSection == null)) {
return;
}
Object[] objects = event.getChangedObjects();
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof ISchemaCompositor)
fDtdSection.updateDTDLabel(objects[i]);
}
}
public final void createContents(Composite parent) {
// This is a hacked fix to ensure that the label columns on every details
// page have the same width. SchemaDetails_translatable plus 11 pixels
// represents the longest label on any field on any details page. This
// occurs on SchemaStringAttributeDetails and 11 is the size of the
// horizontal indent that contributes to the label's width.
GC gc = new GC(parent);
minLabelWeight = gc.textExtent(PDEUIMessages.SchemaDetails_translatable).x + 11;
gc.dispose();
gc = null;
parent.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
FormToolkit toolkit = getManagedForm().getToolkit();
fSection = toolkit.createSection(parent, Section.DESCRIPTION | ExpandableComposite.TITLE_BAR);
fSection.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
fSection.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
GridData gd;
if (fShowDescription)
gd = new GridData(GridData.FILL_BOTH);
else
gd = new GridData(GridData.FILL_HORIZONTAL);
fSection.setLayoutData(gd);
// Align the master and details section headers (misalignment caused
// by section toolbar icons)
getPage().alignSectionHeaders(fElementSection.getSection(), fSection);
Composite client = toolkit.createComposite(fSection);
client.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, 3));
createDetails(client);
if (fShowDescription)
createDescription(client, toolkit);
// If the DTD Approximation section was requested, instantiate it and create it's contents
// on the same parent Composite
if (fShowDTD) {
fDtdSection = new SchemaDtdDetailsSection();
fDtdSection.initialize(getManagedForm());
fDtdSection.createContents(parent);
}
toolkit.paintBordersFor(client);
fSection.setClient(client);
markDetailsPart(fSection);
if (fShowDescription)
fDescriptionViewer.createUIListeners();
hookListeners();
}
private void createDescription(Composite container, FormToolkit toolkit) {
Label label = toolkit.createLabel(container, PDEUIMessages.AbstractSchemaDetails_descriptionLabel);
GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
gd.horizontalSpan = 3;
label.setLayoutData(gd);
label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
fDescriptionViewer = new PDESourceViewer(getPage());
gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 75;
gd.widthHint = 60;
gd.horizontalSpan = 3;
gd.horizontalIndent = 1;
/*
* Needed to align vertically with form entry field and allow space
* for a possible field decoration
* commented out for now since fields are already grossly misaligned (see bug 196879)
* commenting out temporarily makes the alignment better on Element details and Attribute details
* but worse on RootElement details
*/
//gd.horizontalIndent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT;
fDescriptionViewer.createUI(container, gd);
fDescriptionViewer.getDocument().addDocumentListener(new IDocumentListener() {
public void documentChanged(DocumentEvent event) {
if (blockListeners())
return;
if (fSchemaObject != null) {
// Get the text from the event
IDocument document = event.getDocument();
if (document == null) {
return;
}
// Get the text from the event
String text = document.get().trim();
updateObjectDescription(text);
}
}
public void documentAboutToBeChanged(DocumentEvent event) {
}
});
}
public abstract void createDetails(Composite parent);
public abstract void updateFields(ISchemaObject obj);
public abstract void hookListeners();
public boolean isEditableElement() {
return fElementSection.isEditable();
}
protected void setDecription(String desc) {
fSection.setDescription(desc);
}
protected void setText(String title) {
fSection.setText(title);
}
public String getContextId() {
return SchemaInputContext.CONTEXT_ID;
}
public PDEFormPage getPage() {
return (PDEFormPage) getManagedForm().getContainer();
}
public boolean isEditable() {
return getPage().getPDEEditor().getAggregateModel().isEditable();
}
public void fireSaveNeeded() {
markDirty();
getPage().getPDEEditor().fireSaveNeeded(getContextId(), false);
}
public boolean canPaste(Clipboard clipboard) {
if (fShowDescription && fDescriptionViewer != null && fDescriptionViewer.getViewer().getTextWidget().isFocusControl())
return fDescriptionViewer.canPaste();
return super.canPaste(clipboard);
}
public boolean doGlobalAction(String actionId) {
if (fShowDescription && fDescriptionViewer != null && fDescriptionViewer.getViewer().getTextWidget().isFocusControl())
return fDescriptionViewer.doGlobalAction(actionId);
return super.doGlobalAction(actionId);
}
public void selectionChanged(IFormPart part, ISelection selection) {
if (!(part instanceof ElementSection))
return;
Object obj = ((IStructuredSelection) selection).getFirstElement();
if (obj instanceof ISchemaObject) {
setBlockListeners(true);
ISchemaObject sObj = (ISchemaObject) obj;
fSchemaObject = sObj;
if (fShowDTD && fDtdSection != null)
fDtdSection.updateDTDLabel(obj);
if (fShowDescription && fDescriptionViewer != null)
updateDescriptionViewer(sObj);
updateFields(sObj);
setBlockListeners(false);
}
}
public void updateDescriptionViewer(ISchemaObject obj) {
if (obj != null) {
String text = obj.getDescription();
fDescriptionViewer.getDocument().set(text == null ? "" : text); //$NON-NLS-1$
fDescriptionViewer.getViewer().setEditable(obj.getSchema().isEditable());
}
}
private void updateObjectDescription(String text) {
if (fSchemaObject instanceof SchemaObject) {
((SchemaObject) fSchemaObject).setDescription(text);
}
}
protected void fireSelectionChange() {
fElementSection.fireSelection(fElementSection.getTreeViewer().getSelection());
}
protected void fireMasterSelection(ISelection selection) {
fElementSection.fireSelection(selection);
}
protected ComboPart createComboPart(Composite parent, FormToolkit toolkit, String[] items, int colspan, int style) {
ComboPart cp = new ComboPart();
cp.createControl(parent, toolkit, SWT.READ_ONLY);
GridData gd = new GridData(style);
gd.horizontalSpan = colspan;
gd.horizontalIndent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT;
cp.getControl().setLayoutData(gd);
cp.setItems(items);
cp.getControl().setEnabled(isEditable());
return cp;
}
protected ComboPart createComboPart(Composite parent, FormToolkit toolkit, String[] items, int colspan) {
return createComboPart(parent, toolkit, items, colspan, GridData.FILL_HORIZONTAL);
}
protected Button[] createTrueFalseButtons(Composite parent, FormToolkit toolkit, int colSpan) {
Composite comp = toolkit.createComposite(parent, SWT.NONE);
GridLayout gl = new GridLayout(2, false);
gl.marginHeight = gl.marginWidth = 0;
comp.setLayout(gl);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = colSpan;
gd.horizontalIndent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT;
comp.setLayoutData(gd);
Button tButton = toolkit.createButton(comp, BOOLS[0], SWT.RADIO);
Button fButton = toolkit.createButton(comp, BOOLS[1], SWT.RADIO);
gd = new GridData();
gd.horizontalIndent = 20;
fButton.setLayoutData(gd);
return new Button[] {tButton, fButton};
}
protected Composite createMinOccurComp(Composite parent, FormToolkit toolkit) {
fMinLabel = toolkit.createLabel(parent, PDEUIMessages.AbstractSchemaDetails_minOccurLabel);
fMinLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
Composite comp = toolkit.createComposite(parent);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
GridLayout layout = new GridLayout();
layout.marginHeight = layout.marginWidth = 0;
comp.setLayout(layout);
comp.setLayoutData(gd);
fMinOccurSpinner = new Spinner(comp, SWT.BORDER);
fMinOccurSpinner.setMinimum(0);
fMinOccurSpinner.setMaximum(999);
return comp;
}
protected Composite createMaxOccurComp(Composite parent, FormToolkit toolkit) {
fMaxLabel = toolkit.createLabel(parent, PDEUIMessages.AbstractSchemaDetails_maxOccurLabel);
fMaxLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
Composite comp = toolkit.createComposite(parent);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
GridLayout layout = new GridLayout(3, false);
layout.marginHeight = layout.marginWidth = 0;
comp.setLayout(layout);
comp.setLayoutData(gd);
fMaxOccurSpinner = new Spinner(comp, SWT.BORDER);
fMaxOccurSpinner.setMinimum(1);
fMaxOccurSpinner.setMaximum(999);
fMaxOccurSpinner.setIncrement(1);
fUnboundSelect = toolkit.createButton(comp, PDEUIMessages.AbstractSchemaDetails_unboundedButton, SWT.CHECK);
gd = new GridData();
gd.horizontalIndent = 10;
fUnboundSelect.setLayoutData(gd);
fUnboundSelect.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (blockListeners())
return;
fMaxOccurSpinner.setEnabled(!fUnboundSelect.getSelection() && isEditableElement());
}
});
return comp;
}
protected int getMinOccur() {
if (fMinOccurSpinner != null)
return fMinOccurSpinner.getSelection();
return 0;
}
protected int getMaxOccur() {
if (fMaxOccurSpinner != null) {
if (fMaxOccurSpinner.isEnabled())
return fMaxOccurSpinner.getSelection();
return Integer.MAX_VALUE;
}
return 1;
}
protected void updateMinOccur(int min) {
if (fMinOccurSpinner != null)
fMinOccurSpinner.setSelection(min);
}
protected void updateMaxOccur(int max) {
if (fMaxOccurSpinner == null)
return;
boolean isMax = max == Integer.MAX_VALUE;
fUnboundSelect.setSelection(isMax);
fMaxOccurSpinner.setEnabled(!isMax);
if (!isMax)
fMaxOccurSpinner.setSelection(max);
}
protected void hookMinOccur(SelectionAdapter adapter) {
fMinOccurSpinner.addSelectionListener(adapter);
fMinOccurSpinner.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
if (blockListeners())
return;
int minOccur = fMinOccurSpinner.getSelection();
if (minOccur > getMaxOccur())
fMinOccurSpinner.setSelection(minOccur - 1);
}
});
}
protected void hookMaxOccur(SelectionAdapter adapter) {
fUnboundSelect.addSelectionListener(adapter);
fMaxOccurSpinner.addSelectionListener(adapter);
fMaxOccurSpinner.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
if (blockListeners())
return;
int maxValue = fMaxOccurSpinner.getSelection();
if (maxValue < getMinOccur())
fMaxOccurSpinner.setSelection(maxValue + 1);
}
});
}
protected void enableMinMax(boolean enable) {
fMinOccurSpinner.setEnabled(enable);
fMaxOccurSpinner.setEnabled(!fUnboundSelect.getSelection() && enable);
fUnboundSelect.setEnabled(enable);
fMinLabel.setEnabled(enable);
fMaxLabel.setEnabled(enable);
}
protected boolean blockListeners() {
return fBlockListeners;
}
protected void setBlockListeners(boolean blockListeners) {
fBlockListeners = blockListeners;
}
public void dispose() {
// Set the context menu to null to prevent the editor context menu
// from being disposed along with the source viewer
if (fDescriptionViewer != null) {
fDescriptionViewer.unsetMenu();
fDescriptionViewer = null;
}
super.dispose();
}
}