sysperfana/heapanalyser/UI/UIs/Graphical/Wizard/HASetupWizard.cs
changeset 8 15296fd0af4a
equal deleted inserted replaced
7:8e12a575a9b5 8:15296fd0af4a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * Redistribution and use in source and binary forms, with or without
       
     6 * modification, are permitted provided that the following conditions are met:
       
     7 *
       
     8 * - Redistributions of source code must retain the above copyright notice,
       
     9 *   this list of conditions and the following disclaimer.
       
    10 * - Redistributions in binary form must reproduce the above copyright notice,
       
    11 *   this list of conditions and the following disclaimer in the documentation
       
    12 *   and/or other materials provided with the distribution.
       
    13 * - Neither the name of Nokia Corporation nor the names of its contributors
       
    14 *   may be used to endorse or promote products derived from this software
       
    15 *   without specific prior written permission.
       
    16 *
       
    17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
       
    18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
       
    21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    27 * POSSIBILITY OF SUCH DAMAGE.
       
    28 * 
       
    29 * Initial Contributors:
       
    30 * Nokia Corporation - initial contribution.
       
    31 *
       
    32 * Contributors:
       
    33 *
       
    34 * Description: 
       
    35 *
       
    36 */
       
    37 
       
    38 using System;
       
    39 using System.IO;
       
    40 using System.Drawing;
       
    41 using System.Collections;
       
    42 using System.Collections.Generic;
       
    43 using System.ComponentModel;
       
    44 using System.Windows.Forms;
       
    45 using System.Data;
       
    46 using System.Management;
       
    47 using System.Text;
       
    48 using SymbianUtils.Settings;
       
    49 using SymbianUtilsUi.Dialogs;
       
    50 using HeapAnalyser.Engine;
       
    51 using HeapAnalyser.Engine.Types;
       
    52 using HeapLib;
       
    53 using HeapLib.Constants;
       
    54 using HeapLib.Reconstructor;
       
    55 using HeapLib.Reconstructor.Misc;
       
    56 using HeapLib.Reconstructor.DataSources;
       
    57 using HeapLib.Reconstructor.DataSources.Analyser;
       
    58 using HeapUiLib.Dialogs;
       
    59 using SymbianWizardLib.Engine;
       
    60 using SymbianWizardLib.GUI;
       
    61 using SymbianDebugLib.Engine;
       
    62 using SymbianDebugLibUi.Controls;
       
    63 
       
    64 namespace HeapAnalyser.UIs.Graphical.Wizard
       
    65 {
       
    66     public partial class HASetupWizard : Form
       
    67     {
       
    68 		#region Constructors & destructors
       
    69         public HASetupWizard( XmlSettings aSettings, HeapWizardEngine aEngine )
       
    70 		{
       
    71 			iSettings = aSettings;
       
    72 			iEngine = aEngine;
       
    73 			//
       
    74 			InitializeComponent();
       
    75 		}
       
    76 		#endregion
       
    77 
       
    78 		#region Form event handlers
       
    79         private void Form_Load( object sender, System.EventArgs e )
       
    80 		{
       
    81             // Set up version information
       
    82             iLbl_Version.Text = HeapLibConstants.Version + " " + HeapLibConstants.Copyright;
       
    83 			iSettings[ "Wizard", "DialogResult"] = DialogResult.None.ToString();
       
    84 			//
       
    85             Setup_OpType();
       
    86             //
       
    87             Setup_SourceData_LogFileName();
       
    88             Setup_SourceData_HeapDataComparison();
       
    89             Setup_SourceData_HeapCSVComparison();
       
    90             //
       
    91             Setup_Cmn_Symbolics();
       
    92             Setup_Cmn_Filters();
       
    93             //
       
    94             Setup_Output_Directory();
       
    95             Setup_Output_File();
       
    96 		}
       
    97 
       
    98 		private void Form_Closing( object sender, System.ComponentModel.CancelEventArgs e )
       
    99 		{
       
   100 			iSettings.Store();
       
   101 		}
       
   102 
       
   103         private void iWizard_WizardClosedFromAuxillary( SymWizardClosureEvent aEventArgs )
       
   104 		{
       
   105 			iSettings[ "Wizard", "DialogResult"] = DialogResult.Cancel.ToString();
       
   106 		}
       
   107 
       
   108         private void iWizard_WizardClosedFromFinish( SymWizardClosureEvent aEventArgs )
       
   109 		{
       
   110 			iSettings[ "Wizard", "DialogResult"] = DialogResult.OK.ToString();
       
   111 		}
       
   112 		#endregion
       
   113 
       
   114         #region Pages
       
   115 
       
   116         #region Page [Operation type]
       
   117         private void Setup_OpType()
       
   118 		{
       
   119 			string opType = iSettings[ "Wizard", "OperationType" ];
       
   120 
       
   121 			// Make sure something is selected
       
   122             if ( opType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps.ToString() )
       
   123             {
       
   124                 iPG1_RB_OpType_CompareHeapDump.Checked = true;
       
   125             }
       
   126             else if ( opType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapCSV.ToString() )
       
   127             {
       
   128                 iPG1_RB_OpType_CompareCSV.Checked = true;
       
   129             }
       
   130             else
       
   131             {
       
   132                 // Default
       
   133                 iPG1_RB_OpType_HeapViewer.Checked = true;
       
   134             }
       
   135         }
       
   136 
       
   137         private void iPG1_OpType_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   138 		{
       
   139 			if	( iPG1_RB_OpType_HeapViewer.Checked )
       
   140 			{
       
   141 				iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeAnalyseAndView;
       
   142                 aEventArgs.SuggestedNewPage = iPG_SourceData_Log;
       
   143 			}
       
   144             else if ( iPG1_RB_OpType_CompareHeapDump.Checked )
       
   145             {
       
   146                 iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps;
       
   147                 aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
       
   148             }
       
   149             else if ( iPG1_RB_OpType_CompareCSV.Checked )
       
   150 			{
       
   151 				iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeCompareHeapCSV;
       
   152                 aEventArgs.SuggestedNewPage = iPG_SourceData_CompareCSV;
       
   153             }
       
   154 
       
   155             Setup_Output_File_Dynamic();
       
   156             Setup_Output_Directory_Dynamic();
       
   157 
       
   158             iSettings[ "Wizard", "OperationType" ] = iEngine.OperationType.ToString();
       
   159 		}
       
   160 		#endregion
       
   161 
       
   162 		#region Page [SourceData - Log file name]
       
   163 		private void Setup_SourceData_LogFileName()
       
   164 		{
       
   165             iSettings.Load( "Wizard", iPG_SourceData_Log_FB );
       
   166 		}
       
   167 
       
   168         private void iPG_SourceData_Log_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   169 		{
       
   170             string logFileName = iPG_SourceData_Log_FB.EntityName;
       
   171 
       
   172             if ( !iPG_SourceData_Log_FB.IsValid )
       
   173             {
       
   174                 aEventArgs.SuggestedNewPage = iPG_SourceData_Log;
       
   175             }
       
   176             else
       
   177             {
       
   178                 iSettings.Save( "Wizard", iPG_SourceData_Log_FB );
       
   179                 //
       
   180                 iEngine.HeapDataOptions = new Options();
       
   181                 //
       
   182                 DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( logFileName );
       
   183                 SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG302_Combo_Filter );
       
   184 			
       
   185                 // Only allowed to continue if we found a valid source
       
   186                 if ( iPG302_Combo_Filter.Items.Count > 0 )
       
   187                 {
       
   188                     aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
       
   189                 }
       
   190                 else
       
   191                 {
       
   192                     aEventArgs.SuggestedNewPage = aEventArgs.CurrentPage;
       
   193                 }
       
   194 			}
       
   195 		}
       
   196 		#endregion
       
   197 
       
   198         #region Page [SourceData - Heap data comparison source files]
       
   199         private void Setup_SourceData_HeapDataComparison()
       
   200         {
       
   201             iSettings.Load( "Wizard", iPG202_TB_LogFile1 );
       
   202             iSettings.Load( "Wizard", iPG202_TB_LogFile2 );
       
   203 
       
   204             // Start off with the combo's disabled
       
   205             iPG202_Combo_ThreadName1.Enabled = false;
       
   206             iPG202_Combo_ThreadName2.Enabled = false;
       
   207 
       
   208             // We queue these up so that the scan occurs only after the page is actually displayed.
       
   209             this.iPG202_TB_LogFile1.FileSelectionChanged += new SymbianUtilsUi.Controls.SymbianFileControl.FileSelectionChangedHandler( this.iPG202_TB_LogFile1_FileSelectionChanged );
       
   210             this.iPG202_TB_LogFile2.FileSelectionChanged += new SymbianUtilsUi.Controls.SymbianFileControl.FileSelectionChangedHandler( this.iPG202_TB_LogFile2_FileSelectionChanged );
       
   211         }
       
   212 
       
   213         private void iPG202_TB_LogFile1_FileSelectionChanged( SymbianUtilsUi.Controls.SymbianFileControl aSelf, string aFileName )
       
   214         {
       
   215             DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( aFileName );
       
   216             SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG202_Combo_ThreadName1 );
       
   217 
       
   218             iPG_SourceData_CompareHeapData_GP_Log2.Enabled = ( iPG202_Combo_ThreadName1.Items.Count > 0 );
       
   219         }
       
   220 
       
   221         private void iPG202_TB_LogFile2_FileSelectionChanged( SymbianUtilsUi.Controls.SymbianFileControl aSelf, string aFileName )
       
   222         {
       
   223             DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( aFileName );
       
   224 
       
   225             // Get the master thread name
       
   226             string threadName = ThreadNameFromFilterCombo( iPG202_Combo_ThreadName1 );
       
   227             
       
   228             if ( threadName != string.Empty )
       
   229             {
       
   230             }
       
   231             else
       
   232             {
       
   233                 analyser.DataSources.Clear();
       
   234             }
       
   235 
       
   236             // Seed combobox with filter options
       
   237             SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG202_Combo_ThreadName2 );
       
   238         }
       
   239 
       
   240         private void iPG_SourceData_CompareHeapData_PageShownFromButtonNext( SymWizardPage aSender )
       
   241         {
       
   242             if ( iPG202_TB_LogFile1.EntityName != string.Empty && File.Exists( iPG202_TB_LogFile1.EntityName ) )
       
   243             {
       
   244                 iPG202_TB_LogFile1_FileSelectionChanged( iPG202_TB_LogFile1, iPG202_TB_LogFile1.EntityName );
       
   245             }
       
   246             if ( iPG202_TB_LogFile2.EntityName != string.Empty && File.Exists( iPG202_TB_LogFile2.EntityName ) )
       
   247             {
       
   248                 iPG202_TB_LogFile2_FileSelectionChanged( iPG202_TB_LogFile2, iPG202_TB_LogFile2.EntityName );
       
   249             }
       
   250         }
       
   251 
       
   252         private void iPG202_SourceData_Comparison_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   253         {
       
   254             iEngine.ComparisonEngineData.DataSource1 = DataSourceFromFilterCombo( iPG202_Combo_ThreadName1 );
       
   255             iEngine.ComparisonEngineData.DataSource2 = DataSourceFromFilterCombo( iPG202_Combo_ThreadName2 );
       
   256             //
       
   257             if ( !( iPG202_TB_LogFile1.IsValid && iPG202_TB_LogFile2.IsValid ) )
       
   258             {
       
   259                 aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
       
   260             }
       
   261             else if ( iEngine.ComparisonEngineData.DataSource1 == null )
       
   262             {
       
   263                 iPG202_TB_LogFile1.SetError( "Select a valid MemSpy heap data log" );
       
   264                 aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
       
   265             }
       
   266             else if ( iEngine.ComparisonEngineData.DataSource2 == null )
       
   267             {
       
   268                 iPG202_TB_LogFile2.SetError( "Select a valid MemSpy heap data log" );
       
   269                 aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
       
   270             }
       
   271             else
       
   272             {
       
   273                 // Get both data sources and check thread names are common
       
   274                 DataSource ds1 = (DataSource ) iPG202_Combo_ThreadName1.SelectedItem;
       
   275                 DataSource ds2 = (DataSource) iPG202_Combo_ThreadName2.SelectedItem;
       
   276                 //
       
   277                 if ( ds1.ThreadName.ToLower() != ds2.ThreadName.ToLower() )
       
   278                 {
       
   279                     aEventArgs.SuggestedNewPage = iPG_SourceData_CompareHeapData;
       
   280                     iErrorProvider.SetError( iPG202_Combo_ThreadName2, "Thread names differ" );
       
   281                 }
       
   282                 else
       
   283                 {
       
   284                     iSettings.Save( "Wizard", iPG202_TB_LogFile1 );
       
   285                     iSettings.Save( "Wizard", iPG202_TB_LogFile2 );
       
   286 
       
   287                     iErrorProvider.Clear();
       
   288                     aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
       
   289                 }
       
   290             }
       
   291         }
       
   292         #endregion
       
   293 
       
   294         #region Page [SourceData - Heap CSV comparison source files]
       
   295         private void Setup_SourceData_HeapCSVComparison()
       
   296         {
       
   297             iSettings.Load( "PG_SourceData_CompareCSV_Files", iPG_SourceData_CompareCSV_Files );
       
   298         }
       
   299 
       
   300         private void iPG_SourceData_CompareCSV_PageClosedFromButtonNext( SymWizardPageTransitionEvent aEventArgs )
       
   301         {
       
   302             // Check we have at least one valid file.
       
   303             if ( iPG_SourceData_CompareCSV_Files.FileNames.Count == 0 )
       
   304             {
       
   305                 aEventArgs.SuggestedNewPage = iPG_SourceData_CompareCSV;
       
   306             }
       
   307             else
       
   308             {
       
   309                 iSettings.Save( "PG_SourceData_CompareCSV_Files", iPG_SourceData_CompareCSV_Files );
       
   310                 iEngine.ComparisonEngineCSV.SourceFileNames = iPG_SourceData_CompareCSV_Files.FileNames;
       
   311                 aEventArgs.SuggestedNewPage = iPG_OutputToDirectory;
       
   312             }
       
   313         }
       
   314         #endregion
       
   315 
       
   316         #region Page [Cmn - Symbolics]
       
   317         private void Setup_Cmn_Symbolics()
       
   318 		{
       
   319             iPG301_DebugControl.Engine = iEngine.DebugEngine;
       
   320 		}
       
   321 
       
   322         private void iPG301_AnalysisSymbolics_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   323 		{
       
   324             string errorText = string.Empty;
       
   325             if ( iPG301_DebugControl.IsReadyToPrime( out errorText ) )
       
   326             {
       
   327                 iPG301_DebugControl.Prime();
       
   328 
       
   329                 if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
       
   330                 {
       
   331                     aEventArgs.SuggestedNewPage = iPG_OutputToFile;
       
   332                 }
       
   333                 else
       
   334                 {
       
   335                     // If there is only one thread available, then there's no point
       
   336                     // asking the user to pick it...
       
   337                     int number = 0;
       
   338                     bool okayToProceed = SetDataSourceFromFirstAvailableThread( out number );
       
   339                     if ( okayToProceed && number == 1 )
       
   340                     {
       
   341                         aEventArgs.SuggestedNewPage = iPG_Final;
       
   342                     }
       
   343                     else
       
   344                     {
       
   345                         aEventArgs.SuggestedNewPage = iPG_Cmn_Filters;
       
   346                     }
       
   347                 }
       
   348 
       
   349                 // Also save debug engine configuration
       
   350                 iPG301_DebugControl.XmlSettingsSave();
       
   351             }
       
   352             else
       
   353             {
       
   354                 MessageBox.Show( errorText, "Error" );
       
   355                 aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
       
   356             }
       
   357 		}
       
   358 		#endregion
       
   359 
       
   360         #region Page [Cmn - Heap thread filter]
       
   361         private void Setup_Cmn_Filters()
       
   362 		{
       
   363 		}
       
   364 
       
   365         private void iPG302_Cmn_Filters_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   366 		{
       
   367             if ( SetDataSourceFromFirstAvailableThread() )
       
   368             {
       
   369                 // Clear any error
       
   370                 iErrorProvider.SetError( iPG302_Combo_Filter, string.Empty );
       
   371 
       
   372                 // Decide where to go next...
       
   373                 aEventArgs.SuggestedNewPage = iPG_Final;
       
   374             }
       
   375             else
       
   376             {
       
   377                 iErrorProvider.SetError( iPG302_Combo_Filter, "No thread's were detected. Is the log corrupt?" );
       
   378                 aEventArgs.SuggestedNewPage = iPG_Cmn_Filters;
       
   379             }
       
   380 		}
       
   381 		#endregion
       
   382 
       
   383 		#region Page [Output - Directory]
       
   384         private void Setup_Output_Directory()
       
   385 		{
       
   386             iSettings.Load( "Wizard", iPG_OutputToDirectory_FB );
       
   387 		}
       
   388 
       
   389         private void Setup_Output_Directory_Dynamic()
       
   390         {
       
   391             iHeader_OutputToDirectory.Title = "Save CSV Comparsion Reports";
       
   392             iHeader_OutputToDirectory.Description += "Microsoft Excel comparison reports";
       
   393         }
       
   394 
       
   395         private void iPG_OutputToDirectory_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   396 		{
       
   397             if ( !iPG_OutputToDirectory_FB.IsValid )
       
   398             {
       
   399                 aEventArgs.SuggestedNewPage = iPG_OutputToDirectory;
       
   400             }
       
   401             else
       
   402             {
       
   403                 string dir = iPG_OutputToDirectory_FB.EntityName;
       
   404                 iEngine.ComparisonEngineCSV.OutputDirectory = dir;
       
   405                 iSettings.Save( "Wizard", iPG_OutputToDirectory_FB );
       
   406                 aEventArgs.SuggestedNewPage = iPG_Final;
       
   407             }
       
   408 		}
       
   409 		#endregion
       
   410 
       
   411         #region Page [Output - File]
       
   412         private void Setup_Output_File()
       
   413         {
       
   414             iSettings.Load( "Wizard", iPG_OutputToFile_FB );
       
   415         }
       
   416 
       
   417         private void Setup_Output_File_Dynamic()
       
   418         {
       
   419             if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
       
   420             {
       
   421                 iHeader_OutputToFile.Title = "Save Heap Dump Comparison to Microsoft Excel";
       
   422                 iHeader_OutputToFile.Description += "Microsoft Excel comparison report";
       
   423             }
       
   424         }
       
   425 
       
   426         private void iPG500_Comparison_Output_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
       
   427         {
       
   428             if ( iPG_OutputToFile_FB.IsValid )
       
   429             {
       
   430                 iSettings.Save( "Wizard", iPG_OutputToFile_FB );
       
   431                 //
       
   432                 if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
       
   433                 {
       
   434                     iEngine.ComparisonEngineData.OutputFileName = iPG_OutputToFile_FB.EntityName;
       
   435                 }
       
   436                 //
       
   437                 aEventArgs.SuggestedNewPage =  iPG_Final;
       
   438             }
       
   439             else
       
   440             {
       
   441                 aEventArgs.SuggestedNewPage =  iPG_OutputToFile;
       
   442             }
       
   443         }
       
   444         #endregion
       
   445 
       
   446         #endregion
       
   447 
       
   448         #region Internal methods
       
   449         private bool SetDataSourceFromFirstAvailableThread()
       
   450         {
       
   451             int number;
       
   452             return SetDataSourceFromFirstAvailableThread( out number );
       
   453         }
       
   454 
       
   455         private bool SetDataSourceFromFirstAvailableThread( out int aNumberOfDataSources )
       
   456         {
       
   457             bool okayToProceed = false;
       
   458 
       
   459             // Must be at least one thread selected
       
   460             DataSource dataSource = (DataSource) iPG302_Combo_Filter.SelectedItem;
       
   461             if ( dataSource == null || iPG302_Combo_Filter.Items.Count == 0 )
       
   462             {
       
   463                 // Can't do anything at this point... Let a later page
       
   464                 // handle this scenario.
       
   465                 aNumberOfDataSources = 0;
       
   466             }
       
   467             else
       
   468             {
       
   469                 aNumberOfDataSources = iPG302_Combo_Filter.Items.Count;
       
   470                 iEngine.AnalysisEngine.DataSource = dataSource;
       
   471                 
       
   472                 // Save setting for filter thread
       
   473                 iSettings[ "Wizard", iPG302_Combo_Filter.Name ] = iPG302_Combo_Filter.Text;
       
   474 
       
   475                 // Good to go
       
   476                 okayToProceed = true;
       
   477             }
       
   478 
       
   479             return okayToProceed;
       
   480         }
       
   481 
       
   482         private void SeedAnalysisFiltersAfterDataSourceScan( DataSourceCollection aSources, ComboBox aCombo )
       
   483         {
       
   484             // Thread filtering - seed with detected threads
       
   485             aCombo.BeginUpdate();
       
   486             aCombo.Items.Clear();
       
   487             foreach ( DataSource source in aSources )
       
   488             {
       
   489                 bool allowSource = true;
       
   490                 bool containsErrors = CheckSourceForErrors( source, out allowSource );
       
   491                 if ( !containsErrors || allowSource )
       
   492                 {
       
   493                     aCombo.Items.Add( source );
       
   494                 }
       
   495             }
       
   496 
       
   497             // Make sure something is selected
       
   498             if ( aCombo.Items.Count > 0 )
       
   499             {
       
   500                 iErrorProvider.SetError( aCombo, string.Empty );
       
   501 
       
   502                 int selectedThreadIndex = 0;
       
   503 
       
   504                 // If the user has picked a thread previously, try to select the same one
       
   505                 // again this time.
       
   506                 string lastSelectedThread = iSettings[ "Wizard", aCombo.Name ];
       
   507                 if ( lastSelectedThread.Length > 0 )
       
   508                 {
       
   509                     int index = aSources.IndexOf( lastSelectedThread );
       
   510                     if ( index >= 0 )
       
   511                     {
       
   512                         selectedThreadIndex = index;
       
   513                     }
       
   514                 }
       
   515 
       
   516                 // Now pick the thread...
       
   517                 aCombo.SelectedIndex = selectedThreadIndex;
       
   518             }
       
   519             else
       
   520             {
       
   521                 iErrorProvider.SetError( aCombo, "No thread's were detected. Is the log corrupt?" );
       
   522             }
       
   523 
       
   524             aCombo.Enabled = ( aCombo.Items.Count > 1 );
       
   525             aCombo.EndUpdate();
       
   526         }
       
   527 
       
   528         private bool CheckSourceForErrors( DataSource aSource, out bool aAllowSourceAnyway )
       
   529         {
       
   530             aAllowSourceAnyway = false;
       
   531             string description = string.Empty;
       
   532             //
       
   533             bool errorsDetected = aSource.ErrorsDetected( out description );
       
   534             if ( errorsDetected )
       
   535             {
       
   536                 StringBuilder msg = new StringBuilder();
       
   537                 msg.Append( "File: " + aSource.FileName );
       
   538                 msg.Append( System.Environment.NewLine );
       
   539                 msg.Append( "Thread: " + aSource.ThreadName );
       
   540                 msg.Append( System.Environment.NewLine );
       
   541                 msg.Append( System.Environment.NewLine );
       
   542                 msg.Append( description );
       
   543                 msg.Append( System.Environment.NewLine );
       
   544                 msg.Append( "You are recommended to save the heap data to zip and contact" );
       
   545                 msg.Append( "your support provider." );
       
   546                 msg.Append( System.Environment.NewLine );
       
   547                 msg.Append( System.Environment.NewLine );
       
   548                 msg.Append( "Do you want to allow this data anyway?" );
       
   549                 //
       
   550                 string title = string.Format( "Errors Detected - {0}", aSource.ThreadName );
       
   551                 DialogResult result = MessageBox.Show( msg.ToString(), title, MessageBoxButtons.YesNo );
       
   552                 aAllowSourceAnyway = ( result == DialogResult.Yes );
       
   553             }
       
   554             //
       
   555             return errorsDetected;
       
   556         }
       
   557 
       
   558         private static DataSource DataSourceFromFilterCombo( ComboBox aCombo )
       
   559         {
       
   560             DataSource ret = null;
       
   561             //
       
   562             int index = aCombo.SelectedIndex;
       
   563             if ( index >= 0 && index < aCombo.Items.Count )
       
   564             {
       
   565                 object obj = aCombo.Items[ index ];
       
   566                 if ( obj is DataSource )
       
   567                 {
       
   568                     ret = (DataSource) obj;
       
   569                 }
       
   570             }
       
   571             //
       
   572             return ret;
       
   573         }
       
   574 
       
   575         private static string ThreadNameFromFilterCombo( ComboBox aCombo )
       
   576         {
       
   577             string ret = string.Empty;
       
   578             //
       
   579             DataSource ds = DataSourceFromFilterCombo( aCombo );
       
   580             if ( ds != null )
       
   581             {
       
   582                 ret = ds.ThreadName;
       
   583             }
       
   584             //
       
   585             return ret;
       
   586         }
       
   587         #endregion
       
   588 
       
   589         #region Data members
       
   590         private readonly HeapWizardEngine iEngine;
       
   591 		private readonly XmlSettings iSettings;
       
   592 		#endregion
       
   593     }
       
   594 }