--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspyui/source/MemSpyViewThreadInfoItemList.cpp Wed Sep 01 12:30:35 2010 +0100
@@ -0,0 +1,336 @@
+/*
+* 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 "MemSpyViewThreadInfoItemList.h"
+
+// Engine includes
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+#include <memspy/engine/memspyengineobjectthread.h>
+#include <memspy/engine/memspyengineobjectcontainer.h>
+#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
+#include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
+#include <memspy/engine/memspyenginehelperprocess.h>
+
+// User includes
+#include "MemSpyContainerObserver.h"
+#include "MemSpyViewThreads.h"
+#include "MemSpyViewThreadInfoItemHeap.h"
+#include "MemSpyViewThreadInfoItemStack.h"
+#include "MemSpyViewThreadInfoItemChunk.h"
+#include "MemSpyViewThreadInfoItemCodeSeg.h"
+#include "MemSpyViewThreadInfoItemServer.h"
+#include "MemSpyViewThreadInfoItemActiveObject.h"
+#include "MemSpyViewThreadInfoItemGeneralInfo.h"
+#include "MemSpyViewThreadInfoItemMemoryTracking.h"
+
+// Constants
+const TInt KMemSpyIdleResetListboxTimerPeriod = 250000;
+
+
+CMemSpyViewThreadInfoItemList::CMemSpyViewThreadInfoItemList( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver, CMemSpyThread& aThread )
+: CMemSpyViewBase( aEngine, aObserver ), iThread( aThread )
+ {
+ iThread.Process().Open();
+ iThread.Open();
+ }
+
+
+CMemSpyViewThreadInfoItemList::~CMemSpyViewThreadInfoItemList()
+ {
+ delete iIdleResetListboxTimer;
+
+ TRAP_IGNORE(
+ CMemSpyThreadInfoContainer& container = iThread.InfoContainerL();
+ container.ObserverRemove( *this );
+ );
+
+ if ( iCurrentInfoItem )
+ {
+ iCurrentInfoItem->Close();
+ }
+
+ iThread.Process().Close();
+ iThread.Close();
+ }
+
+
+
+void CMemSpyViewThreadInfoItemList::ConstructL( const TRect& aRect, CCoeControl& aContainer, TAny* aSelectionRune )
+ {
+ _LIT( KTitle, "Thread Objects" );
+ SetTitleL( KTitle );
+ //
+ iIdleResetListboxTimer = CPeriodic::NewL( CActive::EPriorityIdle );
+ //
+ CMemSpyThreadInfoContainer& container = iThread.InfoContainerL();
+ container.ObserverAddL( *this );
+ //
+ CMemSpyViewBase::ConstructL( aRect, aContainer, aSelectionRune );
+ //
+ if ( aSelectionRune )
+ {
+ CMemSpyThreadInfoItemBase* selectedItem = reinterpret_cast< CMemSpyThreadInfoItemBase* >( aSelectionRune );
+ const TInt index = container.InfoItemIndexByType( selectedItem->Type() );
+ if ( index >= 0 && index < iListBox->Model()->NumberOfItems() )
+ {
+ iListBox->SetCurrentItemIndex( index );
+ HandleListBoxItemSelectedL( index );
+ }
+ }
+ else if ( container.MdcaCount() > 0 )
+ {
+ iListBox->SetCurrentItemIndex( 0 );
+ HandleListBoxItemSelectedL( 0 );
+ }
+ }
+
+
+const CMemSpyProcess& CMemSpyViewThreadInfoItemList::Process() const
+ {
+ return iThread.Process();
+ }
+
+
+const CMemSpyThread& CMemSpyViewThreadInfoItemList::Thread() const
+ {
+ return iThread;
+ }
+
+
+const CMemSpyThreadInfoItemBase& CMemSpyViewThreadInfoItemList::CurrentInfoItem() const
+ {
+ __ASSERT_ALWAYS( iCurrentInfoItem != NULL, User::Invariant() );
+ return *iCurrentInfoItem;
+ }
+
+
+void CMemSpyViewThreadInfoItemList::RefreshL()
+ {
+ SetListBoxModelL();
+ CMemSpyViewBase::RefreshL();
+ }
+
+
+TMemSpyViewType CMemSpyViewThreadInfoItemList::ViewType() const
+ {
+ return EMemSpyViewTypeThreadInfoItemList;
+ }
+
+
+CMemSpyViewBase* CMemSpyViewThreadInfoItemList::PrepareParentViewL()
+ {
+ CMemSpyViewBase* parent = new(ELeave) CMemSpyViewThreads( iEngine, iObserver, iThread.Process() );
+ CleanupStack::PushL( parent );
+ parent->ConstructL( Rect(), *Parent(), &iThread );
+ CleanupStack::Pop( parent );
+ return parent;
+ }
+
+
+CMemSpyViewBase* CMemSpyViewThreadInfoItemList::PrepareChildViewL()
+ {
+ __ASSERT_ALWAYS( iCurrentInfoItem != NULL, User::Invariant() );
+ CMemSpyViewBase* child = NULL;
+
+ // Decide what type of child view to create...
+ const TMemSpyThreadInfoItemType type = iCurrentInfoItem->Type();
+ //
+ switch( type )
+ {
+ case EMemSpyThreadInfoItemTypeHeap:
+ child = new(ELeave) CMemSpyViewThreadInfoItemHeap( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeStack:
+ child = new(ELeave) CMemSpyViewThreadInfoItemStack( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeChunk:
+ child = new(ELeave) CMemSpyViewThreadInfoItemChunk( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeCodeSeg:
+ child = new(ELeave) CMemSpyViewThreadInfoItemCodeSeg( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeServer:
+ child = new(ELeave) CMemSpyViewThreadInfoItemServer( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeActiveObject:
+ child = new(ELeave) CMemSpyViewThreadInfoItemActiveObject( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeGeneralInfo:
+ child = new(ELeave) CMemSpyViewThreadInfoItemGeneralInfo( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeMemoryTracking:
+ child = new(ELeave) CMemSpyViewThreadInfoItemMemoryTracking( iEngine, iObserver, iThread.InfoContainerL() );
+ break;
+ case EMemSpyThreadInfoItemTypeSession:
+ case EMemSpyThreadInfoItemTypeSemaphore:
+ case EMemSpyThreadInfoItemTypeMutex:
+ case EMemSpyThreadInfoItemTypeTimer:
+ case EMemSpyThreadInfoItemTypeLDD:
+ case EMemSpyThreadInfoItemTypePDD:
+ case EMemSpyThreadInfoItemTypeLogicalChannel:
+ case EMemSpyThreadInfoItemTypeChangeNotifier:
+ case EMemSpyThreadInfoItemTypeUndertaker:
+ case EMemSpyThreadInfoItemTypeMessageQueue:
+ case EMemSpyThreadInfoItemTypeConditionalVariable:
+ case EMemSpyThreadInfoItemTypeOpenFiles:
+ case EMemSpyThreadInfoItemTypeOtherThreads:
+ case EMemSpyThreadInfoItemTypeOtherProcesses:
+ case EMemSpyThreadInfoItemTypeOwnedThreadHandles:
+ case EMemSpyThreadInfoItemTypeOwnedProcessHandles:
+ child = new(ELeave) CMemSpyViewThreadInfoItemGeneric( iEngine, iObserver, iThread.InfoContainerL(), type );
+ break;
+
+ default:
+ __ASSERT_ALWAYS( EFalse, User::Panic( _L("MemSpy-View"), 0) );
+ break;
+ }
+ //
+ CleanupStack::PushL( child );
+ child->ConstructL( Rect(), *Parent() );
+ CleanupStack::Pop( child );
+ return child;
+ }
+
+
+TBool CMemSpyViewThreadInfoItemList::HandleCommandL( TInt aCommand )
+ {
+ TBool handled = ETrue;
+ //
+ switch ( aCommand )
+ {
+ case EMemSpyCmdThreadInfoHandles:
+ OnCmdInfoHandlesL();
+ break;
+
+ default:
+ handled = CMemSpyViewBase::HandleCommandL( aCommand );
+ break;
+ }
+ //
+ return handled;
+ }
+
+
+void CMemSpyViewThreadInfoItemList::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane )
+ {
+ if ( aResourceId == R_MEMSPY_MENUPANE )
+ {
+ aMenuPane->SetItemDimmed( EMemSpyCmdThread, iThread.IsDead() );
+ }
+ else if ( aResourceId == MenuCascadeResourceId() )
+ {
+ // Always remove these items - they are only shown in the master thread view
+ aMenuPane->SetItemDimmed( EMemSpyCmdThreadSetPriority, ETrue );
+ aMenuPane->SetItemDimmed( EMemSpyCmdThreadEnd, ETrue );
+ }
+ }
+
+
+void CMemSpyViewThreadInfoItemList::OnCmdInfoHandlesL()
+ {
+ iThread.InfoContainerForceSyncronousConstructionL().PrintL();
+ }
+
+
+void CMemSpyViewThreadInfoItemList::HandleMemSpyEngineInfoContainerEventL( TEvent aEvent, TMemSpyThreadInfoItemType aType )
+ {
+ if ( aEvent == EInfoItemChanged )
+ {
+ }
+ else if ( aEvent == EInfoItemDestroyed )
+ {
+ if ( iCurrentInfoItem && iCurrentInfoItem->Type() == aType )
+ {
+ iCurrentInfoItem->Close();
+ iCurrentInfoItem = NULL;
+ }
+ }
+
+ iIdleResetListboxTimer->Cancel();
+ iIdleResetListboxTimer->Start( KMemSpyIdleResetListboxTimerPeriod, KMemSpyIdleResetListboxTimerPeriod, TCallBack( IdleUpdateListBoxModel, this ) );
+ }
+
+
+void CMemSpyViewThreadInfoItemList::SetListBoxModelL()
+ {
+ CAknSettingStyleListBox* listbox = static_cast< CAknSettingStyleListBox* >( iListBox );
+ listbox->Model()->SetItemTextArray( &iThread.InfoContainerL() );
+ listbox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
+ }
+
+
+void CMemSpyViewThreadInfoItemList::HandleListBoxItemActionedL( TInt /*aIndex*/ )
+ {
+ // Notify observer about an item being 'fired'
+ ReportEventL( MMemSpyViewObserver::EEventItemActioned );
+ }
+
+
+void CMemSpyViewThreadInfoItemList::HandleListBoxItemSelectedL( TInt aIndex )
+ {
+ if ( iCurrentInfoItem )
+ {
+ CMemSpyThreadInfoItemBase* item = iCurrentInfoItem;
+ iCurrentInfoItem = NULL;
+ item->Close();
+ }
+
+ // Identify the type of item to display...
+ iCurrentInfoItem = &iThread.InfoContainerL().Item( aIndex );
+ iCurrentInfoItem->Open();
+
+ // Notify observer about item selection
+ ReportEventL( MMemSpyViewObserver::EEventItemSelected );
+ }
+
+
+TInt CMemSpyViewThreadInfoItemList::IdleUpdateListBoxModel( TAny* aSelf )
+ {
+ CMemSpyViewThreadInfoItemList* self = reinterpret_cast< CMemSpyViewThreadInfoItemList* >( aSelf );
+ TRAP_IGNORE( self->DoIdleUpdateListBoxModelL() );
+ return EFalse;
+ }
+
+
+void CMemSpyViewThreadInfoItemList::DoIdleUpdateListBoxModelL()
+ {
+ CMemSpyThreadInfoContainer& container = iThread.InfoContainerL();
+
+ // Try to maintain current item selection if at all possible.
+ TMemSpyThreadInfoItemType type = EMemSpyThreadInfoItemTypeHeap;
+ if ( iCurrentInfoItem )
+ {
+ type = iCurrentInfoItem->Type();
+ }
+
+ // Update list box & model
+ SetListBoxModelL();
+ iListBox->HandleItemAdditionL();
+ RefreshL();
+
+ // Try to select previous item if it is still available
+ const TInt index = container.InfoItemIndexByType( type );
+ if ( index >= 0 && index < container.MdcaCount() )
+ {
+ iListBox->SetCurrentItemIndex( index );
+ HandleListBoxItemSelectedL( index );
+ }
+
+ iIdleResetListboxTimer->Cancel();
+ }
+