| /* |
| * Copyright (c) 2014 Eike Stepper (Berlin, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.oomph.ui; |
| |
| import org.eclipse.oomph.util.StringUtil; |
| |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Text; |
| |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class ErrorDialog extends MessageDialog |
| { |
| private static final int TEXT_LINE_COUNT = 15; |
| |
| private final Throwable throwable; |
| |
| private final int detailsButtonID; |
| |
| private Text text; |
| |
| private ErrorDialog(String title, Throwable throwable) |
| { |
| this(title, throwable, 0, 1, IDialogConstants.OK_LABEL, IDialogConstants.SHOW_DETAILS_LABEL); |
| } |
| |
| protected ErrorDialog(String title, Throwable throwable, int defaultButtonID, int detailsButtonID, String... dialogButtonLabels) |
| { |
| super(null, title, null, "Internal error:" + StringUtil.NL + getMessage(throwable), MessageDialog.ERROR, dialogButtonLabels, defaultButtonID); |
| this.throwable = throwable; |
| this.detailsButtonID = detailsButtonID; |
| setShellStyle(SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL); |
| } |
| |
| protected void createDropDownText(Composite parent) |
| { |
| text = new Text(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); |
| text.setFont(parent.getFont()); |
| |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter out = new PrintWriter(stringWriter); |
| throwable.printStackTrace(out); |
| out.close(); |
| text.setText(stringWriter.toString()); |
| |
| GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL); |
| data.heightHint = text.getLineHeight() * TEXT_LINE_COUNT; |
| data.horizontalSpan = 2; |
| text.setLayoutData(data); |
| } |
| |
| @Override |
| protected void buttonPressed(int buttonId) |
| { |
| if (buttonId == detailsButtonID) |
| { |
| toggleDetailsArea(); |
| } |
| else |
| { |
| super.buttonPressed(buttonId); |
| } |
| } |
| |
| private void toggleDetailsArea() |
| { |
| Point windowSize = getShell().getSize(); |
| Point oldSize = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| |
| if (text != null) |
| { |
| text.dispose(); |
| text = null; |
| getButton(detailsButtonID).setText(IDialogConstants.SHOW_DETAILS_LABEL); |
| } |
| else |
| { |
| createDropDownText((Composite)getContents()); |
| getButton(detailsButtonID).setText(IDialogConstants.HIDE_DETAILS_LABEL); |
| } |
| |
| Point newSize = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| getShell().setSize(new Point(windowSize.x, windowSize.y + newSize.y - oldSize.y)); |
| } |
| |
| private static String getMessage(Throwable t) |
| { |
| try |
| { |
| String message = getMessageRecursively(t); |
| if (!StringUtil.isEmpty(message)) |
| { |
| return message; |
| } |
| } |
| catch (Throwable ex) |
| { |
| //$FALL-THROUGH$ |
| } |
| |
| return t.getClass().getSimpleName(); |
| } |
| |
| private static String getMessageRecursively(Throwable t) |
| { |
| String message = t.getMessage(); |
| if (StringUtil.isEmpty(message)) |
| { |
| Throwable cause = t.getCause(); |
| if (cause != null) |
| { |
| return getMessageRecursively(cause); |
| } |
| } |
| |
| return message; |
| } |
| |
| private static void openWithDetail(Throwable detail) |
| { |
| ErrorDialog dialog = new ErrorDialog("Error", detail); |
| dialog.open(); |
| } |
| |
| public static void open(final Throwable detail) |
| { |
| if (Display.getCurrent() == Display.getDefault()) |
| { |
| openWithDetail(detail); |
| } |
| else |
| { |
| Display.getDefault().syncExec(new Runnable() |
| { |
| public void run() |
| { |
| openWithDetail(detail); |
| } |
| }); |
| } |
| } |
| |
| } |