/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* 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
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Mathias Stuempert - initial API and implementation
* Ariel Garcia - modified to work for any Throwable
*****************************************************************************/
package eu.geclipse.ui.internal.dialogs;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import eu.geclipse.core.reporting.IProblem;
import eu.geclipse.core.reporting.ProblemException;
import eu.geclipse.ui.dialogs.GridFileDialog;
import eu.geclipse.ui.internal.Activator;
/**
* Dialog for reporting {@link IProblem}s. The dialog supports sending, saving
* and copying the problem report to the system clipboard.
*/
public class ProblemReportDialog extends TitleAreaDialog {
/**
* ID of the send button.
*/
private static final int SEND_ID = 0x01;
/**
* ID of the save button.
*/
private static final int SAVE_ID = 0x02;
/**
* ID of the copy button.
*/
private static final int COPY_ID = 0x03;
/**
* The throwable to be reported.
*/
private Throwable exc;
/**
* The associated problem to be reported, if any.
*/
private IProblem problem;
/**
* Text field for the email address.
*/
private Text mailtoText;
/**
* The text holding the problem report.
*/
private Text reportText;
/**
* Create a new problem report dialog for the specified problem.
*
* @param parentShell The dialog's parent {@link Shell}.
* @param throwable The {@link Throwable} to be reported.
*/
public ProblemReportDialog( final Shell parentShell, final Throwable throwable ) {
super( parentShell );
this.exc = throwable;
if ( this.exc instanceof ProblemException ) {
this.problem = ( ( ProblemException ) this.exc ).getProblem();
} else {
this.problem = null;
}
setShellStyle( SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE );
URL imgURL = Activator.getDefault().getBundle()
.getResource( "icons/extras/problem_report_dlg.gif" ); //$NON-NLS-1$
ImageDescriptor imgDesc = ImageDescriptor.createFromURL( imgURL );
setTitleImage( imgDesc.createImage() );
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell( final Shell shell ) {
super.configureShell( shell );
shell.setText( "Problem Report" );
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
*/
@Override
protected void buttonPressed( final int buttonId ) {
if ( buttonId == IDialogConstants.CLIENT_ID + SEND_ID ) {
sendPressed();
} else if ( buttonId == IDialogConstants.CLIENT_ID + SAVE_ID ) {
savePressed();
} else if ( buttonId == IDialogConstants.CLIENT_ID + COPY_ID ) {
copyPressed();
} else if ( buttonId == IDialogConstants.CLOSE_ID ) {
closePressed();
} else {
super.buttonPressed( buttonId );
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void createButtonsForButtonBar( final Composite parent ) {
createButton( parent, IDialogConstants.CLIENT_ID + SEND_ID, "Send", true );
createButton( parent, IDialogConstants.CLIENT_ID + SAVE_ID, "Save", false );
createButton( parent, IDialogConstants.CLIENT_ID + COPY_ID, "Copy", false );
createButton( parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, false );
updateUI();
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea( final Composite parent ) {
Label topRule = new Label( parent, SWT.HORIZONTAL | SWT.SEPARATOR );
topRule.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
Composite mainComp = new Composite( parent, SWT.NONE );
mainComp.setLayout( new GridLayout( 1, false ) );
mainComp.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
Label mailtoLabel = new Label( mainComp, SWT.NONE );
mailtoLabel.setText( "Email address:" );
mailtoLabel.setLayoutData( new GridData() );
this.mailtoText = new Text( mainComp, SWT.BORDER );
String mailto = null;
if ( this.problem != null ) {
mailto = this.problem.getMailTo();
}
this.mailtoText.setText( mailto == null ? "" : mailto ); //$NON-NLS-1$
this.mailtoText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false ) );
Label reportLabel = new Label( mainComp, SWT.NONE );
reportLabel.setText( "Problem Report:" );
reportLabel.setLayoutData( new GridData() );
this.reportText = new Text( mainComp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER );
ProblemReport factory = new ProblemReport( this.exc );
this.reportText.setText( factory.createReport() );
GridData gData = new GridData( SWT.FILL, SWT.FILL, true, true );
gData.widthHint = 500;
gData.heightHint = 400;
this.reportText.setLayoutData( gData );
Label bottomRule = new Label( parent, SWT.HORIZONTAL | SWT.SEPARATOR );
bottomRule.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
this.mailtoText.addModifyListener( new ModifyListener() {
public void modifyText( final ModifyEvent e ) {
updateUI();
}
} );
setTitle( "Problem Report" );
setMessage( "A problem report was created, you may save it, send it via email, or copy it to clipboard." );
updateUI();
return mainComp;
}
/**
* Called when the close button is pressed.
*/
protected void closePressed() {
setReturnCode( OK );
close();
}
/**
* Called when the copy button is pressed.
*/
protected void copyPressed() {
try {
Transfer[] dataTypes = new Transfer[] {
TextTransfer.getInstance()
};
Object[] data = new Object[] {
this.reportText.getText()
};
Clipboard clipboard = new Clipboard( getShell().getDisplay() );
clipboard.setContents( data, dataTypes );
clipboard.dispose();
setMessage(
"The problem report was copied to the system clipboard",
IMessageProvider.INFORMATION );
} catch ( Throwable t ) {
setErrorMessage( String.format( "Copy failed: %s", t.getLocalizedMessage() ) );
}
}
/**
* Called when the save button is pressed.
*/
protected void savePressed() {
try {
GridFileDialog dialog = new GridFileDialog( getShell(), GridFileDialog.STYLE_ALLOW_ONLY_FILES );
if ( dialog.open() == Window.OK ) {
IFileStore[] fsList = dialog.getSelectedFileStores();
if ( ( fsList != null ) && ( fsList.length > 0 ) ) {
saveReport( fsList[ 0 ], this.reportText.getText() );
setMessage(
String.format( "The problem report saved to %s", fsList[ 0 ].toString() ),
IMessageProvider.INFORMATION );
}
}
} catch ( Throwable t ) {
setErrorMessage( String.format( "Save failed: %s", t.getLocalizedMessage() ) );
}
}
/**
* Called when the send button is pressed.
*/
protected void sendPressed() {
try {
String mailto = this.mailtoText.getText();
if ( ( mailto == null ) || ( mailto.length() == 0 ) ) {
throw new IllegalArgumentException( "The mailto address is empty" );
}
URL link = getMailToLink( this.reportText.getText(), mailto );
IWorkbenchBrowserSupport browserSupport
= PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser externalBrowser
= browserSupport.getExternalBrowser();
externalBrowser.openURL( link );
setMessage(
String.format( "An attempt was made to send to problem report to %s", mailto ),
IMessageProvider.INFORMATION );
} catch ( Throwable t ) {
setErrorMessage( String.format( "Send failed: %s", t.getLocalizedMessage() ) );
}
}
protected void updateUI() {
Button sendButton = getButton( IDialogConstants.CLIENT_ID + SEND_ID );
if ( sendButton != null ) {
String mailto = this.mailtoText.getText();
sendButton.setEnabled( ( mailto != null ) && ( mailto.length() > 0 ) );
}
}
/**
* Get the mailto link for the send action.
*
* @param report The report to be send.
* @return The mailto link as {@link URL}.
* @throws MalformedURLException If the {@link URL} is malformed.
*/
private URL getMailToLink( final String report, final String address )
throws MalformedURLException {
if ( ( address == null ) || ( address.length() == 0 ) ) {
throw new IllegalArgumentException( "The mailto address is empty" );
}
return new URL(
"mailto:" + address
+ "?subject=Problem Report: " + this.problem.getDescription()
+ "&body=" + report
);
}
/**
* Save the report to the specified {@link IFileStore}.
*
* @param store The {@link IFileStore} to which to save the report.
* @param report The report to be saved.
* @throws CoreException If the output stream could not be opened.
* @throws IOException If writing to the output stream or closing the
* stream failed.
*/
private void saveReport( final IFileStore store, final String report )
throws CoreException, IOException {
OutputStream oStream = store.openOutputStream( EFS.NONE, null );
oStream.write( report.getBytes() );
oStream.close();
}
}