diff -r aecbbf00d063 -r d48ab3b357f1 uifw/AvKon/src/aknmessagequerydialog.cpp --- a/uifw/AvKon/src/aknmessagequerydialog.cpp Tue Aug 31 15:28:30 2010 +0300 +++ b/uifw/AvKon/src/aknmessagequerydialog.cpp Wed Sep 01 12:16:19 2010 +0100 @@ -41,7 +41,7 @@ #include // for testability hooks #include "AknHeadingPaneTouchObserver.h" - +#include "akntrace.h" // CONSTANTS const TInt KMaxLinks = 64; @@ -51,6 +51,24 @@ const TInt KBoldStartTagLength = 22; const TInt KBoldEndTagLength = 23; +NONSHARABLE_CLASS(CAknAsynCallbackRunner) : public CActive + { +public: + CAknAsynCallbackRunner( CAknMessageQueryDialogExtension* aMsgQueryExtension ); + ~CAknAsynCallbackRunner(); + +public: +// new functions + void AsyncCallbackRunL( TInt aCurLink ); + +// from CActive + void DoCancel(); + void RunL(); + +private: + CAknMessageQueryDialogExtension* iMsgQueryExtension; + TInt iCurLink; + }; class CAknMessageQueryDialogExtension : public CBase, public CAknExtendedInputCapabilities::MAknEventObserver, public MAknHeadingPaneTouchObserver @@ -60,6 +78,7 @@ iControlRegisted( EFalse ) {} ~CAknMessageQueryDialogExtension() { + delete iAsyncCallbackRunner; TInt count = iFormatTextArray.Count(); for ( TInt i = 0; i < count; i++ ) { @@ -69,13 +88,6 @@ iFormatTextLocationArray.Close(); iFormatTextArray.Close(); iFormatTypeArray.Close(); - - if ( iDestroyedPtr ) - { - // Mark the object as destroyed. - *iDestroyedPtr = ETrue; - iDestroyedPtr = NULL; - } } /** From CAknExtendedInputCapabilities::MAknEventObserver @@ -99,6 +111,15 @@ iCtrl->DehighlightLink(); } } + + void ExecuteLinkCallbackL( TInt aCurLink ) + { + if ( !iAsyncCallbackRunner ) + { + iAsyncCallbackRunner = new( ELeave ) CAknAsynCallbackRunner( this ); + } + iAsyncCallbackRunner->AsyncCallbackRunL( aCurLink ); + } public: @@ -114,25 +135,60 @@ TInt iButtonGroupPreviouslyChanged; CAknMessageQueryDialog* iParent; TBool iControlRegisted; - CAknMessageQueryControl* iCtrl; + CAknMessageQueryControl* iCtrl; + + TBool iIsInEditor; - /** - * @c iDestroyedPtr is used for the object destruction check. - * If it has non-null value, the destruction check is turned on, and - * the value points to a local boolean variable that keeps the destroyed state. - */ - TBool* iDestroyedPtr; - TBool iIsInEditor; + CAknAsynCallbackRunner* iAsyncCallbackRunner; }; + +CAknAsynCallbackRunner::CAknAsynCallbackRunner( + CAknMessageQueryDialogExtension* aMsgQueryExtension ) : + CActive( EPriorityStandard ), iMsgQueryExtension( aMsgQueryExtension ) + { + CActiveScheduler::Add( this ); + } + +CAknAsynCallbackRunner::~CAknAsynCallbackRunner() + { + Cancel(); + } + +void CAknAsynCallbackRunner::AsyncCallbackRunL( TInt aCurLink ) + { + iCurLink = aCurLink; + if ( !IsActive() ) + { + iStatus = KRequestPending; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + } + +void CAknAsynCallbackRunner::DoCancel() + { + } + +void CAknAsynCallbackRunner::RunL() + { + if ( iMsgQueryExtension && iCurLink >= 0 && + iCurLink < iMsgQueryExtension->iCallBackArray.Count() ) + { + iMsgQueryExtension->iCallBackArray[iCurLink].CallBack(); + } + } EXPORT_C CAknMessageQueryDialog* CAknMessageQueryDialog::NewL( TDesC& aMessage, const TTone& aTone ) { + _AKNTRACE_FUNC_ENTER; CAknMessageQueryDialog* self = new ( ELeave ) CAknMessageQueryDialog( aTone ); CleanupStack::PushL( self ); self->SetMessageTextL( aMessage ); CleanupStack::Pop(); //self AKNTASHOOK_ADDL( self, "CAknMessageQueryDialog" ); + _AKNTRACE_FUNC_EXIT; return self; } @@ -148,11 +204,13 @@ EXPORT_C CAknMessageQueryDialog::CAknMessageQueryDialog( const TTone aTone ) : CAknQueryDialog( aTone ) { + _AKNTRACE_FUNC_ENTER; #ifndef RD_NO_DIALOG_BORDERS iBorder = AknBorderId::EAknBorderNotePopup; #else iBorder = TGulBorder::ENone; #endif + _AKNTRACE_FUNC_EXIT; } //@deprecated @@ -201,12 +259,14 @@ EXPORT_C CAknMessageQueryDialog::~CAknMessageQueryDialog() { + _AKNTRACE( "[%s][%s] Enter", "CAknMessageQueryDialog", "~CAknMessageQueryDialog" ); AKNTASHOOK_REMOVE(); delete iMessage; delete iHeader; delete iHeaderImage; RegisterPointerEventObserver( EFalse ); delete iMsgQueryExtension; + _AKNTRACE( "[%s][%s] Exit", "CAknMessageQueryDialog", "~CAknMessageQueryDialog" ); } EXPORT_C void CAknMessageQueryDialog::SetMessageTextL( const TDesC& aMessage ) @@ -242,8 +302,11 @@ else { // SetLinkTextL creates new callback in the callback array for the new link - iMsgQueryExtension->iFormatTextArray.Append( aLinkText.AllocL() ); - iMsgQueryExtension->iFormatTypeArray.Append( EMsgQueryLink ); + HBufC* linkText = aLinkText.AllocL(); + CleanupStack::PushL( linkText ); + iMsgQueryExtension->iFormatTextArray.AppendL( linkText ); + CleanupStack::Pop( linkText ); + iMsgQueryExtension->iFormatTypeArray.AppendL( EMsgQueryLink ); // If the other method SetLink has been already called // the new link is finished by adding the link count @@ -286,7 +349,10 @@ if ( iMsgQueryExtension->iCallBackArray.Count() < iMsgQueryExtension->iLinkCount ) { // SetLink creates new callback in the callback array for the new link - iMsgQueryExtension->iCallBackArray.Append( aCallBack ); + if ( KErrNone != iMsgQueryExtension->iCallBackArray.Append( aCallBack ) ) + { + return; + } } } else if ( iMsgQueryExtension->iLinkCount < KMaxLinks ) @@ -299,7 +365,10 @@ else { // SetLink creates new callback in the callback array for the new link - iMsgQueryExtension->iCallBackArray.Append( aCallBack ); + if ( KErrNone != iMsgQueryExtension->iCallBackArray.Append( aCallBack ) ) + { + return; + } // If the other method SetLinkText has been already called // the new link is finished by adding the link count @@ -355,6 +424,7 @@ EXPORT_C void CAknMessageQueryDialog::PreLayoutDynInitL() { + _AKNTRACE_FUNC_ENTER; if ( !iMsgQueryExtension ) { CreateExtensionL(); @@ -425,6 +495,7 @@ headingPane->SetLayout(CAknPopupHeadingPane::EMessageQueryHeadingPane); // Use message query heading layout. headingPane->SetTouchObserver( iMsgQueryExtension ); } + _AKNTRACE_FUNC_EXIT; } @@ -626,7 +697,7 @@ } delete messageBuf; } - iMsgQueryExtension->iFormatTextLocationArray.Append( linkTextLocation ); + iMsgQueryExtension->iFormatTextLocationArray.AppendL( linkTextLocation ); return ETrue; } @@ -986,31 +1057,22 @@ TBool CAknMessageQueryDialog::ExecuteLinkL() { - CAknMessageQueryControl* control = STATIC_CAST( CAknMessageQueryControl*, Control( EAknMessageQueryContentId ) ); + _AKNTRACE_FUNC_ENTER; + CAknMessageQueryControl* control = STATIC_CAST( CAknMessageQueryControl*, Control( EAknMessageQueryContentId ) ); if( !control ) { + _AKNTRACE_FUNC_EXIT; return EFalse; } if( !control->LinkHighLighted() ) { + _AKNTRACE_FUNC_EXIT; return EFalse; } TInt curLink = control->CurrentLink(); - /** - * The local @c destroyed variable keeps track of the object destroyed state. - */ - TBool destroyed = EFalse; - iMsgQueryExtension->iDestroyedPtr = &destroyed; - TRAPD( err, iMsgQueryExtension->iCallBackArray[curLink].CallBack() ); - if ( !destroyed ) - { - iMsgQueryExtension->iDestroyedPtr = NULL; - } - User::LeaveIfError( err ); - if ( !destroyed ) - { - control->DehighlightLink(); - } + TRAP_IGNORE( iMsgQueryExtension->ExecuteLinkCallbackL( curLink ) ); + control->DehighlightLink(); + _AKNTRACE_FUNC_EXIT; return ETrue; }