blob: a5ac00088a27a226a2557ac454df2eea792a013a [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.providers.MethodElementLightweightLabelDecorator;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.richtext.RichTextContentValidator;
import org.eclipse.epf.authoring.ui.util.MethodRichTextMarkerHelper;
import org.eclipse.epf.common.html.HTMLFormatter;
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.DecoratedField;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
/**
* 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 DecoratedField label;
protected final FieldDecoration errorFieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
// 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);
}
/**
* 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(DecoratedField label) {
this.label = label;
if (label != null) {
label.addFieldDecoration(errorFieldDecoration,
SWT.LEFT | SWT.BOTTOM, false);
label.hideDecoration(errorFieldDecoration);
updateFieldNameFromLabel(label);
}
}
private boolean updateFieldNameFromLabel(DecoratedField label) {
String fieldName = ((Label)label.getControl()).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;
} else {
return false;
}
}
public void init(MethodElement element, DecoratedField label) {
setMethodElement(element);
setDecoratedFieldLabel(label);
markerHelper = MethodRichTextMarkerHelper.INSTANCE;
}
@Override
protected String formatHTML(String text) {
String formattedText;
try {
// clear markers
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);
} finally {
refreshDecorators();
}
return text;
}
protected void clearMarkers() {
markerHelper.deleteMarkers(contentDescription, fieldNameTrim);
errorFieldDecoration.setDescription(""); //$NON-NLS-1$
hideErrorDecoration();
}
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, fieldName,
new Object[] { contentDescription, fieldNameTrim });
diagnostics.add(
new BasicDiagnostic(Diagnostic.ERROR,
location, 0, errorMsg,
new Object[] { contentDescription, fieldNameTrim }));
markerHelper.createMarkers(diagnostics);
errorFieldDecoration.setDescription(errorMsg);
showErrorDecoration();
}
}
}
@Override
public void dispose() {
super.dispose();
clearMarkers();
refreshDecorators();
}
public void showErrorDecoration() {
if (label != null) {
label.showDecoration(errorFieldDecoration);
}
}
public void hideErrorDecoration() {
if (label != null) {
label.hideDecoration(errorFieldDecoration);
}
}
@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);
}
}