///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;
namespace JetBrains.ExceptionReport
{
public class ExceptionReportForm : Form
{
private static Hashtable _excludedExceptions = new Hashtable();
private IExceptionSubmitter _submitter;
private string _projectKey;
private Label label1;
private TextBox _errorText;
private GroupBox _grpITNLogin;
private Label label2;
private TextBox _edtUserName;
private Label label3;
private TextBox _edtPassword;
private Button _btnSubmit;
private Label _lblProgress;
///
/// Required designer variable.
///
private Container components = null;
private Exception _exception;
private Label label4;
private TextBox _edtDescription;
private Label label5;
private CheckBox _chkDontShowAgain;
private int _buildNumber;
private string _buildDesc;
private Button _btnIgnore;
private LinkLabel _linkITNRegister;
private bool _displaySubmissionResult;
private ProxySettings _proxySettings = new ProxySettings();
private CheckBox _chkAttachLog;
private Button _btnProxy;
private string _defaultUserName;
private string _defaultPassword;
public ExceptionReportForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
_buildNumber = Assembly.GetExecutingAssembly().GetName().Version.Build;
_submitter = null;
}
public IExceptionSubmitter Submitter
{
set { _submitter = value; }
}
public string ProjectKey
{
get { return _projectKey; }
set { _projectKey = value; }
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this._errorText = new System.Windows.Forms.TextBox();
this._grpITNLogin = new System.Windows.Forms.GroupBox();
this._linkITNRegister = new System.Windows.Forms.LinkLabel();
this._edtPassword = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this._edtUserName = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this._btnProxy = new System.Windows.Forms.Button();
this._btnSubmit = new System.Windows.Forms.Button();
this._lblProgress = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this._edtDescription = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this._chkDontShowAgain = new System.Windows.Forms.CheckBox();
this._btnIgnore = new System.Windows.Forms.Button();
this._chkAttachLog = new System.Windows.Forms.CheckBox();
this._grpITNLogin.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label1.Location = new System.Drawing.Point(8, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(424, 32);
this.label1.TabIndex = 0;
this.label1.Text = "An internal error has occured. To help us fix the problem, please submit the erro" +
"r information to the ITN tracker.";
//
// _errorText
//
this._errorText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._errorText.Location = new System.Drawing.Point(8, 172);
this._errorText.Multiline = true;
this._errorText.Name = "_errorText";
this._errorText.ReadOnly = true;
this._errorText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this._errorText.Size = new System.Drawing.Size(424, 92);
this._errorText.TabIndex = 4;
this._errorText.Text = "";
//
// _grpITNLogin
//
this._grpITNLogin.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._grpITNLogin.Controls.Add(this._linkITNRegister);
this._grpITNLogin.Controls.Add(this._edtPassword);
this._grpITNLogin.Controls.Add(this.label3);
this._grpITNLogin.Controls.Add(this._edtUserName);
this._grpITNLogin.Controls.Add(this.label2);
this._grpITNLogin.Controls.Add(this._btnProxy);
this._grpITNLogin.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._grpITNLogin.Location = new System.Drawing.Point(8, 268);
this._grpITNLogin.Name = "_grpITNLogin";
this._grpITNLogin.Size = new System.Drawing.Size(424, 96);
this._grpITNLogin.TabIndex = 5;
this._grpITNLogin.TabStop = false;
this._grpITNLogin.Text = "JIRA Login (optional)";
//
// _linkITNRegister
//
this._linkITNRegister.Location = new System.Drawing.Point(84, 68);
this._linkITNRegister.Name = "_linkITNRegister";
this._linkITNRegister.Size = new System.Drawing.Size(100, 16);
this._linkITNRegister.TabIndex = 4;
this._linkITNRegister.TabStop = true;
this._linkITNRegister.Text = "&Register at JIRA";
this._linkITNRegister.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this._linkITNRegister_LinkClicked);
//
// _edtPassword
//
this._edtPassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._edtPassword.Location = new System.Drawing.Point(84, 44);
this._edtPassword.Name = "_edtPassword";
this._edtPassword.PasswordChar = '*';
this._edtPassword.Size = new System.Drawing.Size(332, 21);
this._edtPassword.TabIndex = 3;
this._edtPassword.Text = "";
//
// label3
//
this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label3.Location = new System.Drawing.Point(8, 48);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(64, 16);
this.label3.TabIndex = 2;
this.label3.Text = "&Password:";
//
// _edtUserName
//
this._edtUserName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._edtUserName.Location = new System.Drawing.Point(84, 19);
this._edtUserName.Name = "_edtUserName";
this._edtUserName.Size = new System.Drawing.Size(332, 21);
this._edtUserName.TabIndex = 1;
this._edtUserName.Text = "";
//
// label2
//
this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label2.Location = new System.Drawing.Point(8, 24);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(64, 20);
this.label2.TabIndex = 0;
this.label2.Text = "&User name:";
//
// _btnProxy
//
this._btnProxy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this._btnProxy.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnProxy.Location = new System.Drawing.Point(304, 68);
this._btnProxy.Name = "_btnProxy";
this._btnProxy.Size = new System.Drawing.Size(112, 23);
this._btnProxy.TabIndex = 5;
this._btnProxy.Text = "Pro&xy Settings";
this._btnProxy.Click += new System.EventHandler(this._btnProxy_Click);
//
// _btnSubmit
//
this._btnSubmit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnSubmit.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnSubmit.Location = new System.Drawing.Point(272, 408);
this._btnSubmit.Name = "_btnSubmit";
this._btnSubmit.TabIndex = 9;
this._btnSubmit.Text = "&Submit";
this._btnSubmit.Click += new System.EventHandler(this._btnSubmit_Click);
//
// _lblProgress
//
this._lblProgress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._lblProgress.Location = new System.Drawing.Point(8, 388);
this._lblProgress.Name = "_lblProgress";
this._lblProgress.Size = new System.Drawing.Size(424, 16);
this._lblProgress.TabIndex = 8;
this._lblProgress.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// label4
//
this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label4.Location = new System.Drawing.Point(8, 40);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(424, 16);
this.label4.TabIndex = 1;
this.label4.Text = "Please &tell us what you were doing when you got the problem:";
//
// _edtDescription
//
this._edtDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._edtDescription.Location = new System.Drawing.Point(8, 56);
this._edtDescription.Multiline = true;
this._edtDescription.Name = "_edtDescription";
this._edtDescription.Size = new System.Drawing.Size(424, 92);
this._edtDescription.TabIndex = 2;
this._edtDescription.Text = "";
//
// label5
//
this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label5.Location = new System.Drawing.Point(8, 156);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(424, 16);
this.label5.TabIndex = 3;
this.label5.Text = "Technical &details:";
//
// _chkDontShowAgain
//
this._chkDontShowAgain.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._chkDontShowAgain.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkDontShowAgain.Location = new System.Drawing.Point(8, 368);
this._chkDontShowAgain.Name = "_chkDontShowAgain";
this._chkDontShowAgain.Size = new System.Drawing.Size(196, 16);
this._chkDontShowAgain.TabIndex = 6;
this._chkDontShowAgain.Text = "Do ¬ show this exception again";
//
// _btnIgnore
//
this._btnIgnore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnIgnore.DialogResult = System.Windows.Forms.DialogResult.OK;
this._btnIgnore.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnIgnore.Location = new System.Drawing.Point(356, 408);
this._btnIgnore.Name = "_btnIgnore";
this._btnIgnore.TabIndex = 10;
this._btnIgnore.Text = "&Ignore";
//
// _chkAttachLog
//
this._chkAttachLog.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._chkAttachLog.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkAttachLog.Location = new System.Drawing.Point(240, 368);
this._chkAttachLog.Name = "_chkAttachLog";
this._chkAttachLog.Size = new System.Drawing.Size(192, 16);
this._chkAttachLog.TabIndex = 7;
this._chkAttachLog.Text = "Attach &log file";
this._chkAttachLog.Visible = false;
//
// ExceptionReportForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
this.ClientSize = new System.Drawing.Size(440, 465);
this.ControlBox = false;
this.Controls.Add(this._chkAttachLog);
this.Controls.Add(this._btnIgnore);
this.Controls.Add(this._chkDontShowAgain);
this.Controls.Add(this.label5);
this.Controls.Add(this._edtDescription);
this.Controls.Add(this._errorText);
this.Controls.Add(this.label4);
this.Controls.Add(this._lblProgress);
this.Controls.Add(this._btnSubmit);
this.Controls.Add(this._grpITNLogin);
this.Controls.Add(this.label1);
this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
this.MinimumSize = new System.Drawing.Size(448, 473);
this.Name = "ExceptionReportForm";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Unhandled Exception";
this.VisibleChanged += new System.EventHandler(this.ExceptionReportForm_VisibleChanged);
this._grpITNLogin.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
public bool DisplaySubmissionResult
{
set { _displaySubmissionResult = value; }
}
public void SetITNLogin( string userName, string password )
{
_edtUserName.Text = userName;
_edtPassword.Text = password;
}
public void SetDefaultLogin( string userName, string password )
{
_defaultUserName = userName;
_defaultPassword = password;
}
public void SetProxy( ProxySettings settings )
{
_proxySettings = settings;
}
public void SetBuildNumber( int buildNumber )
{
_buildNumber = buildNumber;
}
public string ITNUserName
{
get { return _edtUserName.Text; }
}
public string ITNPassword
{
get { return _edtPassword.Text; }
}
public ProxySettings ProxySettings
{
get { return _proxySettings; }
}
public DialogResult ReportException( IWin32Window ownerWindow, Exception e, string buildDesc )
{
string excString = ITNExceptionSubmitter.FilterExceptionString( e.ToString() );
if (_excludedExceptions.ContainsKey( excString ))
{
AttachLog = false;
return DialogResult.None;
}
_errorText.Text = e.ToString();
_errorText.Select( 0, 0 );
_exception = e;
_buildDesc = buildDesc;
DialogResult dlgResult = ownerWindow == null ? ShowDialog() : ShowDialog( ownerWindow );
if (dlgResult == DialogResult.OK && _chkDontShowAgain.Checked)
{
string filterStr = ITNExceptionSubmitter.FilterExceptionString( _exception.ToString() );
if (!_excludedExceptions.ContainsKey( filterStr ))
_excludedExceptions.Add( filterStr, true );
}
return dlgResult;
}
private void _btnSubmit_Click( object sender, EventArgs e )
{
string userName = _edtUserName.Text;
string password = _edtPassword.Text;
if ( userName == "" || password == "")
{
if ( _defaultUserName == "" || _defaultPassword == "" )
{
MessageBox.Show( this, "Please enter your user name and password.", "Report Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
return;
}
userName = _defaultUserName;
password = _defaultPassword;
}
try
{
_btnSubmit.Enabled = false;
string description;
if (_edtDescription.Text.Length > 0)
description = _edtDescription.Text + "\n" + _buildDesc;
else
description = _buildDesc;
_submitter.SubmitProgress += new SubmitProgressEventHandler( submitter_SubmitProgress );
SubmissionResult submissionResult = _submitter.SubmitException( _exception, description, userName, password, _buildNumber, ProxySettings.Proxy );
if (_displaySubmissionResult && submissionResult != null)
{
ShowSubmissionResult( this, submissionResult, this._projectKey );
}
else
{
MessageBox.Show( this, "Thank you for your bug report!", "Report Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Information );
}
DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
MessageBox.Show( this, "Error submitting exception to the tracker.\n" + ex.ToString(), "Report Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
_submitter = null;
}
public static void ShowSubmissionResult( IWin32Window owner, SubmissionResult submissionResult, string projectKey )
{
string msgBoxText = "Thank you for your bug report!";
if ( IsRequestFixed( submissionResult ) )
{
string resolution = GetRequestResolution( submissionResult );
if ( resolution == null )
{
msgBoxText += "\nThis request (" + BuildRequestNumber( submissionResult.ThreadId, projectKey ) + ") has already been FIXED";
}
else
{
msgBoxText += "\nThis request (" + BuildRequestNumber( submissionResult.ThreadId, projectKey ) + ") has been resolved as " + resolution;
}
msgBoxText += GetFixVersionText( submissionResult );
}
else
{
string verb = submissionResult.IsUpdated ? "updated" : "created";
msgBoxText += "\n";
msgBoxText += "Request " + BuildRequestNumber( submissionResult.ThreadId, projectKey ) + " has been " + verb;
}
MessageBox.Show( owner, msgBoxText, "Report Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Information );
}
private static bool IsRequestFixed( SubmissionResult submissionResult )
{
XmlDocument requestDescripion = submissionResult.RequestDescription;
if (requestDescripion == null)
return false;
string state = requestDescripion.DocumentElement.GetAttribute( "state" );
return state == "Fixed" || state == "Resolved";
}
private static string GetRequestResolution( SubmissionResult submissionResult )
{
XmlDocument requestDescripion = submissionResult.RequestDescription;
if (requestDescripion == null)
return null;
return requestDescripion.DocumentElement.GetAttribute( "resolution" );
}
private static string GetFixVersionText( SubmissionResult submissionResult )
{
XmlDocument requestDescripion = submissionResult.RequestDescription;
if (requestDescripion == null)
return "";
XmlNodeList versionNodes = requestDescripion.SelectNodes( "//fixVersions/version" );
if ( versionNodes.Count == 0 )
return "";
if ( versionNodes.Count == 1 )
{
return " in version " + versionNodes [0].Attributes ["name"].Value;
}
StringBuilder result = new StringBuilder( " in versions " );
bool first = true;
foreach( XmlNode node in versionNodes )
{
if ( !first )
{
result.Append( ", " );
}
else
{
first = false;
}
result.Append( node.Attributes ["name"].Value );
}
return result.ToString();
}
private void ExceptionReportForm_VisibleChanged( object sender, EventArgs e )
{
BringToFront();
}
private void _linkITNRegister_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e )
{
Process.Start( "http://www.jetbrains.net/jira/Signup!default.jspa" );
}
private void submitter_SubmitProgress( object sender, SubmitProgressEventArgs e )
{
_lblProgress.Text = e.Message;
Application.DoEvents();
}
private void _btnProxy_Click( object sender, EventArgs e )
{
using (ExceptionProxySetup dlg = new ExceptionProxySetup( _proxySettings ))
{
if (dlg.ShowDialog() != DialogResult.OK)
return;
try
{
_proxySettings = dlg.ProxySettings;
}
catch( FormatException )
{
MessageBox.Show( this, "Invalid port number specified in proxy settings.", "Exception Reporter",
MessageBoxButtons.OK, MessageBoxIcon.Error );
}
}
}
public bool AttachLog
{
get { return _chkAttachLog.Checked; }
set
{
if (value)
_chkAttachLog.Visible = true;
_chkAttachLog.Checked = value;
}
}
private static string BuildRequestNumber( int id, string projectKey )
{
if ( projectKey != null )
{
return projectKey + "-" + id;
}
return "#" + id;
}
}
}