sysperfana/heapanalyser/UI/UIs/Graphical/Wizard/HASetupWizard.cs
changeset 8 15296fd0af4a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/heapanalyser/UI/UIs/Graphical/Wizard/HASetupWizard.cs	Tue Jun 15 12:47:20 2010 +0300
@@ -0,0 +1,594 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright notice,
+*   this list of conditions and the following disclaimer in the documentation
+*   and/or other materials provided with the distribution.
+* - Neither the name of Nokia Corporation nor the names of its contributors
+*   may be used to endorse or promote products derived from this software
+*   without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+* 
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+using System;
+using System.IO;
+using System.Drawing;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Data;
+using System.Management;
+using System.Text;
+using SymbianUtils.Settings;
+using SymbianUtilsUi.Dialogs;
+using HeapAnalyser.Engine;
+using HeapAnalyser.Engine.Types;
+using HeapLib;
+using HeapLib.Constants;
+using HeapLib.Reconstructor;
+using HeapLib.Reconstructor.Misc;
+using HeapLib.Reconstructor.DataSources;
+using HeapLib.Reconstructor.DataSources.Analyser;
+using HeapUiLib.Dialogs;
+using SymbianWizardLib.Engine;
+using SymbianWizardLib.GUI;
+using SymbianDebugLib.Engine;
+using SymbianDebugLibUi.Controls;
+
+namespace HeapAnalyser.UIs.Graphical.Wizard
+{
+    public partial class HASetupWizard : Form
+    {
+		#region Constructors & destructors
+        public HASetupWizard( XmlSettings aSettings, HeapWizardEngine aEngine )
+		{
+			iSettings = aSettings;
+			iEngine = aEngine;
+			//
+			InitializeComponent();
+		}
+		#endregion
+
+		#region Form event handlers
+        private void Form_Load( object sender, System.EventArgs e )
+		{
+            // Set up version information
+            iLbl_Version.Text = HeapLibConstants.Version + " " + HeapLibConstants.Copyright;
+			iSettings[ "Wizard", "DialogResult"] = DialogResult.None.ToString();
+			//
+            Setup_OpType();
+            //
+            Setup_SourceData_LogFileName();
+            Setup_SourceData_HeapDataComparison();
+            Setup_SourceData_HeapCSVComparison();
+            //
+            Setup_Cmn_Symbolics();
+            Setup_Cmn_Filters();
+            //
+            Setup_Output_Directory();
+            Setup_Output_File();
+		}
+
+		private void Form_Closing( object sender, System.ComponentModel.CancelEventArgs e )
+		{
+			iSettings.Store();
+		}
+
+        private void iWizard_WizardClosedFromAuxillary( SymWizardClosureEvent aEventArgs )
+		{
+			iSettings[ "Wizard", "DialogResult"] = DialogResult.Cancel.ToString();
+		}
+
+        private void iWizard_WizardClosedFromFinish( SymWizardClosureEvent aEventArgs )
+		{
+			iSettings[ "Wizard", "DialogResult"] = DialogResult.OK.ToString();
+		}
+		#endregion
+
+        #region Pages
+
+        #region Page [Operation type]
+        private void Setup_OpType()
+		{
+			string opType = iSettings[ "Wizard", "OperationType" ];
+
+			// Make sure something is selected
+            if ( opType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps.ToString() )
+            {
+                iPG1_RB_OpType_CompareHeapDump.Checked = true;
+            }
+            else if ( opType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapCSV.ToString() )
+            {
+                iPG1_RB_OpType_CompareCSV.Checked = true;
+            }
+            else
+            {
+                // Default
+                iPG1_RB_OpType_HeapViewer.Checked = true;
+            }
+        }
+
+        private void iPG1_OpType_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+		{
+			if	( iPG1_RB_OpType_HeapViewer.Checked )
+			{
+				iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeAnalyseAndView;
+                aEventArgs.SuggestedNewPage = iPG_SourceData_Log;
+			}
+            else if ( iPG1_RB_OpType_CompareHeapDump.Checked )
+            {
+                iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps;
+                aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
+            }
+            else if ( iPG1_RB_OpType_CompareCSV.Checked )
+			{
+				iEngine.OperationType = HeapWizardEngine.TOperationType.EOperationTypeCompareHeapCSV;
+                aEventArgs.SuggestedNewPage = iPG_SourceData_CompareCSV;
+            }
+
+            Setup_Output_File_Dynamic();
+            Setup_Output_Directory_Dynamic();
+
+            iSettings[ "Wizard", "OperationType" ] = iEngine.OperationType.ToString();
+		}
+		#endregion
+
+		#region Page [SourceData - Log file name]
+		private void Setup_SourceData_LogFileName()
+		{
+            iSettings.Load( "Wizard", iPG_SourceData_Log_FB );
+		}
+
+        private void iPG_SourceData_Log_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+		{
+            string logFileName = iPG_SourceData_Log_FB.EntityName;
+
+            if ( !iPG_SourceData_Log_FB.IsValid )
+            {
+                aEventArgs.SuggestedNewPage = iPG_SourceData_Log;
+            }
+            else
+            {
+                iSettings.Save( "Wizard", iPG_SourceData_Log_FB );
+                //
+                iEngine.HeapDataOptions = new Options();
+                //
+                DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( logFileName );
+                SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG302_Combo_Filter );
+			
+                // Only allowed to continue if we found a valid source
+                if ( iPG302_Combo_Filter.Items.Count > 0 )
+                {
+                    aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
+                }
+                else
+                {
+                    aEventArgs.SuggestedNewPage = aEventArgs.CurrentPage;
+                }
+			}
+		}
+		#endregion
+
+        #region Page [SourceData - Heap data comparison source files]
+        private void Setup_SourceData_HeapDataComparison()
+        {
+            iSettings.Load( "Wizard", iPG202_TB_LogFile1 );
+            iSettings.Load( "Wizard", iPG202_TB_LogFile2 );
+
+            // Start off with the combo's disabled
+            iPG202_Combo_ThreadName1.Enabled = false;
+            iPG202_Combo_ThreadName2.Enabled = false;
+
+            // We queue these up so that the scan occurs only after the page is actually displayed.
+            this.iPG202_TB_LogFile1.FileSelectionChanged += new SymbianUtilsUi.Controls.SymbianFileControl.FileSelectionChangedHandler( this.iPG202_TB_LogFile1_FileSelectionChanged );
+            this.iPG202_TB_LogFile2.FileSelectionChanged += new SymbianUtilsUi.Controls.SymbianFileControl.FileSelectionChangedHandler( this.iPG202_TB_LogFile2_FileSelectionChanged );
+        }
+
+        private void iPG202_TB_LogFile1_FileSelectionChanged( SymbianUtilsUi.Controls.SymbianFileControl aSelf, string aFileName )
+        {
+            DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( aFileName );
+            SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG202_Combo_ThreadName1 );
+
+            iPG_SourceData_CompareHeapData_GP_Log2.Enabled = ( iPG202_Combo_ThreadName1.Items.Count > 0 );
+        }
+
+        private void iPG202_TB_LogFile2_FileSelectionChanged( SymbianUtilsUi.Controls.SymbianFileControl aSelf, string aFileName )
+        {
+            DataSourceAnalyser analyser = HeapReconstructorDataSourceAnalyserDialog.Analyse( aFileName );
+
+            // Get the master thread name
+            string threadName = ThreadNameFromFilterCombo( iPG202_Combo_ThreadName1 );
+            
+            if ( threadName != string.Empty )
+            {
+            }
+            else
+            {
+                analyser.DataSources.Clear();
+            }
+
+            // Seed combobox with filter options
+            SeedAnalysisFiltersAfterDataSourceScan( analyser.DataSources, iPG202_Combo_ThreadName2 );
+        }
+
+        private void iPG_SourceData_CompareHeapData_PageShownFromButtonNext( SymWizardPage aSender )
+        {
+            if ( iPG202_TB_LogFile1.EntityName != string.Empty && File.Exists( iPG202_TB_LogFile1.EntityName ) )
+            {
+                iPG202_TB_LogFile1_FileSelectionChanged( iPG202_TB_LogFile1, iPG202_TB_LogFile1.EntityName );
+            }
+            if ( iPG202_TB_LogFile2.EntityName != string.Empty && File.Exists( iPG202_TB_LogFile2.EntityName ) )
+            {
+                iPG202_TB_LogFile2_FileSelectionChanged( iPG202_TB_LogFile2, iPG202_TB_LogFile2.EntityName );
+            }
+        }
+
+        private void iPG202_SourceData_Comparison_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+        {
+            iEngine.ComparisonEngineData.DataSource1 = DataSourceFromFilterCombo( iPG202_Combo_ThreadName1 );
+            iEngine.ComparisonEngineData.DataSource2 = DataSourceFromFilterCombo( iPG202_Combo_ThreadName2 );
+            //
+            if ( !( iPG202_TB_LogFile1.IsValid && iPG202_TB_LogFile2.IsValid ) )
+            {
+                aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
+            }
+            else if ( iEngine.ComparisonEngineData.DataSource1 == null )
+            {
+                iPG202_TB_LogFile1.SetError( "Select a valid MemSpy heap data log" );
+                aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
+            }
+            else if ( iEngine.ComparisonEngineData.DataSource2 == null )
+            {
+                iPG202_TB_LogFile2.SetError( "Select a valid MemSpy heap data log" );
+                aEventArgs.SuggestedNewPage =  iPG_SourceData_CompareHeapData;
+            }
+            else
+            {
+                // Get both data sources and check thread names are common
+                DataSource ds1 = (DataSource ) iPG202_Combo_ThreadName1.SelectedItem;
+                DataSource ds2 = (DataSource) iPG202_Combo_ThreadName2.SelectedItem;
+                //
+                if ( ds1.ThreadName.ToLower() != ds2.ThreadName.ToLower() )
+                {
+                    aEventArgs.SuggestedNewPage = iPG_SourceData_CompareHeapData;
+                    iErrorProvider.SetError( iPG202_Combo_ThreadName2, "Thread names differ" );
+                }
+                else
+                {
+                    iSettings.Save( "Wizard", iPG202_TB_LogFile1 );
+                    iSettings.Save( "Wizard", iPG202_TB_LogFile2 );
+
+                    iErrorProvider.Clear();
+                    aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
+                }
+            }
+        }
+        #endregion
+
+        #region Page [SourceData - Heap CSV comparison source files]
+        private void Setup_SourceData_HeapCSVComparison()
+        {
+            iSettings.Load( "PG_SourceData_CompareCSV_Files", iPG_SourceData_CompareCSV_Files );
+        }
+
+        private void iPG_SourceData_CompareCSV_PageClosedFromButtonNext( SymWizardPageTransitionEvent aEventArgs )
+        {
+            // Check we have at least one valid file.
+            if ( iPG_SourceData_CompareCSV_Files.FileNames.Count == 0 )
+            {
+                aEventArgs.SuggestedNewPage = iPG_SourceData_CompareCSV;
+            }
+            else
+            {
+                iSettings.Save( "PG_SourceData_CompareCSV_Files", iPG_SourceData_CompareCSV_Files );
+                iEngine.ComparisonEngineCSV.SourceFileNames = iPG_SourceData_CompareCSV_Files.FileNames;
+                aEventArgs.SuggestedNewPage = iPG_OutputToDirectory;
+            }
+        }
+        #endregion
+
+        #region Page [Cmn - Symbolics]
+        private void Setup_Cmn_Symbolics()
+		{
+            iPG301_DebugControl.Engine = iEngine.DebugEngine;
+		}
+
+        private void iPG301_AnalysisSymbolics_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+		{
+            string errorText = string.Empty;
+            if ( iPG301_DebugControl.IsReadyToPrime( out errorText ) )
+            {
+                iPG301_DebugControl.Prime();
+
+                if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
+                {
+                    aEventArgs.SuggestedNewPage = iPG_OutputToFile;
+                }
+                else
+                {
+                    // If there is only one thread available, then there's no point
+                    // asking the user to pick it...
+                    int number = 0;
+                    bool okayToProceed = SetDataSourceFromFirstAvailableThread( out number );
+                    if ( okayToProceed && number == 1 )
+                    {
+                        aEventArgs.SuggestedNewPage = iPG_Final;
+                    }
+                    else
+                    {
+                        aEventArgs.SuggestedNewPage = iPG_Cmn_Filters;
+                    }
+                }
+
+                // Also save debug engine configuration
+                iPG301_DebugControl.XmlSettingsSave();
+            }
+            else
+            {
+                MessageBox.Show( errorText, "Error" );
+                aEventArgs.SuggestedNewPage = iPG_Cmn_Symbolics;
+            }
+		}
+		#endregion
+
+        #region Page [Cmn - Heap thread filter]
+        private void Setup_Cmn_Filters()
+		{
+		}
+
+        private void iPG302_Cmn_Filters_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+		{
+            if ( SetDataSourceFromFirstAvailableThread() )
+            {
+                // Clear any error
+                iErrorProvider.SetError( iPG302_Combo_Filter, string.Empty );
+
+                // Decide where to go next...
+                aEventArgs.SuggestedNewPage = iPG_Final;
+            }
+            else
+            {
+                iErrorProvider.SetError( iPG302_Combo_Filter, "No thread's were detected. Is the log corrupt?" );
+                aEventArgs.SuggestedNewPage = iPG_Cmn_Filters;
+            }
+		}
+		#endregion
+
+		#region Page [Output - Directory]
+        private void Setup_Output_Directory()
+		{
+            iSettings.Load( "Wizard", iPG_OutputToDirectory_FB );
+		}
+
+        private void Setup_Output_Directory_Dynamic()
+        {
+            iHeader_OutputToDirectory.Title = "Save CSV Comparsion Reports";
+            iHeader_OutputToDirectory.Description += "Microsoft Excel comparison reports";
+        }
+
+        private void iPG_OutputToDirectory_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+		{
+            if ( !iPG_OutputToDirectory_FB.IsValid )
+            {
+                aEventArgs.SuggestedNewPage = iPG_OutputToDirectory;
+            }
+            else
+            {
+                string dir = iPG_OutputToDirectory_FB.EntityName;
+                iEngine.ComparisonEngineCSV.OutputDirectory = dir;
+                iSettings.Save( "Wizard", iPG_OutputToDirectory_FB );
+                aEventArgs.SuggestedNewPage = iPG_Final;
+            }
+		}
+		#endregion
+
+        #region Page [Output - File]
+        private void Setup_Output_File()
+        {
+            iSettings.Load( "Wizard", iPG_OutputToFile_FB );
+        }
+
+        private void Setup_Output_File_Dynamic()
+        {
+            if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
+            {
+                iHeader_OutputToFile.Title = "Save Heap Dump Comparison to Microsoft Excel";
+                iHeader_OutputToFile.Description += "Microsoft Excel comparison report";
+            }
+        }
+
+        private void iPG500_Comparison_Output_CloseFromNext( SymWizardPageTransitionEvent aEventArgs )
+        {
+            if ( iPG_OutputToFile_FB.IsValid )
+            {
+                iSettings.Save( "Wizard", iPG_OutputToFile_FB );
+                //
+                if ( iEngine.OperationType == HeapWizardEngine.TOperationType.EOperationTypeCompareHeapDumps )
+                {
+                    iEngine.ComparisonEngineData.OutputFileName = iPG_OutputToFile_FB.EntityName;
+                }
+                //
+                aEventArgs.SuggestedNewPage =  iPG_Final;
+            }
+            else
+            {
+                aEventArgs.SuggestedNewPage =  iPG_OutputToFile;
+            }
+        }
+        #endregion
+
+        #endregion
+
+        #region Internal methods
+        private bool SetDataSourceFromFirstAvailableThread()
+        {
+            int number;
+            return SetDataSourceFromFirstAvailableThread( out number );
+        }
+
+        private bool SetDataSourceFromFirstAvailableThread( out int aNumberOfDataSources )
+        {
+            bool okayToProceed = false;
+
+            // Must be at least one thread selected
+            DataSource dataSource = (DataSource) iPG302_Combo_Filter.SelectedItem;
+            if ( dataSource == null || iPG302_Combo_Filter.Items.Count == 0 )
+            {
+                // Can't do anything at this point... Let a later page
+                // handle this scenario.
+                aNumberOfDataSources = 0;
+            }
+            else
+            {
+                aNumberOfDataSources = iPG302_Combo_Filter.Items.Count;
+                iEngine.AnalysisEngine.DataSource = dataSource;
+                
+                // Save setting for filter thread
+                iSettings[ "Wizard", iPG302_Combo_Filter.Name ] = iPG302_Combo_Filter.Text;
+
+                // Good to go
+                okayToProceed = true;
+            }
+
+            return okayToProceed;
+        }
+
+        private void SeedAnalysisFiltersAfterDataSourceScan( DataSourceCollection aSources, ComboBox aCombo )
+        {
+            // Thread filtering - seed with detected threads
+            aCombo.BeginUpdate();
+            aCombo.Items.Clear();
+            foreach ( DataSource source in aSources )
+            {
+                bool allowSource = true;
+                bool containsErrors = CheckSourceForErrors( source, out allowSource );
+                if ( !containsErrors || allowSource )
+                {
+                    aCombo.Items.Add( source );
+                }
+            }
+
+            // Make sure something is selected
+            if ( aCombo.Items.Count > 0 )
+            {
+                iErrorProvider.SetError( aCombo, string.Empty );
+
+                int selectedThreadIndex = 0;
+
+                // If the user has picked a thread previously, try to select the same one
+                // again this time.
+                string lastSelectedThread = iSettings[ "Wizard", aCombo.Name ];
+                if ( lastSelectedThread.Length > 0 )
+                {
+                    int index = aSources.IndexOf( lastSelectedThread );
+                    if ( index >= 0 )
+                    {
+                        selectedThreadIndex = index;
+                    }
+                }
+
+                // Now pick the thread...
+                aCombo.SelectedIndex = selectedThreadIndex;
+            }
+            else
+            {
+                iErrorProvider.SetError( aCombo, "No thread's were detected. Is the log corrupt?" );
+            }
+
+            aCombo.Enabled = ( aCombo.Items.Count > 1 );
+            aCombo.EndUpdate();
+        }
+
+        private bool CheckSourceForErrors( DataSource aSource, out bool aAllowSourceAnyway )
+        {
+            aAllowSourceAnyway = false;
+            string description = string.Empty;
+            //
+            bool errorsDetected = aSource.ErrorsDetected( out description );
+            if ( errorsDetected )
+            {
+                StringBuilder msg = new StringBuilder();
+                msg.Append( "File: " + aSource.FileName );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( "Thread: " + aSource.ThreadName );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( description );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( "You are recommended to save the heap data to zip and contact" );
+                msg.Append( "your support provider." );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( System.Environment.NewLine );
+                msg.Append( "Do you want to allow this data anyway?" );
+                //
+                string title = string.Format( "Errors Detected - {0}", aSource.ThreadName );
+                DialogResult result = MessageBox.Show( msg.ToString(), title, MessageBoxButtons.YesNo );
+                aAllowSourceAnyway = ( result == DialogResult.Yes );
+            }
+            //
+            return errorsDetected;
+        }
+
+        private static DataSource DataSourceFromFilterCombo( ComboBox aCombo )
+        {
+            DataSource ret = null;
+            //
+            int index = aCombo.SelectedIndex;
+            if ( index >= 0 && index < aCombo.Items.Count )
+            {
+                object obj = aCombo.Items[ index ];
+                if ( obj is DataSource )
+                {
+                    ret = (DataSource) obj;
+                }
+            }
+            //
+            return ret;
+        }
+
+        private static string ThreadNameFromFilterCombo( ComboBox aCombo )
+        {
+            string ret = string.Empty;
+            //
+            DataSource ds = DataSourceFromFilterCombo( aCombo );
+            if ( ds != null )
+            {
+                ret = ds.ThreadName;
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region Data members
+        private readonly HeapWizardEngine iEngine;
+		private readonly XmlSettings iSettings;
+		#endregion
+    }
+}