meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrviewerattendeesfield.cpp
changeset 0 8466d47a6819
child 1 12c456ceeff2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrviewerattendeesfield.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,628 @@
+/*
+* Copyright (c) 2007-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:  ESMR UI Container class
+*
+*/
+
+#include "cesmrviewerattendeesfield.h"
+
+#include "mesmrlistobserver.h"
+#include "cesmrborderlayer.h"
+#include "cesmrrichtextlink.h"
+#include "esmrfieldbuilderdef.h"
+#include "cesmrlayoutmgr.h"
+#include "cmrlabel.h"
+#include "nmrlayoutmanager.h"
+
+#include <caluser.h>
+#include <calentry.h>
+#include <StringLoader.h>
+#include <esmrgui.rsg>
+#include <CPbkContactEngine.h>
+#include <AknBidiTextUtils.h>
+#include "cmrlistpane.h"
+
+// DEBUG
+#include "emailtrace.h"
+
+using namespace ESMRLayout;
+
+// CONSTANTS
+/// Unnamed namespace for local definitions
+namespace { // codescanner::namespace
+
+_LIT( KNewLine, "\f" );
+const TInt KMaxLineCount = 4;
+const TInt KNumberOfComponents = 2;
+const TInt KMargin = 5;
+
+static void RPointerArrayResetAndDestroy( TAny* aPtr )
+    {
+    static_cast<RPointerArray<CESMRRichTextLink>*>( aPtr )->ResetAndDestroy();
+    }
+
+} // namespace
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::NewL
+// -----------------------------------------------------------------------------
+//
+CESMRViewerAttendeesField* CESMRViewerAttendeesField::NewL(
+        CCalAttendee::TCalRole aRole )
+    {
+    FUNC_LOG;
+    CESMRViewerAttendeesField* self = 
+        new (ELeave) CESMRViewerAttendeesField( aRole );
+    CleanupStack::PushL ( self );
+    self->ConstructL ( );
+    CleanupStack::Pop ( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::ConstructL( )
+    {
+    FUNC_LOG;
+
+    SetFieldId ( (iRole == CCalAttendee::EReqParticipant) ? EESMRFieldAttendee
+            : EESMRFieldOptAttendee );
+
+    iTitle = CMRLabel::NewL();
+    iTitle->SetParent( this );
+    
+    iRichTextViewer = CESMRRichTextViewer::NewL (this );
+    iRichTextViewer->SetEdwinSizeObserver ( this );
+    iRichTextViewer->SetLinkObserver (this );
+    iRichTextViewer->SetParent( this );
+
+    HBufC* label = StringLoader::LoadLC (iRole == CCalAttendee::EReqParticipant ?
+            R_QTN_MEET_REQ_LABEL_REQUIRED : R_QTN_MEET_REQ_LABEL_OPT );
+    iTitle->SetTextL ( *label );
+
+    CleanupStack::PopAndDestroy( label );
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::InitializeL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::InitializeL()
+    {
+    FUNC_LOG;
+    TAknLayoutText layoutText =
+        NMRLayoutManager::GetLayoutText( Rect(), 
+                NMRLayoutManager::EMRTextLayoutMultiRowTextEditor );
+    iRichTextViewer->SetFontL( layoutText.Font(), iLayout );
+    UpdateAttendeesListL();
+    //wake up current contact menu selection by calling this
+    iRichTextViewer->FocusChanged( ENoDrawNow );
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::SetOutlineFocusL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::SetOutlineFocusL( TBool aFocus )
+    {
+    FUNC_LOG;
+    CESMRField::SetOutlineFocusL( aFocus );
+    iRichTextViewer->SetFocus( aFocus );
+    
+    if ( aFocus )
+        {
+        SetMiddleSoftKeyVisible( ETrue );
+        }
+    else
+        {
+        TInt oldShowAttendees = iShowAllAttendees;
+        iShowAllAttendees = EFalse;
+        if (oldShowAttendees != iShowAllAttendees)
+            {
+            UpdateAttendeesListL();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::InternalizeL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::InternalizeL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    CCalEntry& entry = aEntry.Entry();
+    RPointerArray<CCalAttendee>& attendees = entry.AttendeesL();
+    iCalAttendees.ReserveL(attendees.Count());
+    for (TInt i=0; i<attendees.Count ( ); ++i )
+        {
+        CCalAttendee* attendee = attendees[i];
+        if ( attendee->RoleL() == iRole )
+            {
+            iCalAttendees.AppendL( attendee );
+            }
+        }
+
+    UpdateAttendeesListL();
+
+    if ( iRichTextViewer->TextLength() > 0 )
+        {
+        //wake up current contact menu selection by calling this
+        iRichTextViewer->FocusChanged( ENoDrawNow );
+        }
+    else
+        {
+        iObserver->RemoveControl( iFieldId );
+        }
+    iDisableRedraw = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::GetMinimumVisibleVerticalArea
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::GetMinimumVisibleVerticalArea(
+        TInt& aUpper, TInt& aLower)
+    {
+    FUNC_LOG;
+    aLower = iRichTextViewer->CurrentLineNumber() * iRichTextViewer->RowHeight() + iTitle->Size().iHeight;
+    aUpper = aLower - iRichTextViewer->RowHeight() - iTitle->Size().iHeight;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::ListObserverSet
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::ListObserverSet( )
+    {
+    FUNC_LOG;
+    iRichTextViewer->SetListObserver( iObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::SizeChanged
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::SizeChanged( )
+    {
+    FUNC_LOG;
+    // Store iRichTextViewer original width.
+    TInt richTextViewerWidth = iRichTextViewer->Size().iWidth;
+    
+    // Get field's rect
+    TRect rect( Rect() );
+    
+    // First row for title
+    TAknLayoutRect rowLayoutRect =
+        NMRLayoutManager::GetFieldRowLayoutRect( rect, 1 );
+    TRect rowRect = rowLayoutRect.Rect();
+    
+    // Layout title to first row's rect
+    TAknTextComponentLayout titleLayout =
+        NMRLayoutManager::GetTextComponentLayout( 
+                NMRLayoutManager::EMRTextLayoutText );
+    AknLayoutUtils::LayoutLabel( iTitle, rect, titleLayout );
+    // Color should be overrided after layouting
+    // If this function leaves we'll have to use default color
+    TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( 
+                                *iTitle, 
+                                EColorLabelText,
+                                KRgbBlack ));
+    
+    // Move upper left corner below first line and get second row's rect.
+    rect.iTl.iY += rowRect.Height();
+    rowLayoutRect =
+        NMRLayoutManager::GetFieldRowLayoutRect( rect, 2 );
+    rowRect = rowLayoutRect.Rect();
+    
+    // Get default 1 row editor rect.
+    TAknLayoutText viewerLayoutText =
+        NMRLayoutManager::GetLayoutText( rowRect, 
+                NMRLayoutManager::EMRTextLayoutMultiRowTextEditor );
+    TRect viewerRect = viewerLayoutText.TextRect();
+    // Resize resize it's height according to actual height required by edwin.
+    viewerRect.Resize( 0, iExpandedSize.iHeight - viewerRect.Height() );
+    iRichTextViewer->SetRect( viewerRect );  
+    
+    // Update AttendeesList only if iRichTextViewer width was changed.
+    // This happens when screen orientation changes e.g. This check
+    // also prevents recursive calls to UpdateAttendeesListL since
+    // it causes edwin size changed event.
+    if ( iRichTextViewer->Size().iWidth != richTextViewerWidth )
+        {
+        // Ignore leave, there's nothing we can do if leave occurs.
+        TRAP_IGNORE( UpdateAttendeesListL() );
+        //wake up current contact menu selection by calling this
+        iRichTextViewer->FocusChanged(ENoDrawNow);
+        }
+
+    DrawDeferred();
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CESMRViewerAttendeesField::OfferKeyEventL( const TKeyEvent& aEvent,
+        TEventCode aType )
+    {
+    FUNC_LOG;
+    TKeyResponse response = EKeyWasNotConsumed;
+    response = iRichTextViewer->OfferKeyEventL ( aEvent, aType );
+
+    //track up and down events to change MSK
+    if ( aType == EEventKey )
+        {
+        if ( aEvent.iScanCode == EStdKeyUpArrow
+             || aEvent.iScanCode == EStdKeyDownArrow )
+            {
+            const CESMRRichTextLink* link = 
+                iRichTextViewer->GetSelectedLink ( );
+            if( link )
+                {
+                if (link->Type() == CESMRRichTextLink::ETypeShowAll )
+                    {
+                    ChangeMiddleSoftKeyL(
+                            EESMRCmdShowAllAttendees, R_QTN_MEET_REQ_SHOW_ALL);
+                    }
+                else
+                    {
+                    RestoreMiddleSoftKeyL();
+                    SetMiddleSoftKeyVisible( ETrue );
+                    }
+                }
+            }
+        }
+
+    return response;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRViewerAttendeesField::SetContainerWindowL()
+// ---------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::SetContainerWindowL( 
+        const CCoeControl& aContainer )
+    {
+    CESMRField::SetContainerWindowL( aContainer );
+    iRichTextViewer->SetContainerWindowL( aContainer );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRViewerAttendeesField::MinimumSize()
+// ---------------------------------------------------------------------------
+//
+TSize CESMRViewerAttendeesField::MinimumSize()
+    {
+    // Parent rect will be list area later --> no need to calculate it manually.
+    TRect parentRect = Parent()->Rect();
+    TRect contentRect = NMRLayoutManager::GetLayoutRect( 
+            parentRect, NMRLayoutManager::EMRLayoutListArea ).Rect();
+    // We have two lines;  title and richtextviewer.
+    TRect fieldRect = 
+        NMRLayoutManager::GetFieldLayoutRect( contentRect, 2 ).Rect();
+    // Get row size for second row (richtext viewer).
+    TRect rowRect = 
+        NMRLayoutManager::GetFieldRowLayoutRect( fieldRect, 2 ).Rect();
+    // Get size for default 1 line editor.
+    TRect viewerRect = NMRLayoutManager::GetLayoutText( 
+            rowRect, 
+            NMRLayoutManager::EMRTextLayoutMultiRowTextEditor ).TextRect();
+    // Adjust field size so that there's room for expandable editor.
+    fieldRect.Resize( 0, iExpandedSize.iHeight - viewerRect.Height() );
+    return fieldRect.Size();
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRViewerAttendeesField::ExecuteGenericCommandL()
+// ---------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::ExecuteGenericCommandL( TInt aCommand )
+    {
+    FUNC_LOG;
+    switch ( aCommand )
+        {
+        case EESMRCmdClipboardCopy:
+            {
+            iRichTextViewer->CopyCurrentLinkValueToClipBoardL();
+            break;
+            }
+        case EESMRCmdShowAllAttendees:
+            {
+            iShowAllAttendees = ETrue;
+            UpdateAttendeesListL();
+        
+            RestoreMiddleSoftKeyL();
+            //wake up current contact menu selection by calling this
+            iRichTextViewer->FocusChanged(ENoDrawNow);
+            break;
+            }
+        case EAknSoftkeySelect:
+            {
+            iRichTextViewer->LinkSelectedL();
+            break;
+            }
+        default:
+            // do nothing for now..
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::HandleEdwinSizeEventL
+// -----------------------------------------------------------------------------
+//
+TBool CESMRViewerAttendeesField::HandleEdwinSizeEventL(CEikEdwin* /*aEdwin*/,
+        TEdwinSizeEvent /*aType*/, TSize aSize )
+    {
+    FUNC_LOG;
+    iExpandedSize = aSize;
+    if ( iObserver && iDisableRedraw )
+        {
+        iObserver->ControlSizeChanged ( this );
+        }
+    return iDisableRedraw;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::HandleRichTextLinkSelection
+// -----------------------------------------------------------------------------
+//
+TBool CESMRViewerAttendeesField::HandleRichTextLinkSelection(
+        const CESMRRichTextLink* aLink )
+    {
+    FUNC_LOG;
+    if ( aLink->Type() == CESMRRichTextLink::ETypeShowAll )
+        {
+        iShowAllAttendees = ETrue;
+        TRAPD( err, UpdateAttendeesListL() );
+
+        if ( err == KErrNone )
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::CountComponentControls
+// -----------------------------------------------------------------------------
+//
+TInt CESMRViewerAttendeesField::CountComponentControls( ) const
+    {
+    FUNC_LOG;
+    TInt count = KNumberOfComponents;
+    return count;
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::ComponentControl
+// -----------------------------------------------------------------------------
+//
+CCoeControl* CESMRViewerAttendeesField::ComponentControl( TInt aInd ) const
+    {
+    FUNC_LOG;
+    switch ( aInd )
+        {
+        case 0:
+            {
+            return iTitle;
+            }
+        case 1:
+            {
+            return iRichTextViewer;
+            }
+        default:
+            {
+            return NULL;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::~CESMRViewerAttendeesField
+// -----------------------------------------------------------------------------
+//
+CESMRViewerAttendeesField::~CESMRViewerAttendeesField( )
+    {
+    FUNC_LOG;
+    delete iTitle;
+    delete iRichTextViewer;
+    iCalAttendees.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::CESMRViewerAttendeesField
+// -----------------------------------------------------------------------------
+//
+CESMRViewerAttendeesField::CESMRViewerAttendeesField(
+        CCalAttendee::TCalRole aRole ) :
+    iRole( aRole)
+    {
+    FUNC_LOG;
+    //do nothing
+    }
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::ClipTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC* CESMRViewerAttendeesField::ClipTextLC( 
+        const TDesC& aText, const CFont& aFont, TInt aWidth )
+    {
+    FUNC_LOG;
+    HBufC* text = HBufC::NewLC( aText.Length() + KAknBidiExtraSpacePerLine );
+    TPtr textPtr = text->Des();
+    AknBidiTextUtils::ConvertToVisualAndClip( 
+            aText, textPtr, aFont, aWidth, aWidth );
+    return text;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::UpdateAttendeesListL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::UpdateAttendeesListL()
+    {
+    FUNC_LOG;
+    RBuf buffer; // codescanner::resourcenotoncleanupstack
+    buffer.CleanupClosePushL();
+
+    iRichTextViewer->SetMargins( KMargin );
+    
+    TSize oldSize = Size();
+
+    TRect rect( Rect() );
+    TAknLayoutText layoutText =
+        NMRLayoutManager::GetLayoutText( rect, 
+                NMRLayoutManager::EMRTextLayoutMultiRowTextEditor );
+    TRect viewerRect = layoutText.TextRect();
+    TInt maxLineWidth = viewerRect.Size().iWidth;
+    const CFont* font = layoutText.Font();    
+
+    if ( maxLineWidth > 0 )  // control size is set
+        {
+        TInt linkCount = iCalAttendees.Count();
+        TBool notAllShown(EFalse);
+        if ( !iShowAllAttendees )
+            {
+            linkCount = Min(KMaxLineCount, iCalAttendees.Count() );
+            notAllShown = ( linkCount != iCalAttendees.Count() );
+            }
+        
+        RPointerArray<CESMRRichTextLink> attendeeLinks;  // codescanner::resourcenotoncleanupstack
+        TCleanupItem arrayCleanup( RPointerArrayResetAndDestroy, &attendeeLinks );
+        CleanupStack::PushL( arrayCleanup );
+        attendeeLinks.ReserveL( linkCount );
+        
+        for ( TInt i = 0; i < linkCount; ++i )
+            {
+            CCalAttendee* attendee = iCalAttendees[i];
+            
+            // Attendee email address.
+            TPtrC addr = attendee->Address();
+            // Attendee common name.
+            TPtrC name = attendee->CommonName();
+            // Actual text to be added to attendee field (email or common name).
+            TPtrC text = addr;
+
+            // If attendee has common name, use it instead.
+            if ( name.Length() > 0 )
+                {
+                text.Set( name );
+                }
+            
+            HBufC* clippedTextHBufC = ClipTextLC( text, *font, maxLineWidth );
+            TPtr clippedText = clippedTextHBufC->Des();
+            clippedText.Trim();
+            
+            if ( clippedText.Length() > 0 )
+                {
+                CESMRRichTextLink* link = CESMRRichTextLink::NewL(
+                        buffer.Length(), 
+                        clippedText.Length() + 
+                            KAddressDelimeterSemiColon().Length(), 
+                        addr,
+                        CESMRRichTextLink::ETypeEmail,
+                        CESMRRichTextLink::ETriggerKeyRight );
+                CleanupStack::PushL( link );
+                attendeeLinks.AppendL( link );
+                CleanupStack::Pop( link );
+        
+                // Append text and semicolon to buffer.
+                buffer.ReAllocL( buffer.Length() +
+                                 clippedText.Length() +
+                                 KAddressDelimeterSemiColon().Length() + 
+                                 KNewLine().Length() );
+                buffer.Append( clippedText );
+                buffer.Append( KAddressDelimeterSemiColon );
+                buffer.Append( KNewLine );
+                }
+            
+            CleanupStack::PopAndDestroy( clippedTextHBufC );
+            }
+        
+        // If there are more lines in use than KMaxLineCount and
+        // we don't want to show all attendees, leave only
+        // KMaxLineCount-1 attendees and add 'show all'
+        // link to the end.
+        if ( notAllShown )
+            {
+            // Create and append 'show all' link.
+            CESMRRichTextLink* showAllLink;
+            HBufC* showAllBuf = StringLoader::LoadLC( R_QTN_MEET_REQ_SHOW_ALL );
+            buffer.ReAllocL( buffer.Length() + 
+                             showAllBuf->Length() );
+            showAllLink = CESMRRichTextLink::NewL( buffer.Length ( ),
+                    showAllBuf->Length(), KNullDesC,
+                    CESMRRichTextLink::ETypeShowAll,
+                    CESMRRichTextLink::ETriggerKeyOk );
+            buffer.Append( *showAllBuf );
+            CleanupStack::PopAndDestroy( showAllBuf );
+            CleanupStack::PushL( showAllLink );
+            attendeeLinks.AppendL( showAllLink );
+            CleanupStack::Pop( showAllLink );
+            }
+            
+        // Remove unnecessary new line from the end of buffer.
+        else if ( buffer.Length() >= KNewLine().Length() )
+            {
+            buffer.SetLength( buffer.Length() - KNewLine().Length() );
+            }
+
+        if ( buffer.Length() > 0 )
+            {
+            iRichTextViewer->SetTextL( &buffer );
+
+            // Add all links to iRichTextViewer.
+            while ( attendeeLinks.Count() > 0 )
+                {
+                CESMRRichTextLink* link = attendeeLinks[0];
+                CleanupStack::PushL( link );
+                attendeeLinks.Remove( 0 );
+                iRichTextViewer->AddLinkL( link );
+                CleanupStack::Pop( link );
+                }
+            }
+
+        CleanupStack::PopAndDestroy( &attendeeLinks );
+        
+        TSize newSize = Size();
+        if (oldSize != newSize)
+            {
+            CMRListPane* parent = static_cast<CMRListPane*>(Parent());
+            parent->SizeChanged();
+            }
+        }
+    CleanupStack::PopAndDestroy( &buffer );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CESMRViewerAttendeesField::HandlePointerEventL
+// -----------------------------------------------------------------------------
+//
+void CESMRViewerAttendeesField::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+    {
+    CCoeControl::HandlePointerEventL(aPointerEvent);
+    }
+// End of file
+