package org.argeo.cms.forms;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
import org.argeo.cms.ui.CmsView;
import org.argeo.cms.util.CmsUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/** Utilitary methods to ease implementation of CMS forms */
public class FormUtils {
private final static Log log = LogFactory.getLog(FormUtils.class);
public final static String DEFAULT_SHORT_DATE_FORMAT = "dd/MM/yyyy";
/** Best effort to convert a String to a calendar. Fails silently */
public static Calendar parseDate(DateFormat dateFormat, String calStr) {
Calendar cal = null;
if (EclipseUiUtils.notEmpty(calStr)) {
try {
Date date = dateFormat.parse(calStr);
cal = new GregorianCalendar();
cal.setTime(date);
} catch (ParseException pe) {
// Silent
log.warn("Unable to parse date: " + calStr + " - msg: "
+ pe.getMessage());
}
}
return cal;
}
/** Add a double click listener on tables that display a JCR node list */
public static void addCanonicalDoubleClickListener(final TableViewer v) {
v.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
CmsView cmsView = CmsUtils.getCmsView();
Node node = (Node) ((IStructuredSelection) event.getSelection())
.getFirstElement();
try {
cmsView.navigateTo(node.getPath());
} catch (RepositoryException e) {
throw new CmsException("Unable to get path for node "
+ node + " before calling navigateTo(path)", e);
}
}
});
}
// MANAGE ERROR DECORATION
public static ControlDecoration addDecoration(final Text text) {
final ControlDecoration dynDecoration = new ControlDecoration(text,
SWT.LEFT);
Image icon = getDecorationImage(FieldDecorationRegistry.DEC_ERROR);
dynDecoration.setImage(icon);
dynDecoration.setMarginWidth(3);
dynDecoration.hide();
return dynDecoration;
}
public static void refreshDecoration(Text text, ControlDecoration deco,
boolean isValid, boolean clean) {
if (isValid || clean) {
text.setBackground(null);
deco.hide();
} else {
text.setBackground(new Color(text.getDisplay(), 250, 200, 150));
deco.show();
}
}
public static Image getDecorationImage(String image) {
FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
return registry.getFieldDecoration(image).getImage();
}
public static void addCompulsoryDecoration(Label label) {
final ControlDecoration dynDecoration = new ControlDecoration(label,
SWT.RIGHT | SWT.TOP);
Image icon = getDecorationImage(FieldDecorationRegistry.DEC_REQUIRED);
dynDecoration.setImage(icon);
dynDecoration.setMarginWidth(3);
}
// TODO the read only generation of read only links for various contact type
// should be factorised in the cms Utils.
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able phone number
*/
public static String getPhoneLink(String value) {
return getPhoneLink(value, value);
}
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able phone number
*
* @param value
* @param label
* a potentially distinct label
* @return
*/
public static String getPhoneLink(String value, String label) {
StringBuilder builder = new StringBuilder();
builder.append("").append(label)
.append("");
return builder.toString();
}
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able mail
*/
public static String getMailLink(String value) {
return getMailLink(value, value);
}
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able mail
*
* @param value
* @param label
* a potentially distinct label
* @return
*/
public static String getMailLink(String value, String label) {
StringBuilder builder = new StringBuilder();
value = replaceAmpersand(value);
builder.append("").append(label).append("");
return builder.toString();
}
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able link
*/
public static String getUrlLink(String value) {
return getUrlLink(value, value);
}
/**
* Creates the read-only HTML snippet to display in a label with styling
* enabled in order to provide a click-able link
*/
public static String getUrlLink(String value, String label) {
StringBuilder builder = new StringBuilder();
value = replaceAmpersand(value);
label = replaceAmpersand(label);
if (!(value.startsWith("http://") || value.startsWith("https://")))
value = "http://" + value;
builder.append("" + label + "");
return builder.toString();
}
private static String AMPERSAND = "&";
/**
* Cleans a String by replacing any '&' by its HTML encoding '&' to
* avoid SAXParseException
while rendering HTML with RWT
*/
public static String replaceAmpersand(String value) {
value = value.replaceAll("&(?![#a-zA-Z0-9]+;)", AMPERSAND);
return value;
}
// Prevents instantiation
private FormUtils() {
}
}