diff -r e11368ed4880 -r 4f2773374eff memspyui/ui/avkon/src/MemSpyViewProcesses.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspyui/ui/avkon/src/MemSpyViewProcesses.cpp Fri May 14 15:53:02 2010 +0300 @@ -0,0 +1,704 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "MemSpyViewProcesses.h" + +// System includes +#include +#include +#include + +// Engine includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// User includes +#include "MemSpyViewThreads.h" +#include "MemSpyViewMainMenu.h" +#include "MemSpyContainerObserver.h" + +// Constants +const TInt KMemSpyMaxSearchTextLength = 30; +const TInt KMemSpyMaxSearchTextLengthWithWildcards = KMemSpyMaxSearchTextLength + 4; + + +/* +CMemSpyViewProcesses::CMemSpyViewProcesses( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver ) +: CMemSpyViewBase( aEngine, aObserver ) + { + } + + +CMemSpyViewProcesses::CMemSpyViewProcesses( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver, CMemSpyProcess& aProcess ) +: CMemSpyViewBase( aEngine, aObserver ), iCurrentProcess( &aProcess ) + { + iCurrentProcess->Open(); + } +*/ + +CMemSpyViewProcesses::CMemSpyViewProcesses( RMemSpySession& aSession, MMemSpyViewObserver& aObserver ) +: CMemSpyViewBase( aSession, aObserver ) + { + } + +/* +CMemSpyViewProcesses::CMemSpyViewProcesses( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver, CMemSpyProcess& aProcess ) +: CMemSpyViewBase( aEngine, aObserver ), iCurrentProcess( &aProcess ) + { + iCurrentProcess->Open(); + } +*/ + +CMemSpyViewProcesses::CMemSpyViewProcesses( RMemSpySession& aEngine, MMemSpyViewObserver& aObserver, TProcessId aId ) +: CMemSpyViewBase( aEngine, aObserver ), iCurrentProcessId( aId ) + { + } + +CMemSpyViewProcesses::~CMemSpyViewProcesses() + { + iProcesses.Close(); + delete iSearchField; + delete iMatcherBuffer; + } + + +//void CMemSpyViewProcesses::ConstructL( const TRect& aRect, CCoeControl& aContainer, TAny* aSelectionRune ) +void CMemSpyViewProcesses::ConstructL( const TRect& aRect, CCoeControl& aContainer, TProcessId aSelectionRune ) + { + iMemSpySession.GetProcessesL(iProcesses); // get processes array; + + _LIT( KTitle, "Processes\n& Threads" ); + SetTitleL( KTitle ); + // + //CMemSpyViewBase::ConstructL( aRect, aContainer, aSelectionRune ); + CMemSpyViewBase::ConstructL( aRect, aContainer ); + // + iMatcherBuffer = HBufC::NewL( KMemSpyMaxSearchTextLengthWithWildcards ); + // + iSearchField = CAknSearchField::NewL( *this, CAknSearchField::ESearch, NULL, KMemSpyMaxSearchTextLength ); + iSearchField->SetObserver( this ); + iSearchField->SetFocus( ETrue ); + iSearchField->SetComponentsToInheritVisibility( ETrue ); + // + if ( aSelectionRune ) + { + TInt index = 0; + TProcessId selectedItem = aSelectionRune; //static_cast< TProcessId >( *aSelectionRune ); + for( TInt i=0; iId() == selectedItem ) + { + index = i; + } + } + + if ( index >= 0 && index < iListBox->Model()->NumberOfItems() ) + { + iListBox->SetCurrentItemIndex( index ); + HandleListBoxItemSelectedL( index ); + } + } + else if ( iProcesses.Count() > 0 ) //TODO: to solve item selection when come back from previous view + { + iListBox->SetCurrentItemIndex( 0 ); + HandleListBoxItemSelectedL( 0 ); + } + // + SizeChanged(); + ActivateL(); + } + + +CMemSpyProcess& CMemSpyViewProcesses::CurrentProcess() const + { + /* + __ASSERT_ALWAYS( iCurrentProcess != NULL, User::Invariant() ); + return *iCurrentProcess; + */ + } + + +void CMemSpyViewProcesses::RefreshL() + { + SetListBoxModelL(); + CMemSpyViewBase::RefreshL(); + } + + +TMemSpyViewType CMemSpyViewProcesses::ViewType() const + { + return EMemSpyViewTypeProcesses; + } + + +CMemSpyViewBase* CMemSpyViewProcesses::PrepareParentViewL() + { + CMemSpyViewMainMenu* parent = new(ELeave) CMemSpyViewMainMenu( iMemSpySession, iObserver ); + CleanupStack::PushL( parent ); + parent->ConstructL( Rect(), *Parent(), (TAny*) ViewType() ); + CleanupStack::Pop( parent ); + return parent; + } + + +CMemSpyViewBase* CMemSpyViewProcesses::PrepareChildViewL() + { + CMemSpyViewThreads* child = new(ELeave) CMemSpyViewThreads( iMemSpySession, iObserver, iProcesses[iListBox->CurrentItemIndex()]->Id() ); + CleanupStack::PushL( child ); + child->ConstructL( Rect(), *Parent() ); + CleanupStack::Pop( child ); + return child; + + return 0; + } + + +void CMemSpyViewProcesses::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ) + { + if ( aResourceId == MenuCascadeResourceId() ) + { + CMemSpyProcess& process = CurrentProcess(); + //const TBool hide = ( iEngine.Container().Count() == 0 ) || process.IsDead(); //TODO + // + const TBool hide = EFalse; //to replace + + aMenuPane->SetItemDimmed( EMemSpyCmdProcessInfo, hide ); + aMenuPane->SetItemDimmed( EMemSpyCmdProcessEnd, hide ); + } + } + + +TBool CMemSpyViewProcesses::HandleCommandL( TInt aCommand ) + { + TBool handled = ETrue; + // + switch ( aCommand ) + { + // Sorting + case EMemSpyCmdProcessSortById: + OnCmdSortByIdL(); + break; + case EMemSpyCmdProcessSortByName: + OnCmdSortByNameL(); + break; + case EMemSpyCmdProcessSortByThreadCount: + OnCmdSortByThreadCountL(); + break; + case EMemSpyCmdProcessSortByCodeSegs: + OnCmdSortByCodeSegsL(); + break; + case EMemSpyCmdProcessSortByHeapUsage: + OnCmdSortByHeapUsageL(); + break; + case EMemSpyCmdProcessSortByStackUsage: + OnCmdSortByStackUsageL(); + break; + // End + case EMemSpyCmdProcessEndTerminate: + OnCmdEndTerminateL(); + break; + case EMemSpyCmdProcessEndKill: + OnCmdEndKillL(); + break; + case EMemSpyCmdProcessEndPanic: + OnCmdEndPanicL(); + break; + // Info + case EMemSpyCmdProcessInfoSummary: + OnCmdInfoSummaryL(); + break; + case EMemSpyCmdProcessInfoHandles: + OnCmdInfoHandlesL(); + break; + + default: + handled = CMemSpyViewBase::HandleCommandL( aCommand ); + break; + } + // + return handled; + } + + +void CMemSpyViewProcesses::OnCmdSortByIdL() + { + //iEngine.Container().SortById(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdSortByNameL() + { + //iEngine.Container().SortByName(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdSortByThreadCountL() + { + //iEngine.Container().SortByThreadCount(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdSortByCodeSegsL() + { + //iEngine.Container().SortByCodeSegs(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdSortByHeapUsageL() + { + //iEngine.Container().SortByHeapUsage(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdSortByStackUsageL() + { + // iEngine.Container().SortByStackUsage(); + RefreshL(); + } + + +void CMemSpyViewProcesses::OnCmdInfoSummaryL() + { + //CMemSpyProcess& process = CurrentProcess(); + //iEngine.HelperProcess().OutputProcessInfoL( process ); + } + + +void CMemSpyViewProcesses::OnCmdInfoHandlesL() + { + /* + CMemSpyProcess& process = CurrentProcess(); + // + const TInt threadCount = process.Count(); + for( TInt i=0; iExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) ); + } + // + if ( doTerminate ) + { + process.TerminateL(); + RefreshL(); + } + */ + } + + +void CMemSpyViewProcesses::OnCmdEndPanicL() + {/* + TBool doTerminate = ETrue; + CMemSpyProcess& process = CurrentProcess(); + // + if ( process.IsSystemPermanent() || process.IsSystemCritical() ) + { + CAknQueryDialog* importDialog = CAknQueryDialog::NewL(); + doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) ); + } + // + if ( doTerminate ) + { + process.PanicL(); + RefreshL(); + } + */ + } + + +void CMemSpyViewProcesses::OnCmdEndKillL() + {/* + TBool doTerminate = ETrue; + CMemSpyProcess& process = CurrentProcess(); + // + if ( process.IsSystemPermanent() || process.IsSystemCritical() ) + { + CAknQueryDialog* importDialog = CAknQueryDialog::NewL(); + doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) ); + } + // + if ( doTerminate ) + { + process.KillL(); + RefreshL(); + } + */ + } + + + + +void CMemSpyViewProcesses::SetListBoxModelL() + { + if( iProcesses.Count() > 0 ) + { + iProcesses.Close(); + } + + iMemSpySession.GetProcessesL(iProcesses); // get processes array; + iModel = new (ELeave) CDesC16ArrayFlat( iProcesses.Count() + 1); //array for formated items + + _LIT( KTab, "\t" ); + //iModel = FormatModel( iProcesses ); //TODO Format model method with advanced formatting + + + for( TInt i=0; i < iProcesses.Count(); i++ ) + { + HBufC* tempName = HBufC::NewL( iProcesses[i]->Name().Length() + 16 ); + CleanupStack::PushL( tempName ); + TPtr tempNamePtr( tempName->Des() ); + tempNamePtr.Copy( KTab ); + tempNamePtr.Append( iProcesses[i]->Name() ); + iModel->AppendL( tempNamePtr ); + + CleanupStack::PopAndDestroy( tempName ); + } + + CAknSettingStyleListBox* listbox = static_cast< CAknSettingStyleListBox* >( iListBox ); + //listbox->Model()->SetItemTextArray( &iEngine.Container() ); + listbox->Model()->SetItemTextArray( iModel ); + listbox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); + } + + +void CMemSpyViewProcesses::HandleListBoxItemActionedL( TInt /*aIndex*/ ) + { + // Notify observer about an item being 'fired' + ReportEventL( MMemSpyViewObserver::EEventItemActioned ); + } + + +void CMemSpyViewProcesses::HandleListBoxItemSelectedL( TInt aIndex ) + {/* + if ( iCurrentProcess ) + { + iCurrentProcess->Close(); + } + + // Obtain the process that corresponds to the selected item + CMemSpyEngineObjectContainer& container = iEngine.Container(); + CMemSpyProcess& process = container.At( aIndex ); + iCurrentProcess = &process; + iCurrentProcess->Open(); + + // Notify observer about item selection + ReportEventL( MMemSpyViewObserver::EEventItemSelected );*/ + } + + +void CMemSpyViewProcesses::SizeChanged() + { + const TRect rect( Rect() ); + + if ( iListBox && iSearchField ) + { + const TInt lafIndex_H = 1; + AknLayoutUtils::LayoutControl( iListBox, rect, AknLayout::list_gen_pane( lafIndex_H ) ); + AknLayoutUtils::LayoutControl( iSearchField, rect, AknLayout::find_pane() ); + } + else + { + CMemSpyViewBase::SizeChanged(); + } + +/* + // Search field + TSize searchFieldSize( iSearchField->MinimumSize() ); // BALLS: search field doesn't implement minimum size correctly?!?!? + searchFieldSize.SetWidth( rect.Width() ); + const TRect searchFieldRect( TPoint( rect.iTl.iX, rect.iBr.iY ), searchFieldSize ); + iSearchField->SetRect( searchFieldRect ); + + // Listbox + TSize listBoxSize( rect.Size() - TSize( 0, searchFieldSize.iHeight ) ); + iListBox->SetRect( rect.iTl, listBoxSize ); +*/ + } + + +TInt CMemSpyViewProcesses::CountComponentControls() const + { + TInt count = 0; + // + if ( iListBox != NULL ) + { + ++count; + } + if ( iSearchField != NULL ) + { + ++count; + } + // + return count; + } + + +CCoeControl* CMemSpyViewProcesses::ComponentControl( TInt aIndex ) const + { + CCoeControl* ret = iListBox; + // + if ( aIndex == 1 ) + { + ret = iSearchField; + } + // + return ret; + } + + +TKeyResponse CMemSpyViewProcesses::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse resp = EKeyWasNotConsumed; + // + if ( aType == EEventKey ) + { + switch( aKeyEvent.iCode ) + { + case EKeyUpArrow: + case EKeyDownArrow: + case EKeyEnter: + case EKeyOK: + if ( iListBox ) + { + resp = iListBox->OfferKeyEventL( aKeyEvent, aType ); + } + break; + default: + break; + } + // + if ( resp == EKeyWasNotConsumed ) + { + // Do we need to show the find field? + resp = iSearchField->OfferKeyEventL( aKeyEvent, aType ); + } + } + // + return resp; + } + + +void CMemSpyViewProcesses::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType ) + { + CMemSpyViewBase::HandleControlEventL( aControl, aEventType ); + // + if ( aEventType == MCoeControlObserver::EEventStateChanged ) + { + if ( aControl == iSearchField ) + { + SelectListBoxItemByFindTextL(); + } + } + } + + +void CMemSpyViewProcesses::FocusChanged( TDrawNow /*aDrawNow*/ ) + { + if ( iListBox ) + { + iListBox->SetFocus( IsFocused() ); + } + if ( iSearchField ) + { + iSearchField->SetFocus( IsFocused() ); + } + } + + +void CMemSpyViewProcesses::SelectListBoxItemByFindTextL() + { + /* + _LIT( KMemSpyWildcardCharacter, "*" ); + + TPtr pBuffer( iMatcherBuffer->Des() ); + iSearchField->GetSearchText( pBuffer ); + //pBuffer.Insert( 0, KMemSpyWildcardCharacter ); + pBuffer.Append( KMemSpyWildcardCharacter ); + + CMemSpyEngineObjectContainer& container = iEngine.Container(); + const TInt count = container.Count(); + // + TInt index = 0; + while( index < count ) + { + CMemSpyProcess& process = container.At( index ); + const TPtrC processName( process.Name() ); + // + if ( processName.MatchF( pBuffer ) >= 0 ) + { + HandleListBoxItemSelectedL( index ); + iListBox->ScrollToMakeItemVisible( index ); + iListBox->SetCurrentItemIndexAndDraw( index ); + return; + } + + ++index; + } + */ + } + +//Model formating methods +//TODO: to be debbuged +/* +CDesCArrayFlat* CMemSpyViewProcesses::FormatModel( RArray aProcesses ) + { + model = new (ELeave) CDesC16ArrayFlat( iProcesses.Count() + 16 ); //array for formated items + _LIT( KMemSpyProcessNameFormatSpecBasicName, " \t%S\t\t%8x, " ); + + for( TInt i=0; i < aProcesses.Count(); i++ ) + { + HBufC* tempName = HBufC::NewL( KMaxFullName ); //aProcesses[i]->Name().Length() + 16 + CleanupStack::PushL( tempName ); + TPtr tempNamePtr( tempName->Des() ); + tempNamePtr.Copy( aProcesses[i]->Name() ); + + TBuf<10> priority; + AppendPriority( priority, aProcesses[i]->Priority() ); + + // Convert the full name to the format we want in the UI + TBuf name; + TMemSpyTruncateOverflow overflow; //included from EngineUtils TODO: to consider if this is needed to be removed or left there + + name.AppendFormat( KMemSpyProcessNameFormatSpecBasicName, &overflow, tempNamePtr, aProcesses[i]->SID() ); + + if( aProcesses[i]->ExitType() != EExitPending ) // instead of IsDead() method + { + AppendExitInfo( name, aProcesses[i]->ExitType(), aProcesses[i]->ExitReason(), aProcesses[i]->ExitCategory() ); + } + else + { + _LIT( KMemSpyProcessNameFormatSpecAlive, "%2d thr, %S" ); + name.AppendFormat( KMemSpyProcessNameFormatSpecAlive, &overflow, aProcesses[i]->ThreadCount(), &priority ); + } + + model->AppendL( name ); + + CleanupStack::PopAndDestroy( tempName ); + } + + return model; + } + +void CMemSpyViewProcesses::AppendPriority( TDes& aDes, TProcessPriority aPriority ) + { + switch( aPriority ) + { + case EPriorityLow: + aDes += _L("[L]"); + break; + case EPriorityBackground: + aDes += _L("[B]"); + break; + case EPriorityForeground: + aDes += _L("[F]"); + break; + case EPriorityHigh: + aDes += _L("[H]"); + break; + case EPriorityWindowServer: + aDes += _L("[WS]"); + break; + case EPriorityFileServer: + aDes += _L("[FS]"); + break; + case EPriorityRealTimeServer: + aDes += _L("[RTS]"); + break; + case EPrioritySupervisor: + aDes += _L("[SUP]"); + break; + default: + aDes += _L("[?]"); + break; + } + } + +void CMemSpyViewProcesses::AppendExitInfo( TDes& aDes, TExitType aType, TInt aExitReason, const TDesC& aExitCategory ) + { + aDes.Append( '[' ); + const TInt length = aDes.Length(); + AppendExitType( aDes, aType ); + aDes.SetLength( length + 1 ); // Remove all but the first letter + aDes.Append( ']' ); + + if ( aType == EExitKill || aType == EExitPending ) + { + // Kill implies "clean" exit. Pending implies not yet dead. + } + else + { + TMemSpyTruncateOverflow overflow; + + // Terminate or Panic implies abnormal exit condition, so + // show full exit info. + _LIT( KAbnormalFormatSpec, " %S-%d" ); + aDes.AppendFormat( KAbnormalFormatSpec, &overflow, &aExitCategory, aExitReason ); + } + } + +void CMemSpyViewProcesses::AppendExitType( TDes& aDes, TExitType aType ) + { + _LIT( KExitTypeKilled, "Killed" ); + _LIT( KExitTypeTerminated, "Terminated" ); + _LIT( KExitTypePanicked, "Panicked" ); + _LIT( KExitTypePending, "Pending" ); + + // Panic and Terminate are exceptional exit conditions. + // Kill, is ironically, not an exceptional condition. + switch( aType ) + { + case EExitKill: + aDes += KExitTypeKilled; + break; + case EExitTerminate: + aDes += KExitTypeTerminated; + break; + case EExitPanic: + aDes += KExitTypePanicked; + break; + default: + case EExitPending: + aDes += KExitTypePending; + break; + } + } +*/