'**************************************************************'
' BN+ Framework: Stand alone dialog '
' By De Dauw Jeroen - jeroendedauw@gmail.com '
'**************************************************************'
' Namespace Bn.Dialogs '
' Class BugSubmitter v1.0.0 - March 2009 '
'**************************************************************'
' Copyright 2009 - BN+ Discussions '
' http://code.bn2vs.com '
'**************************************************************'
' Author notes
' > Although this class is part of BN+ Framework, it can be used as a stand alone without modifications
' This code is avaible at
' > BN+ Discussions: http://code.bn2vs.com/viewtopic.php?t=147
' > The Code Project: http://www.codeproject.com/KB/dialog/BugSubmitterDialog.aspx
' Dutch support can be found here: http://www.helpmij.nl/forum/showthread.php?t=415085
Option Strict On : Option Explicit On
Imports System.ComponentModel
Imports System.Drawing
Imports System.IO
Imports System.Net
Imports System.Windows.Forms
Namespace Bn.Dialogs
#Region " Public Class BugSubmitter "
''' <summary>A dialog that enables user to submit variouse types of bugs with build in validation. Sends it's info to a webservice.</summary>
''' <remarks>Class BugSubmitter v1.0.0, by De Dauw Jeroen - March 2009</remarks>
<DesignTimeVisible(True), DefaultProperty("SubmitterPath"), DefaultEvent("Submitted")> _
Public Class BugSubmitter
Inherits System.Windows.Forms.Form
#Region "Events"
''' <summary>Occurs when the submit process is started</summary>
<Category("Behavior")> _
Public Event Submitting As EventHandler
''' <summary>Occurs when the submit process is completed successfully</summary>
<Category("Behavior")> _
Public Event Submitted As EventHandler
''' <summary>Occurs when the submit process is completed unsuccessfully</summary>
<Category("Behavior")> _
Public Event ErrorOccured As EventHandler
''' <summary>Occurs when the submit process is completed</summary>
<Category("Behavior")> _
Public Event SubmissionAttemptCompleted As EventHandler
''' <summary>Occurs when the update path is changed</summary>
<Category("Property Changed")> _
Public Event SubmitterPathChanged As EventHandler
''' <summary>Occurs when the update file is changed</summary>
<Category("Property Changed")> _
Public Event SubmitterFileChanged As EventHandler
''' <summary>Occurs when the application version info is changed</summary>
<Category("Property Changed")> _
Public Event ApplicationVersionChanged As EventHandler
''' <summary>Occurs when the UseErrorProvider property is changed</summary>
<Category("Property Changed")> _
Public Event UseErrorProviderChanged As EventHandler
''' <summary>Occurs when the minimum report length is changed</summary>
<Category("Property Changed")> _
Public Event MinimumReportLengthChanged As EventHandler
''' <summary>Occurs when the maximum report length is changed</summary>
<Category("Property Changed")> _
Public Event MaximumReportLengthChanged As EventHandler
#End Region
#Region "Fields"
Private WithEvents bgwSender As New BackgroundWorker
Private m_submitter_path, m_submitter_file, m_app_version As String
Private m_useErrorProvider As Boolean
Private m_minRepLength As Int32 = 5
Private m_parameters As String
Private m_errorOccured As Boolean
#End Region
#Region "Constructors"
''' <summary>Create a new instance</summary>
Public Sub New()
' Initialize the designer generated layout
Me.InitializeComponent()
' Set the default values of the complex type fields
setComponent()
' Set the default values of the properties
Me.UseErrorProvider = True
End Sub
#End Region
#Region "Public methods"
''' <summary>Attempt to send the bug report</summary>
Public Sub SendReport()
If Me.ReportLengthSuffies And Me.EmailIsValid Then
If Me.UseErrorProvider Then epReport.Dispose()
showSubmitting()
m_parameters = "?type=" & cbxBugType.Text & "&description=" & txtBugDescription.Text.Replace("&", "[amp]") & "&email=" & txtUserEmail.Text & "&version=" & Me.ApplicationVersion
bgwSender.RunWorkerAsync()
Else
If Me.UseErrorProvider Then
If Not Me.ReportLengthSuffies Then epReport.SetError(txtBugDescription, "Please enter a brief description")
If Not Me.EmailIsValid Then epReport.SetError(txtUserEmail, "Only valid email adresses are allowed")
End If
End If
End Sub
''' <summary>Cancel the bug report dialog</summary>
Public Sub Cancel()
Me.DialogResult = DialogResult.Cancel
Me.Close()
End Sub
''' <summary>Clean up the component list and other recources managed by the BugSubmitter</summary>
Public Overloads Sub Dispose()
Me.Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
#Region "Private/protected methods"
Private Sub BugSubmitter_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles MyBase.Paint
' Draw a line underneath the sub page title and one above the buttons
drawLines()
End Sub
Private Sub setComponent()
cbxBugType.SelectedIndex = 0
End Sub
Private Sub drawLines()
Dim gfx As Graphics = Me.CreateGraphics
Dim pen As New Pen(Color.DarkGray)
Dim upperLineY As Int32 = lblHeaderStatus.Height
Dim lowerLineY As Int32 = tlpButtons.Location.Y - (Me.Height - (tlpButtons.Location.Y + tlpButtons.Height)) + 25
gfx.DrawLine(pen, 0, upperLineY, Me.Width, upperLineY)
gfx.DrawLine(pen, 0, lowerLineY, Me.Width, lowerLineY)
End Sub
Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnSubmit.Click
Select Case btnSubmit.Text
Case "&Submit report" : Me.SendReport()
Case "&Finish" : Me.Dispose()
End Select
End Sub
Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnCancel.Click
Me.Cancel()
End Sub
Private Sub BugSubmitter_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles MyBase.FormClosing
Me.Dispose()
End Sub
Private Sub cbxBugType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cbxBugType.SelectedIndexChanged
btnSubmit.Enabled = Me.SubmitIsEnabled
End Sub
Private Sub txtBugDescription_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles txtBugDescription.TextChanged
If Me.ReportLengthSuffies Then epReport.SetError(txtBugDescription, "")
btnSubmit.Enabled = Me.SubmitIsEnabled
End Sub
Private Sub txtUserEmail_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles txtUserEmail.TextChanged
If Me.EmailIsValid Then epReport.SetError(txtUserEmail, "")
btnSubmit.Enabled = Me.SubmitIsEnabled
End Sub
Private Sub txtBugDescription_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles txtBugDescription.Enter
Me.AcceptButton = Nothing
End Sub
Private Sub txtBugDescription_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles txtBugDescription.Leave
Me.AcceptButton = btnSubmit
End Sub
Private Sub sender_DoWork() Handles bgwSender.DoWork
m_errorOccured = False
Try
Dim reader As New StreamReader((New WebClient).OpenRead(Me.SubmitterPath & "/" & Me.SubmitterFile & m_parameters))
Catch ex As Exception
m_errorOccured = True
MessageBox.Show(ex.ToString)
End Try
End Sub
Private Sub sender_RunWorkerCompleted() Handles bgwSender.RunWorkerCompleted
Me.Cursor = Cursors.Default
If m_errorOccured Then showError() Else showCompleted()
End Sub
Private Sub showSubmitting()
Me.Cursor = Cursors.WaitCursor
toggleInteractionControls(False)
lblHeaderStatus.Text = "Submitting the report"
btnSubmit.Text = "Submitting..."
End Sub
Private Sub showCompleted()
txtBugDescription.Visible = False
txtUserEmail.Visible = False
cbxBugType.Visible = False
lblBugDesc.Visible = False
lblBugType.Visible = False
lblUserEmail.Visible = False
lblCompleted.Visible = True
lblHeaderStatus.Text = "Submittion complete"
btnSubmit.Enabled = True
btnSubmit.Text = "&Finish"
End Sub
Private Sub showError()
MessageBox.Show("Unable to connect to the submission server. Please try again later.", "Submission error")
toggleInteractionControls(True)
btnSubmit.Text = "&Submit report"
End Sub
Private Sub toggleInteractionControls(ByVal enable As Boolean)
btnSubmit.Enabled = enable
btnCancel.Enabled = enable
txtBugDescription.ReadOnly = Not enable
txtUserEmail.ReadOnly = Not enable
cbxBugType.Enabled = enable
End Sub
''' <summary>Form overrides dispose to clean up the component list.</summary>
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
bgwSender.Dispose()
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
#End Region
#Region "Properties"
''' <summary>Gets or sets the path to the file containing update info</summary>
Public Property SubmitterPath() As String
Get
Return m_submitter_path
End Get
Set(ByVal value As String)
If m_submitter_path <> value Then
m_submitter_path = value
RaiseEvent SubmitterPathChanged(Me, New EventArgs)
End If
End Set
End Property
''' <summary>Gets or sets the name of the file containing update info</summary>
Public Property SubmitterFile() As String
Get
Return m_submitter_file
End Get
Set(ByVal value As String)
If m_submitter_file <> value Then
m_submitter_file = value
RaiseEvent SubmitterFileChanged(Me, New EventArgs)
End If
End Set
End Property
''' <summary>Gets or sets the version of the application. This data will be included in the error report</summary>
Public Property ApplicationVersion() As String
Get
Return m_app_version
End Get
Set(ByVal value As String)
m_app_version = value
End Set
End Property
''' <summary>Gets or sets if an error provider should be used to notify a user of errors. When false, live validation will only enable the submit button when all fields are valid</summary>
Public Property UseErrorProvider() As Boolean
Get
Return m_useErrorProvider
End Get
Set(ByVal value As Boolean)
m_useErrorProvider = value
End Set
End Property
''' <summary>Gets or sets the minimum length of the report text</summary>
Public Property MinimumReportLength() As Int32
Get
Return m_minRepLength
End Get
Set(ByVal value As Int32)
m_minRepLength = value
End Set
End Property
''' <summary>Gets or sets the maximum length of the report text</summary>
Public Property MaximumReportLength() As Int32
Get
Return txtBugDescription.MaxLength
End Get
Set(ByVal value As Int32)
txtBugDescription.MaxLength = value
End Set
End Property
''' <summary>Gets the report text</summary>
Private ReadOnly Property ReportText() As String
Get
Return txtBugDescription.Text.Trim
End Get
End Property
''' <summary>Gets if the entered email is valid</summary>
Private ReadOnly Property EmailIsValid() As Boolean
Get
Dim pattern As String = "^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$"
Return System.Text.RegularExpressions.Regex.Match(txtUserEmail.Text, pattern).Success Or txtUserEmail.Text.Length < 1
End Get
End Property
''' <summary>Gets if the length of the repport suffies</summary>
Private ReadOnly Property ReportLengthSuffies() As Boolean
Get
Return Me.ReportText.Length >= Me.MinimumReportLength
End Get
End Property
''' <summary>Gets if the submit button is enabled</summary>
Private ReadOnly Property SubmitIsEnabled() As Boolean
Get
Return cbxBugType.SelectedIndex > 0 And (Me.UseErrorProvider Or (Me.ReportLengthSuffies And Me.EmailIsValid))
End Get
End Property
#End Region
#Region "Designer"
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.tlpButtons = New System.Windows.Forms.TableLayoutPanel
Me.btnSubmit = New System.Windows.Forms.Button
Me.btnCancel = New System.Windows.Forms.Button
Me.cbxBugType = New System.Windows.Forms.ComboBox
Me.txtBugDescription = New System.Windows.Forms.RichTextBox
Me.txtUserEmail = New System.Windows.Forms.TextBox
Me.lblBugType = New System.Windows.Forms.Label
Me.lblBugDesc = New System.Windows.Forms.Label
Me.lblUserEmail = New System.Windows.Forms.Label
Me.lblHeaderStatus = New System.Windows.Forms.Label
Me.epReport = New System.Windows.Forms.ErrorProvider(Me.components)
Me.lblCompleted = New System.Windows.Forms.Label
Me.tlpButtons.SuspendLayout()
CType(Me.epReport, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'tlpButtons
'
Me.tlpButtons.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.tlpButtons.ColumnCount = 2
Me.tlpButtons.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 56.49717!))
Me.tlpButtons.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 43.50283!))
Me.tlpButtons.Controls.Add(Me.btnSubmit, 0, 0)
Me.tlpButtons.Controls.Add(Me.btnCancel, 1, 0)
Me.tlpButtons.Location = New System.Drawing.Point(233, 273)
Me.tlpButtons.Name = "tlpButtons"
Me.tlpButtons.RowCount = 1
Me.tlpButtons.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.tlpButtons.Size = New System.Drawing.Size(177, 29)
Me.tlpButtons.TabIndex = 0
'
'btnSubmit
'
Me.btnSubmit.Anchor = System.Windows.Forms.AnchorStyles.None
Me.btnSubmit.Enabled = False
Me.btnSubmit.Location = New System.Drawing.Point(3, 3)
Me.btnSubmit.Name = "btnSubmit"
Me.btnSubmit.Size = New System.Drawing.Size(93, 23)
Me.btnSubmit.TabIndex = 0
Me.btnSubmit.Text = "&Submit report"
'
'btnCancel
'
Me.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.None
Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.btnCancel.Location = New System.Drawing.Point(104, 3)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(67, 23)
Me.btnCancel.TabIndex = 1
Me.btnCancel.Text = "&Cancel"
'
'cbxBugType
'
Me.cbxBugType.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.cbxBugType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cbxBugType.FormattingEnabled = True
Me.cbxBugType.Items.AddRange(New Object() {"Select one...", "Application crash", "Wrong data/results displayed", "Typo or layout error", "Application freeze", "Wrong behaviour", "Other problem"})
Me.cbxBugType.Location = New System.Drawing.Point(127, 60)
Me.cbxBugType.Name = "cbxBugType"
Me.cbxBugType.Size = New System.Drawing.Size(240, 21)
Me.cbxBugType.TabIndex = 1
'
'txtBugDescription
'
Me.txtBugDescription.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.txtBugDescription.BackColor = System.Drawing.SystemColors.Window
Me.txtBugDescription.Location = New System.Drawing.Point(127, 87)
Me.txtBugDescription.Name = "txtBugDescription"
Me.txtBugDescription.Size = New System.Drawing.Size(240, 96)
Me.txtBugDescription.TabIndex = 2
Me.txtBugDescription.Text = ""
'
'txtUserEmail
'
Me.txtUserEmail.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.txtUserEmail.Location = New System.Drawing.Point(127, 189)
Me.txtUserEmail.Name = "txtUserEmail"
Me.txtUserEmail.Size = New System.Drawing.Size(240, 20)
Me.txtUserEmail.TabIndex = 3
'
'lblBugType
'
Me.lblBugType.AutoSize = True
Me.lblBugType.Location = New System.Drawing.Point(38, 63)
Me.lblBugType.Name = "lblBugType"
Me.lblBugType.Size = New System.Drawing.Size(52, 13)
Me.lblBugType.TabIndex = 4
Me.lblBugType.Text = "Bug type:"
'
'lblBugDesc
'
Me.lblBugDesc.AutoSize = True
Me.lblBugDesc.Location = New System.Drawing.Point(38, 90)
Me.lblBugDesc.Name = "lblBugDesc"
Me.lblBugDesc.Size = New System.Drawing.Size(83, 13)
Me.lblBugDesc.TabIndex = 5
Me.lblBugDesc.Text = "Bug description:"
'
'lblUserEmail
'
Me.lblUserEmail.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.lblUserEmail.AutoSize = True
Me.lblUserEmail.Location = New System.Drawing.Point(38, 192)
Me.lblUserEmail.Name = "lblUserEmail"
Me.lblUserEmail.Size = New System.Drawing.Size(84, 13)
Me.lblUserEmail.TabIndex = 6
Me.lblUserEmail.Text = "E-mail (optional):"
'
'lblHeaderStatus
'
Me.lblHeaderStatus.BackColor = System.Drawing.SystemColors.ControlLightLight
Me.lblHeaderStatus.Dock = System.Windows.Forms.DockStyle.Top
Me.lblHeaderStatus.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.lblHeaderStatus.Location = New System.Drawing.Point(0, 0)
Me.lblHeaderStatus.Name = "lblHeaderStatus"
Me.lblHeaderStatus.Padding = New System.Windows.Forms.Padding(3, 0, 0, 0)
Me.lblHeaderStatus.Size = New System.Drawing.Size(422, 29)
Me.lblHeaderStatus.TabIndex = 7
Me.lblHeaderStatus.Text = "Creating a bug report"
Me.lblHeaderStatus.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'epReport
'
Me.epReport.ContainerControl = Me
'
'lblCompleted
'
Me.lblCompleted.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.lblCompleted.Location = New System.Drawing.Point(0, 31)
Me.lblCompleted.Name = "lblCompleted"
Me.lblCompleted.Size = New System.Drawing.Size(422, 206)
Me.lblCompleted.TabIndex = 8
Me.lblCompleted.Text = "Thank you for submitting your report." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "The submitted information will be reviewed" & _
" and used to improve this application."
Me.lblCompleted.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.lblCompleted.Visible = False
'
'BugSubmitter
'
Me.AcceptButton = Me.btnSubmit
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.btnCancel
Me.ClientSize = New System.Drawing.Size(422, 314)
Me.Controls.Add(Me.lblHeaderStatus)
Me.Controls.Add(Me.lblUserEmail)
Me.Controls.Add(Me.lblBugDesc)
Me.Controls.Add(Me.lblBugType)
Me.Controls.Add(Me.txtUserEmail)
Me.Controls.Add(Me.txtBugDescription)
Me.Controls.Add(Me.cbxBugType)
Me.Controls.Add(Me.tlpButtons)
Me.Controls.Add(Me.lblCompleted)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "BugSubmitter"
Me.ShowInTaskbar = False
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
Me.Text = "Report a bug"
Me.tlpButtons.ResumeLayout(False)
CType(Me.epReport, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Private WithEvents tlpButtons As System.Windows.Forms.TableLayoutPanel
Private WithEvents btnSubmit As System.Windows.Forms.Button
Private WithEvents btnCancel As System.Windows.Forms.Button
Private WithEvents cbxBugType As System.Windows.Forms.ComboBox
Private WithEvents txtBugDescription As System.Windows.Forms.RichTextBox
Private WithEvents txtUserEmail As System.Windows.Forms.TextBox
Private WithEvents lblBugType As System.Windows.Forms.Label
Private WithEvents lblBugDesc As System.Windows.Forms.Label
Private WithEvents lblUserEmail As System.Windows.Forms.Label
Private WithEvents lblHeaderStatus As System.Windows.Forms.Label
Private WithEvents lblCompleted As System.Windows.Forms.Label
Private WithEvents epReport As System.Windows.Forms.ErrorProvider
#End Region
End Class
#End Region
End Namespace