| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 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 implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.authoring.ui.editors; |
| |
| import java.io.UnsupportedEncodingException; |
| import java.util.regex.Matcher; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.epf.authoring.ui.forms.BaseFormPage; |
| import org.eclipse.epf.authoring.ui.richtext.IMethodRichText; |
| import org.eclipse.epf.authoring.ui.richtext.MethodRichTextContext; |
| import org.eclipse.epf.authoring.ui.util.MethodRichTextMarkerHelper; |
| import org.eclipse.epf.common.IHTMLFormatter; |
| import org.eclipse.epf.library.layout.RichTextContentValidator; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.richtext.RichText; |
| import org.eclipse.epf.uma.ContentDescription; |
| import org.eclipse.epf.uma.DescribableElement; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.ProcessComponent; |
| import org.eclipse.jface.fieldassist.ControlDecoration; |
| import org.eclipse.jface.fieldassist.FieldDecorationRegistry; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| |
| /** |
| * A Method Editor Rich Text control. |
| * |
| * @author Kelvin Low |
| * @author Jeff Hardy |
| * @since 1.0 |
| */ |
| public class MethodRichText extends RichText implements IMethodRichText { |
| |
| // The method element associated with this rich text control. |
| private MethodElement methodElement; |
| |
| // the MethodElement's ContentDescription |
| private ContentDescription contentDescription; |
| |
| // The modal object associated with this rich text control. |
| private EObject modalObject; |
| |
| // The modal object feature associated with this rich text control. |
| private EStructuralFeature modalObjectFeature; |
| |
| // The resource being edited |
| protected Resource resource; |
| |
| // the decoratedField label |
| protected Label label; |
| |
| protected ControlDecoration controlDecoration; |
| |
| protected final Image errorFieldDecorationImage = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage(); |
| |
| // Field name being edited |
| protected String fieldName = ""; //$NON-NLS-1$ |
| |
| // Field name being edited with the trailing : removed |
| protected String fieldNameTrim; |
| |
| // marker helper |
| protected MethodRichTextMarkerHelper markerHelper; |
| |
| // // marker attribute |
| // private static String METHOD_FIELDNAME = "MethodFieldName"; |
| |
| // // marker ID |
| // protected static final String MARKER_ID = "org.eclipse.epf.authoring.ui.methodRichText"; //$NON-NLS-1$ |
| |
| /** |
| * Creates a new instance. |
| * |
| * @param parent |
| * The parent control. |
| * @param style |
| * The initial style for the editor. |
| * @param basePath |
| * The base path used for resolving hrefs. |
| */ |
| public MethodRichText(Composite parent, int style, String basePath) { |
| super(parent, style, basePath); |
| } |
| |
| /** |
| * Creates a new instance. |
| * |
| * @param context |
| * The context |
| */ |
| public MethodRichText(MethodRichTextContext context) { |
| this(context.getParent(), context.getStyle(), context.getBasePath()); |
| } |
| |
| /** |
| * Updates the presentation names of all element links. |
| * |
| * @param text |
| * Rich text encoded in HTML format. |
| */ |
| @Override |
| protected String tidyText(String text) { |
| /* |
| * this will do the following to the HTML: |
| * 1. update Element Links |
| * 2. change <A ..> to <a ..> |
| * 3. change </A> to </a> |
| * 4. add double-quotes (") around all attribute values if they are missing |
| */ |
| |
| return ResourceHelper.validateRichTextContent(methodElement, text, |
| new RichTextContentValidator()); |
| } |
| |
| /** |
| * Sets the method element associated with this rich text control. |
| * |
| * @param methodElement |
| */ |
| public void setMethodElement(MethodElement methodElement) { |
| this.methodElement = methodElement; |
| if (this.methodElement instanceof ProcessComponent) { |
| this.methodElement = ((ProcessComponent) this.methodElement).getProcess(); |
| } |
| if (this.methodElement instanceof DescribableElement) { |
| this.contentDescription = ((DescribableElement)this.methodElement).getPresentation(); |
| } else if (this.methodElement instanceof ContentDescription) { |
| this.contentDescription = (ContentDescription)(this.methodElement); |
| } |
| } |
| |
| /** |
| * Returns the method element associated with this rich text control. |
| */ |
| public MethodElement getMethodElement() { |
| return methodElement; |
| } |
| |
| /** |
| * Returns the modal object associated with this rich text control. |
| */ |
| public EObject getModalObject() { |
| return modalObject; |
| } |
| |
| /** |
| * Sets the modal object associated with this rich text control. |
| */ |
| public void setModalObject(EObject modalObject) { |
| this.modalObject = modalObject; |
| } |
| |
| /** |
| * Returns modal object feature associated with this rich text control. |
| */ |
| public EStructuralFeature getModalObjectFeature() { |
| return modalObjectFeature; |
| } |
| |
| /** |
| * Sets the modal object feature associated with this rich text control. |
| */ |
| public void setModalObjectFeature(EStructuralFeature modalObjectFeature) { |
| this.modalObjectFeature = modalObjectFeature; |
| } |
| |
| public String getFieldName() { |
| return fieldName; |
| } |
| |
| public void setDecoratedFieldLabel(Label label) { |
| this.label = label; |
| if (label != null) { |
| Object data = label.getData(BaseFormPage.LABEL_DECORATOR_KEY); |
| if (data instanceof ControlDecoration) { |
| controlDecoration = (ControlDecoration)data; |
| controlDecoration.setImage(errorFieldDecorationImage); |
| controlDecoration.hide(); |
| } |
| updateFieldNameFromLabel(label); |
| } |
| } |
| |
| private boolean updateFieldNameFromLabel(Label label) { |
| if (label != null) { |
| String fieldName = label.getText(); |
| if (!this.fieldName.equals(fieldName)) { |
| this.fieldName = fieldName; |
| int colonIndex = fieldName.indexOf(':'); |
| if (colonIndex == -1) |
| colonIndex = fieldName.length(); |
| this.fieldNameTrim = fieldName.substring(0, colonIndex).trim(); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public void init(MethodElement element, Label label) { |
| setMethodElement(element); |
| setDecoratedFieldLabel(label); |
| markerHelper = MethodRichTextMarkerHelper.INSTANCE; |
| } |
| |
| @Override |
| protected String formatHTML(String text) { |
| String formattedText; |
| try { |
| // clear markers first |
| clearMarkers(); |
| // Call JTidy to format the source to XHTML. |
| formattedText = htmlFormatter.formatHTML(text); |
| if (htmlFormatter.getLastErrorStr() != null) { |
| String errorString = htmlFormatter.getLastErrorStr(); |
| // create markers |
| try { |
| createMarker(errorString); |
| } catch (CoreException cex) { |
| logger.logError(cex); |
| } |
| } |
| return formattedText; |
| } catch (UnsupportedEncodingException e) { |
| logger.logError(e); |
| } |
| return text; |
| } |
| |
| protected void clearMarkers() { |
| markerHelper.deleteMarkers(contentDescription, fieldNameTrim); |
| setErrorDescription(""); //$NON-NLS-1$ |
| hideErrorDecoration(); |
| refreshDecorators(); |
| } |
| |
| protected void setErrorDescription(String text) { |
| if (controlDecoration != null) { |
| controlDecoration.setDescriptionText(text); |
| } |
| } |
| |
| protected void refreshDecorators() { |
| // refresh |
| // PlatformUI.getWorkbench().getDecoratorManager().update(MethodElementLightweightLabelDecorator.DECORATOR_ID); |
| } |
| |
| |
| /* |
| * TODO: |
| * had to undo change in DescribableElementImpl to set presentation on any new obj |
| * so editor will need to assign presentation when field is edited so that the marker |
| * can be added to the presentation's resource |
| */ |
| |
| |
| protected void createMarker(String fullErrMsg) throws CoreException { |
| if (contentDescription.eContainer() instanceof DescribableElement) { |
| Matcher m = IHTMLFormatter.jTidyErrorParser.matcher(fullErrMsg); |
| if (m.find()) { |
| String location = m.group(1); |
| String errorMsg = m.group(4); |
| BasicDiagnostic diagnostics = |
| new BasicDiagnostic |
| (IHTMLFormatter.DIAGNOSTIC_SOURCE, |
| 0, "", //$NON-NLS-1$ |
| new Object[] { contentDescription, fieldNameTrim }); |
| |
| diagnostics.add( |
| new BasicDiagnostic(Diagnostic.ERROR, |
| location, 0, errorMsg, |
| new Object[] { contentDescription, fieldNameTrim })); |
| |
| markerHelper.createMarkers(diagnostics); |
| setErrorDescription(errorMsg); |
| showErrorDecoration(); |
| refreshDecorators(); |
| } |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| super.dispose(); |
| clearMarkers(); |
| refreshDecorators(); |
| } |
| |
| public void showErrorDecoration() { |
| if (controlDecoration != null) { |
| controlDecoration.show(); |
| } |
| } |
| |
| public void hideErrorDecoration() { |
| if (controlDecoration != null) { |
| controlDecoration.hide(); |
| } |
| } |
| |
| @Override |
| public void setText(String text) { |
| // check if label text was changed (this happens when RTE is expanded) |
| // this is called when RTE is toggled in editor - read new fieldName |
| if (updateFieldNameFromLabel(label)) |
| hideErrorDecoration(); |
| super.setText(text); |
| } |
| } |