uifw/AvKon/src/aknmessagequerydialog.cpp
branchRCL_3
changeset 20 d48ab3b357f1
parent 19 aecbbf00d063
--- 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 <AknTasHook.h> // 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;
     }