phoneuis/vmbx/src/VmDetailsDialog.cpp
branchRCL_3
changeset 25 5266b1f337bd
parent 0 5f000ab63145
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneuis/vmbx/src/VmDetailsDialog.cpp	Wed Sep 01 12:30:10 2010 +0100
@@ -0,0 +1,577 @@
+/*
+* Copyright (c) 2002 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:  Details dialog for last message.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <bldvariant.hrh>
+#include "VmDetailsDialog.h"
+#include "VoiceMailboxAppPrivateCRKeys.h"
+#include "VmDetDlgPropertyObserver.h"
+#include <centralrepository.h>
+#include "Vm.hrh"
+#include <Vm.rsg>
+#include <AknLists.h>
+#include <AknTitle.h>
+#include <NumberGrouping.h>
+#include <NumberGroupingCRKeys.h>
+#include <StringLoader.h>
+#include "VMBLogger.h"
+
+// CONSTANTS
+const TInt KVmMaxLabelStringLength = 100;
+const TInt KVmMaxLabelFreeTextLength = 255;
+const TUint KVmDateSeparator = '/';
+const TUint KVmTimeSeparator = ':';
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::CVmDetailsDialog
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CVmDetailsDialog::CVmDetailsDialog()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::ConstructL()
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::ConstructL =>" );
+    CAknDialog::ConstructL( R_VMBX_DETAIL_MENUBAR );
+
+    // Central Repository handle
+    iSession = CRepository::NewL( KCRUidVoiceMailbox );
+    iObserver = CVmDetDlgPropertyObserver::NewL( *this );
+    StartObservingL();
+
+    TInt pngErr( KErrNone );
+    TInt pngSupported( 0 );
+    CRepository* repository = CRepository::NewL( KCRUidNumberGrouping );
+    pngErr = repository->Get( KNumberGrouping, pngSupported );
+    delete repository;
+
+    // create number grouping component if is supported.
+    if ( KErrNone == pngErr && pngSupported != 0 )
+        {
+        iNumberGrouping = CPNGNumberGrouping::NewL( KVmMaxLabelStringLength );
+        }
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::ConstructL <=" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CVmDetailsDialog* CVmDetailsDialog::NewL()
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::NewL =>" );
+    CVmDetailsDialog* self = new( ELeave ) CVmDetailsDialog;
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::NewL <=" );
+    return self;
+    }
+    
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::~CVmDetailsDialog
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CVmDetailsDialog::~CVmDetailsDialog()
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::~CVmDetailsDialog =>" );
+    delete iOldTitlePaneText;
+    iOldTitlePaneText = NULL;
+
+    delete iObserver;
+    delete iSession;
+    delete iNumberGrouping;
+
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::~CVmDetailsDialog <=" );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::PreLayoutDynInitL
+// Called before the dialog is launched. Title pane is updated and listbox
+// is filled with a last message information.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::PreLayoutDynInitL()
+    {
+    // Take old title pane to variable.
+    CAknTitlePane* titlePane = 
+        static_cast< CAknTitlePane* >
+            ( iEikonEnv->AppUiFactory()->StatusPane()->ControlL(
+                TUid::Uid( EEikStatusPaneUidTitle ) ) );
+    iOldTitlePaneText = titlePane->Text()->AllocL();
+
+    // Set new title
+    HBufC* titleText = StringLoader::LoadL( R_TITLE_DETAILS );
+    titlePane->SetText( titleText ); //takes ownership
+    titleText = NULL;
+
+
+    // Get listbox pointer
+    CAknSingleHeadingStyleListBox* listbox = 
+        static_cast<CAknSingleHeadingStyleListBox*> 
+            ( Control( KVmDetailsDialog ) );
+
+    listbox->CreateScrollBarFrameL( ETrue );
+    listbox->ScrollBarFrame()->SetScrollBarVisibilityL(
+        CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+
+    // populate array
+    MDesCArray* itemList = listbox->Model()->ItemTextArray();
+    CDesCArray* itemArray = static_cast<CDesCArray*>( itemList );
+    PopulateListboxItemsL( *itemArray );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::PopulateListboxItemsL
+// Reads message details from shared data.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::PopulateListboxItemsL( CDesCArray& aItemArray )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::PopulateListboxItemsL =>" );
+    // To calculate the rect for the text box.
+    CAknSingleHeadingStyleListBox* listbox = 
+                   static_cast<CAknSingleHeadingStyleListBox*> 
+                       ( Control(KVmDetailsDialog) );    
+    CListBoxView* view = listbox->View();    
+    TRect itemTextRect (TPoint( view->ItemPos(0) ), TSize(view->ItemSize() ) );
+    aItemArray.Reset();
+
+    // Used variables
+    HBufC* heading = NULL;
+    HBufC* data = NULL;
+    TInt error = KErrNone;
+
+
+    // Urgency
+    heading = StringLoader::LoadLC( R_URGENCY );
+
+    TInt urgency; 
+    error = iSession->Get( KVmUrgencyLevel, urgency );
+    if ( error == KErrNone )
+        {
+        switch ( urgency )
+            {
+            case 0: // Normal
+            case 1: // Interactive
+                {
+                data = StringLoader::LoadLC( R_NORMAL );
+                break;
+                }
+            case 2: // Urgent
+                {
+                data = StringLoader::LoadLC( R_URGENT );
+                break;
+                }
+            case 3: // Emergency
+                {
+                data = StringLoader::LoadLC( R_EMERGENCY );
+                break;
+                }
+            default:
+                {
+                User::Leave( KErrNotSupported );
+                break;
+                }
+            }
+        }
+    else
+        {
+        data = KNullDesC().AllocLC();
+        }
+    
+    AppendLineL( aItemArray, heading->Des(), data->Des(), itemTextRect );
+    CleanupStack::PopAndDestroy( data );
+    CleanupStack::PopAndDestroy( heading );
+
+
+    // Date
+    heading = StringLoader::LoadLC( R_DATE );
+
+    data = HBufC::NewLC( KVmMaxLabelStringLength );
+    TPtr datePtr = data->Des();
+    if ( iSession->Get( KVmDateStamp, datePtr ) == KErrNone )
+        {
+        FormatDateStringL( datePtr );
+        }
+        
+    AppendLineL( aItemArray, heading->Des(), data->Des(), itemTextRect );
+    CleanupStack::PopAndDestroy( data );
+    CleanupStack::PopAndDestroy( heading );
+
+    // Time
+    heading = StringLoader::LoadLC( R_TIME );
+
+    data = HBufC::NewLC( KVmMaxLabelStringLength );
+    TPtr timePtr = data->Des();
+    if ( iSession->Get( KVmTimeStamp, timePtr ) == KErrNone )
+        {
+        FormatTimeStringL( timePtr );
+        }
+
+    AppendLineL( aItemArray, heading->Des(), data->Des(), itemTextRect );
+    CleanupStack::PopAndDestroy( data );
+    CleanupStack::PopAndDestroy( heading );
+
+    // Callback number
+    heading = StringLoader::LoadLC( R_CALL_BACK );
+
+    data = HBufC::NewLC( KVmMaxLabelStringLength );
+    TPtr callbackPtr = data->Des();
+    iSession->Get( KVmCallbackNumber, callbackPtr ); // ignore error
+
+    if ( iNumberGrouping )
+        {
+        iNumberGrouping->Set( callbackPtr );
+        CleanupStack::PopAndDestroy( data );
+        data = iNumberGrouping->FormattedNumber().AllocLC();
+        }
+
+    AppendLineL( aItemArray, heading->Des(), data->Des(), itemTextRect, ETrue );
+    CleanupStack::PopAndDestroy( data );
+    CleanupStack::PopAndDestroy( heading );
+
+    // Text
+    heading = StringLoader::LoadLC( R_TEXT );
+
+    data = HBufC::NewLC( KVmMaxLabelFreeTextLength );
+    TPtr textPtr = data->Des();
+    iSession->Get( KVmUserData, textPtr ); // ignore error
+
+    AppendLineL( aItemArray, heading->Des(), data->Des(), itemTextRect, ETrue );
+    CleanupStack::PopAndDestroy( data );
+    CleanupStack::PopAndDestroy( heading );
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::PopulateListboxItemsL <=" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::FormatDateStringL
+// Formats date string
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::FormatDateStringL( TDes& aDateString )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatDateStringL =>" );
+    if ( !aDateString.Length() )
+        {
+        return;
+        }
+
+    // Check that we have two separators '/'
+    TInt indexFirst = aDateString.Locate( KVmDateSeparator );
+    TInt indexSecond = aDateString.LocateReverse( KVmDateSeparator );
+    if ( indexFirst == indexSecond ) // Also -1 is covered
+        {
+        // Incorrect date format
+        User::Leave( KErrCorrupt );
+        }
+
+    TLex lex = aDateString.Right( aDateString.Length() - indexSecond - 1 );
+    TInt year;
+    User::LeaveIfError( lex.Val( year ) );
+    
+    lex = aDateString.Mid( indexFirst + 1, indexSecond - indexFirst );
+    TInt month;
+    User::LeaveIfError( lex.Val( month ) );
+
+    lex = aDateString.Left( indexFirst );
+    TInt day;
+    User::LeaveIfError( lex.Val( day ) );
+
+    // Format date according the locale:
+    TDateTime dateTime( year, TMonth( month - 1 ), day, 0, 0, 0, 0 );
+    TTime time( dateTime );
+    HBufC* dateFormat = StringLoader::LoadLC( R_QTN_DATE_USUAL_WITH_ZERO );
+    time.FormatL( aDateString, *dateFormat );
+    CleanupStack::PopAndDestroy( dateFormat ); //dateFormatString
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatDateStringL <=" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::FormatTimeStringL
+// Formats time string
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::FormatTimeStringL( TDes& aTimeString )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatTimeStringL =>" );
+    if ( !aTimeString.Length() )
+        {
+        VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatTimeStringL: \
+        Empty time " );
+        return;
+        }
+
+    // Check that we have two separators ':'
+    TInt indexFirst = aTimeString.Locate( KVmTimeSeparator );
+    TInt indexSecond = aTimeString.LocateReverse( KVmTimeSeparator );
+    if ( indexFirst == indexSecond ) // Also -1 is covered
+        {
+        VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatTimeStringL \
+        Incorrect date format" );
+        // Incorrect date format
+        User::Leave( KErrCorrupt );
+        }
+
+    TLex lex( aTimeString.Left( indexFirst ) );
+    TInt hour;
+    User::LeaveIfError( lex.Val( hour ) );
+    
+    lex = aTimeString.Mid( indexFirst + 1, indexSecond - indexFirst );
+    TInt minute;
+    User::LeaveIfError( lex.Val( minute ) );
+    
+    lex = aTimeString.Right( aTimeString.Length() - indexSecond - 1 );
+    TInt second;
+    User::LeaveIfError( lex.Val( second ) );
+
+    // Format time according the locale:
+    TDateTime dateTime( 0, TMonth(0), 0, hour, minute, second, 0 );
+    TTime time( dateTime );
+    HBufC* timeFormat = StringLoader::LoadLC( R_QTN_TIME_USUAL_WITH_ZERO );
+    time.FormatL( aTimeString, *timeFormat );
+    CleanupStack::PopAndDestroy( timeFormat ); //dateFormatString
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::FormatTimeStringL <=" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::AppendLineL
+// Adds line to the listbox.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::AppendLineL( CDesCArray& aItemArray, 
+                                    const TDesC& aHeading, 
+                                    const TDesC& aData, 
+                                    TRect aItemTextRect,
+                                    TBool aUseMultipleLines )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::AppendLineL =>" );
+    TBuf<1> tabChar(_L("\t"));
+    HBufC* combination = NULL;
+
+    if ( aUseMultipleLines )
+        {
+        CArrayFixFlat<TPtrC>* wrappedTexts = 
+            new (ELeave) CArrayFixFlat<TPtrC>( 2 );
+        CleanupStack::PushL( wrappedTexts );
+
+        // Layout used for CAknSingleHeadingStyleListBox 
+        // is list_single_heading_pane
+        // Layout text for list_single_heading_pane_2 (first row from No.2)
+        TAknTextLineLayout layout = 
+            AKN_LAYOUT_TEXT_List_pane_texts__single_heading__Line_2 (0 );
+        TAknLayoutText text;
+        text.LayoutText( aItemTextRect, layout );
+        TRect rect = text.TextRect();
+
+        // Wrap the long text to several lines.
+        AknTextUtils::WrapToArrayL( aData, 
+                    rect.Width() /* layout.iW */, 
+                    *AknLayoutUtils::FontFromId( layout.FontId() /* iFont */),
+                    *wrappedTexts );
+
+        if ( wrappedTexts->Count() == 0 ) // i.e. empty text
+            {
+            // For creating the first line
+            wrappedTexts->AppendL( KNullDesC() );
+            }
+
+        // Create the first line:
+        combination = HBufC::NewLC( aHeading.Length() + 
+                                    tabChar.Length() + 
+                                    wrappedTexts->At( 0 ).Length() );
+
+        TPtr comPtr = combination->Des();
+
+        comPtr.Append( aHeading );
+        comPtr.Append( tabChar );
+        comPtr.Append( wrappedTexts->At( 0 ) );
+        
+        aItemArray.AppendL( comPtr );
+        
+        CleanupStack::PopAndDestroy( combination );
+        combination = NULL;
+
+        // Create the other lines
+        for ( TInt i = 1 ; i < wrappedTexts->Count() ; i++ )
+            {
+            // combination is created without the header.
+            combination = HBufC::NewLC( tabChar.Length() + 
+                                    wrappedTexts->At( i ).Length() );
+
+            comPtr.Set( combination->Des() );
+
+            comPtr.Append( tabChar );
+            comPtr.Append( wrappedTexts->At( i ) );
+
+            aItemArray.AppendL( comPtr );
+
+            CleanupStack::PopAndDestroy( combination );
+            combination = NULL;
+            }
+        CleanupStack::PopAndDestroy( wrappedTexts );
+        }
+    else
+        {
+        // Create combination to one line in listbox.
+        combination = HBufC::NewLC( aHeading.Length() + 
+                                        tabChar.Length() + 
+                                        aData.Length() );
+
+        TPtr comPtr = combination->Des();
+        
+        comPtr.Append( aHeading );
+        comPtr.Append( tabChar );
+        comPtr.Append( aData );
+        
+        aItemArray.AppendL( comPtr );
+        
+        CleanupStack::PopAndDestroy( combination );
+        }
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::AppendLineL =>" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::OfferKeyEventL
+// Called when a key is pressed.
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CVmDetailsDialog::OfferKeyEventL( const TKeyEvent& aKeyEvent, 
+                                             TEventCode aType )
+    {
+    // Special case: exiting with escape key
+    if ( aKeyEvent.iCode == EKeyEscape )
+        {
+        SetOldTitleL();
+        return CAknDialog::OfferKeyEventL( aKeyEvent, aType );
+        }
+
+    TKeyResponse res = EKeyWasNotConsumed;
+    res = Control(KVmDetailsDialog)->OfferKeyEventL( aKeyEvent, aType );
+    if (res != EKeyWasNotConsumed) 
+        {
+        return res;
+        }
+    
+    res = CAknDialog::OfferKeyEventL( aKeyEvent, aType );
+    return res;
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::OkToExitL
+// Called when softkeys are pressed.
+// -----------------------------------------------------------------------------
+//
+TBool CVmDetailsDialog::OkToExitL( TInt aButtonId )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::OkToExitL =>" );
+    TBool retVal( EFalse );
+    // Translate the button presses into commands
+    if ( aButtonId == EAknSoftkeyBack )
+        { 
+        // terminate the diallog.
+        SetOldTitleL();
+        retVal = ETrue;
+        }
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::OkToExitL <=" );
+    return retVal;
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::SetOldTitleL
+// Saves the old title text.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::SetOldTitleL()
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::SetOldTitleL =>" );
+    if ( !iOldTitlePaneText )
+        {
+        VMBLOGSTRING( "VMBX: CVmDetailsDialog::SetOldTitleL: already set" );
+        return; // already set
+        }
+
+    CAknTitlePane* titlePane = static_cast<CAknTitlePane*> 
+        ( iEikonEnv->AppUiFactory()->StatusPane()->ControlL( 
+            TUid::Uid( EEikStatusPaneUidTitle ) ) );
+    titlePane->SetText( iOldTitlePaneText ); // takes ownership
+    iOldTitlePaneText = NULL;
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::SetOldTitleL =>" );
+    }
+
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::HandlePropertyNotificationEventL
+// Called when key value is set.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::HandlePropertyNotificationEventL( const TDesC& aValue )
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::HandlePropertyNotificationEventL \
+    =>" );
+    StartObservingL();
+    TLex lexer( aValue );
+    TInt value = KErrNotFound;
+       User::LeaveIfError( lexer.Val( value ) );
+    if ( value == 0 ) // message is not set
+        {
+        // Exit the details dialog
+        TryExitL( EAknSoftkeyBack );
+        }
+    else // new message set
+        {
+        // Update listbox context:
+        CAknSingleHeadingStyleListBox* listbox = 
+           static_cast<CAknSingleHeadingStyleListBox*>( 
+                                               Control( KVmDetailsDialog ) );
+        MDesCArray* itemList = listbox->Model()->ItemTextArray();
+        CDesCArray* itemArray = static_cast<CDesCArray*>( itemList );
+        PopulateListboxItemsL( *itemArray );
+        listbox->HandleItemAdditionL();
+        }
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::HandlePropertyNotificationEventL \
+    <=" );
+    }
+// -----------------------------------------------------------------------------
+// CVmDetailsDialog::StartObservingL
+// Starts observing for key value changes.
+// -----------------------------------------------------------------------------
+//
+void CVmDetailsDialog::StartObservingL()
+    {
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::StartObservingL =>" );
+    iObserver->ObservePropertyChangeL( KCRUidVoiceMailbox, KVmSummaryInfoIsSet );
+    VMBLOGSTRING( "VMBX: CVmDetailsDialog::StartObservingL <=" );
+    }
+
+//  End of File