blob: 786cbcc9057cf5913355c33ce8b7b37b509f2c9c [file] [log] [blame]
//------------------------------------------------------------------------------
// 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.html.HTMLFormatter;
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();
}
}
/**
* 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 = HTMLFormatter.jTidyErrorParser.matcher(fullErrMsg);
if (m.find()) {
String location = m.group(1);
String errorMsg = m.group(4);
BasicDiagnostic diagnostics =
new BasicDiagnostic
(HTMLFormatter.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);
}
}