From 5a774ac0f40507432d0a597b061934eb3781bdbe Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 29 Apr 2015 21:02:47 +0000 Subject: [PATCH] Improve error notifications. git-svn-id: https://svn.argeo.org/commons/trunk@8084 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../src/org/argeo/cms/CmsApplication.java | 68 +++++----- .../src/org/argeo/cms/util/CmsUtils.java | 2 + .../argeo/cms/util/SystemNotifications.java | 128 ++++++++++++++++++ 3 files changed, 165 insertions(+), 33 deletions(-) create mode 100644 org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java diff --git a/org.argeo.cms/src/org/argeo/cms/CmsApplication.java b/org.argeo.cms/src/org/argeo/cms/CmsApplication.java index fdf2e0270..74b3b6b03 100644 --- a/org.argeo.cms/src/org/argeo/cms/CmsApplication.java +++ b/org.argeo.cms/src/org/argeo/cms/CmsApplication.java @@ -2,8 +2,6 @@ package org.argeo.cms; import java.io.IOException; import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -18,13 +16,13 @@ import javax.jcr.Session; import javax.jcr.security.Privilege; import javax.jcr.version.VersionManager; -import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.auth.LoginRequiredException; import org.argeo.cms.internal.ImageManagerImpl; import org.argeo.cms.util.BundleResourceLoader; import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.util.SystemNotifications; import org.argeo.jcr.JcrUtils; import org.eclipse.gemini.blueprint.context.BundleContextAware; import org.eclipse.rap.rwt.RWT; @@ -41,8 +39,6 @@ import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; import org.osgi.framework.BundleContext; /** Configures an Argeo CMS RWT application. */ @@ -341,40 +337,46 @@ public class CmsApplication implements CmsConstants, ApplicationConfiguration, protected void refreshBody() { if (bodyArea == null) return; - // clear - for (Control child : bodyArea.getChildren()) - child.dispose(); - bodyArea.setLayout(CmsUtils.noSpaceGridLayout()); - // Exception Throwable exception = getException(); if (exception != null) { - new Label(bodyArea, SWT.NONE).setText("Unreachable state : " - + getState()); - if (getNode() != null) - new Label(bodyArea, SWT.NONE).setText("Context : " - + getNode()); - - Text errorText = new Text(bodyArea, SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL); - errorText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - true)); - StringWriter sw = new StringWriter(); - exception.printStackTrace(new PrintWriter(sw)); - errorText.setText(sw.toString()); - IOUtils.closeQuietly(sw); + // new Label(bodyArea, SWT.NONE).setText("Unreachable state : " + // + getState()); + // if (getNode() != null) + // new Label(bodyArea, SWT.NONE).setText("Context : " + // + getNode()); + // + // Text errorText = new Text(bodyArea, SWT.MULTI | SWT.H_SCROLL + // | SWT.V_SCROLL); + // errorText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + // true, + // true)); + // StringWriter sw = new StringWriter(); + // exception.printStackTrace(new PrintWriter(sw)); + // errorText.setText(sw.toString()); + // IOUtils.closeQuietly(sw); + SystemNotifications systemNotifications = new SystemNotifications( + bodyArea); + systemNotifications.notifyException(exception); resetException(); + return; // TODO report - } else { - String state = getState(); - try { - if (state == null) - throw new CmsException("State cannot be null"); - uiProvider.createUi(bodyArea, getNode()); - } catch (RepositoryException e) { - throw new CmsException("Cannot refresh body", e); - } } + + // clear + for (Control child : bodyArea.getChildren()) + child.dispose(); + bodyArea.setLayout(CmsUtils.noSpaceGridLayout()); + + String state = getState(); + try { + if (state == null) + throw new CmsException("State cannot be null"); + uiProvider.createUi(bodyArea, getNode()); + } catch (RepositoryException e) { + throw new CmsException("Cannot refresh body", e); + } + bodyArea.layout(true, true); } diff --git a/org.argeo.cms/src/org/argeo/cms/util/CmsUtils.java b/org.argeo.cms/src/org/argeo/cms/util/CmsUtils.java index 5d31e2c51..0eda74f53 100644 --- a/org.argeo.cms/src/org/argeo/cms/util/CmsUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/util/CmsUtils.java @@ -65,10 +65,12 @@ public class CmsUtils implements CmsConstants { return new RowData(16, 16); } + /** Style widget */ public static void style(Widget widget, String style) { widget.setData(CmsConstants.STYLE, style); } + /** Enable markups on widget */ public static void markup(Widget widget) { widget.setData(CmsConstants.MARKUP, true); } diff --git a/org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java b/org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java new file mode 100644 index 000000000..9d0c63845 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java @@ -0,0 +1,128 @@ +package org.argeo.cms.util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.commons.io.IOUtils; +import org.argeo.ArgeoException; +import org.argeo.cms.CmsStyles; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** Shell displaying system notifications such as exceptions */ +public class SystemNotifications extends Shell implements CmsStyles, + MouseListener { + private static final long serialVersionUID = -8129377525216022683L; + + private Control source; + + public SystemNotifications(Control source) { + super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); + setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU); + + this.source = source; + + // TODO UI + // setLocation(source.toDisplay(source.getSize().x - getSize().x, + // source.getSize().y)); + setLayout(new GridLayout()); + addMouseListener(this); + + addShellListener(new ShellAdapter() { + private static final long serialVersionUID = 5178980294808435833L; + + @Override + public void shellDeactivated(ShellEvent e) { + close(); + dispose(); + } + }); + + } + + public void notifyException(Throwable exception) { + Composite pane = this; + + Label lbl = new Label(pane, SWT.NONE); + lbl.setText(exception.getLocalizedMessage() + + (exception instanceof ArgeoException ? "" : "(" + + exception.getClass().getName() + ")") + "\n"); + lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + lbl.addMouseListener(this); + if (exception.getCause() != null) + appendCause(pane, exception.getCause()); + + StringBuilder mailToUrl = new StringBuilder("mailto:?"); + try { + mailToUrl.append("subject=").append( + URLEncoder.encode( + "Exception " + + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .format(new Date()), "UTF-8") + .replace("+", "%20")); + + StringWriter sw = new StringWriter(); + exception.printStackTrace(new PrintWriter(sw)); + IOUtils.closeQuietly(sw); + + // see + // http://stackoverflow.com/questions/4737841/urlencoder-not-able-to-translate-space-character + String encoded = URLEncoder.encode(sw.toString(), "UTF-8").replace( + "+", "%20"); + mailToUrl.append("&body=").append(encoded); + } catch (UnsupportedEncodingException e) { + mailToUrl.append("&body=").append("Could not encode: ") + .append(e.getMessage()); + } + Label mailTo = new Label(pane, SWT.NONE); + CmsUtils.markup(mailTo); + mailTo.setText("Send details"); + mailTo.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); + + pack(); + layout(); + + setLocation(source.toDisplay(source.getSize().x - getSize().x, + source.getSize().y - getSize().y)); + open(); + } + + private void appendCause(Composite parent, Throwable e) { + Label lbl = new Label(parent, SWT.NONE); + lbl.setText(" caused by: " + e.getLocalizedMessage() + " (" + + e.getClass().getName() + ")" + "\n"); + lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + lbl.addMouseListener(this); + if (e.getCause() != null) + appendCause(parent, e.getCause()); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + } + + @Override + public void mouseDown(MouseEvent e) { + close(); + dispose(); + } + + @Override + public void mouseUp(MouseEvent e) { + } + +} -- 2.30.2