meetingrequest/mrgui/mrfieldbuilderplugin/src/cesmrdescriptionfield.cpp
branchRCL_3
changeset 64 3533d4323edc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuilderplugin/src/cesmrdescriptionfield.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,599 @@
+/*
+* 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:  ESMR Description (summary) field implementation
+ *
+*/
+
+#include "cesmrdescriptionfield.h"
+#include "mesmrlistobserver.h"
+#include "cesmreditor.h"
+#include "cesmrrichtextlink.h"
+#include "esmrfieldbuilderdef.h"
+#include "cesmrfeaturesettings.h"
+#include "cesmrglobalnote.h"
+#include "nmrlayoutmanager.h"
+#include "nmrbitmapmanager.h"
+//<cmail>
+#include "cesmrurlparserplugin.h"
+//</cmail>
+
+#include <calentry.h>
+#include <StringLoader.h>
+#include <esmrgui.rsg>
+#include <AknUtils.h>
+#include <AknsBasicBackgroundControlContext.h>
+#include <eikmfne.h>
+
+// DEBUG
+#include "emailtrace.h"
+
+namespace // codescanner::namespace
+    {
+    /// Field's component count, iDescription
+    const TInt KComponentCount( 1 );
+    }//namespace
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::NewL
+// ---------------------------------------------------------------------------
+//
+CESMRDescriptionField* CESMRDescriptionField::NewL( )
+    {
+    FUNC_LOG;
+    CESMRDescriptionField* self = new (ELeave) CESMRDescriptionField;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::~CESMRDescriptionField
+// ---------------------------------------------------------------------------
+//
+CESMRDescriptionField::~CESMRDescriptionField( )
+    {
+    FUNC_LOG;
+    delete iLocationLink;
+    delete iFeatures;
+    delete iBgControlContext;
+    delete iUrlParser;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::InitializeL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::InitializeL()
+    {
+    FUNC_LOG;
+    // Do nothing
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::InternalizeL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::InternalizeL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    CCalEntry& entry = aEntry.Entry ( );
+    HBufC* summary = entry.DescriptionL().AllocLC ( );
+
+    // externalize is done only when there is text and its NOT the default one.
+    if ( summary->Length ( )> 0 &&
+            iDescription->DefaultText().Compare (*summary )!= 0 )
+        {
+        iDescription->ClearSelectionAndSetTextL ( *summary );
+        if ( FeaturesL().FeatureSupported(
+                CESMRFeatureSettings::EESMRUIMnFwIntegration ) )
+            {
+            StoreLinkL( aEntry );
+            }
+        }
+
+    CleanupStack::PopAndDestroy ( summary );
+
+    // this is needed to be re-called here, otherwise the CEikEdwin
+    // does not get correctly instantiated with default text
+    iDescription->FocusChanged(EDrawNow);
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::ExternalizeL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::ExternalizeL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    HBufC* buf = iDescription->GetTextInHBufL();
+    CCalEntry& entry = aEntry.Entry();
+    
+    if( buf )
+        {
+        CleanupStack::PushL( buf );
+
+        if( iDescription->DefaultText().Compare( *buf ) != 0 )
+            {
+            // Edited text. Add link to description text
+            HBufC* newBuf = AddLinkToTextL( *buf );
+            if( newBuf )
+                {
+                CleanupStack::PopAndDestroy( buf );
+                buf = newBuf;
+                CleanupStack::PushL( buf );
+                }
+            entry.SetDescriptionL( *buf );
+            }
+        else if ( iLocationLink )
+            {
+            // Location link set
+            entry.SetDescriptionL( iLocationLink->Value() );
+            }
+        else if ( entry.DescriptionL().Length() != 0 )
+            {
+            // Clear old description
+            entry.SetDescriptionL( KNullDesC );
+            }
+        CleanupStack::PopAndDestroy( buf );
+        }
+    else if( iLocationLink )
+        {
+        entry.SetDescriptionL( iLocationLink->Value() );
+        }
+    else
+        {
+        entry.SetDescriptionL( KNullDesC );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::SetOutlineFocusL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::SetOutlineFocusL( TBool aFocus )
+    {
+    FUNC_LOG;
+    CESMRField::SetOutlineFocusL ( aFocus );
+    if ( aFocus )
+        {
+        ChangeMiddleSoftKeyL(EESMRCmdSaveMR,R_QTN_MSK_SAVE);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CESMRDescriptionField::OfferKeyEventL(const TKeyEvent& aEvent,
+        TEventCode aType )
+    {
+    FUNC_LOG;
+    TKeyResponse response( EKeyWasNotConsumed);
+    response = iDescription->OfferKeyEventL( aEvent, aType );
+
+    if ( aType == EEventKey &&
+         ( aEvent.iScanCode != EStdKeyUpArrow &&
+          aEvent.iScanCode != EStdKeyDownArrow ))
+        {
+        iDescription->DrawDeferred();
+        }
+
+    return response;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::HandleEdwinSizeEventL
+// ---------------------------------------------------------------------------
+//
+TBool CESMRDescriptionField::HandleEdwinSizeEventL(CEikEdwin* /*aEdwin*/,
+        TEdwinSizeEvent /*aType*/, TSize aSize )
+    {
+    FUNC_LOG;
+    if ( aSize != iSize )
+        {
+        iSize = aSize;
+
+        if ( iObserver )
+            {
+            iObserver->ControlSizeChanged ( this );
+            }
+
+        if( iDescription->LineCount() != iLineCount )
+            {
+            // Line count has changed, the whole component needs
+            // to be redrawn
+            DrawDeferred();
+
+            // Also if new line count is less than previous one, we
+            // need to redraw the parent also (this is the last field).
+            // Otherwise the removed line will remain on the screen
+            // until parent is redrawn.
+            if( iDescription->LineCount() < iLineCount )
+                {
+                Parent()->DrawDeferred();
+                }
+            iLineCount = iDescription->LineCount();
+            }
+        }
+
+    return ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::HandleEdwinEventL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::HandleEdwinEventL(
+        CEikEdwin* aEdwin,TEdwinEvent aEventType)
+    {
+    FUNC_LOG;
+    if ( aEdwin == iDescription
+         && aEventType == EEventTextUpdate )
+        {
+        HBufC* text = iDescription->GetTextInHBufL();
+        if ( text )
+            {
+            CleanupStack::PushL( text );
+            TInt textLength( text->Length() );
+            if ( iDescription->GetLimitLength() <= textLength )
+                {
+                NotifyEventAsyncL( EESMRCmdSizeExceeded );
+                }
+            CleanupStack::PopAndDestroy( text );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::CESMRDescriptionField
+// ---------------------------------------------------------------------------
+//
+CESMRDescriptionField::CESMRDescriptionField()
+    {
+    FUNC_LOG;
+    SetFieldId( EESMRFieldDescription );
+    SetFocusType( EESMRHighlightFocus );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::ConstructL()
+    {
+    FUNC_LOG;
+    iDescription = CESMREditor::NewL( this, 1, KTextLimit,
+                                    CEikEdwin::EResizable |
+                                    CEikEdwin::EAvkonEditor );
+    iDescription->SetEdwinSizeObserver( this );
+    iDescription->SetEdwinObserver( this );
+    CESMRField::ConstructL( iDescription );
+
+    HBufC* buf = StringLoader::LoadLC( R_QTN_MEET_REQ_DETAILS_FIELD );
+    iDescription->SetDefaultTextL( buf ); // ownership transferred
+    CleanupStack::Pop( buf );
+
+    // Setting background instead of theme skin
+    NMRBitmapManager::TMRBitmapStruct bitmapStruct;
+    bitmapStruct = NMRBitmapManager::GetBitmapStruct( NMRBitmapManager::EMRBitmapInputCenter );
+
+    TRect initialisationRect( 0, 0, 0, 0 );
+    iBgControlContext = CAknsBasicBackgroundControlContext::NewL(
+                bitmapStruct.iItemId,
+                initialisationRect,
+                EFalse );
+
+    iDescription->SetSkinBackgroundControlContextL( iBgControlContext );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::ListObserverSet
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::ListObserverSet()
+    {
+    FUNC_LOG;
+    iDescription->SetListObserver( iObserver );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::GetCursorLineVerticalPos
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::GetCursorLineVerticalPos(TInt& aUpper, TInt& aLower)
+    {
+    aLower = iDescription->CurrentLineNumber() * iDescription->RowHeight();
+    aUpper = aLower - iDescription->RowHeight();
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::StoreLinkL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::StoreLinkL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    TPtrC urlPointer;
+    TInt position;
+    position = UrlParserL().FindLocationUrl( aEntry.Entry().DescriptionL(),
+                                           urlPointer );
+
+    if ( position >= KErrNone )
+        {
+        HBufC* description =
+            HBufC::NewL( aEntry.Entry().DescriptionL().Length() );
+        CleanupStack::PushL( description );
+        TPtr descriptionPointer( description->Des() );
+        descriptionPointer.Append( aEntry.Entry().DescriptionL() );
+        descriptionPointer.Delete( position, urlPointer.Length() );
+        descriptionPointer.TrimLeft();
+        if ( description->Length() != 0 )
+            {
+            iDescription->ClearSelectionAndSetTextL( *description );
+            }
+        else
+            {
+            iDescription->ClearSelectionAndSetTextL(
+                    iDescription->DefaultText() );
+            }
+        CleanupStack::PopAndDestroy( description );
+
+        if ( iLocationLink )
+            {
+            delete iLocationLink;
+            iLocationLink = NULL;
+            }
+        HBufC* showOnMapBuf =
+            StringLoader::LoadLC( R_MEET_REQ_LINK_SHOW_ON_MAP );
+        iLocationLink = CESMRRichTextLink::NewL( position,
+                                     showOnMapBuf->Length(),
+                                     urlPointer,
+                                     CESMRRichTextLink::ETypeLocationUrl,
+                                     CESMRRichTextLink::ETriggerKeyOk );
+        CleanupStack::PopAndDestroy( showOnMapBuf );
+
+        StoreGeoValueL( aEntry.Entry(),
+                        urlPointer );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::AddLinkToTextL
+// ---------------------------------------------------------------------------
+//
+HBufC* CESMRDescriptionField::AddLinkToTextL( const TDesC& aBuf )
+    {
+    FUNC_LOG;
+    if( iLocationLink )
+        {
+        TInt newTextLen = aBuf.Length() + iLocationLink->Value().Length() + 1;
+        HBufC* retBuf = HBufC::NewL( newTextLen );
+
+        retBuf->Des().Append( iLocationLink->Value() );
+        _LIT( KParagraphSeparator, "\x2029" ); // unicode paragraph separator
+        // add the separator after url
+        retBuf->Des().Append( KParagraphSeparator );
+        retBuf->Des().Append( aBuf );
+
+        return retBuf;
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::FeaturesL
+// ---------------------------------------------------------------------------
+//
+CESMRFeatureSettings& CESMRDescriptionField::FeaturesL()
+    {
+    FUNC_LOG;
+    if ( !iFeatures )
+        {
+        iFeatures = CESMRFeatureSettings::NewL();
+        }
+
+    return *iFeatures;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::ExecuteGenericCommandL
+// ---------------------------------------------------------------------------
+//
+TBool CESMRDescriptionField::ExecuteGenericCommandL(
+        TInt aCommand )
+    {
+    FUNC_LOG;
+    TBool isUsed( EFalse );
+    if ( EESMRCmdSizeExceeded == aCommand )
+        {
+        CESMRGlobalNote::ExecuteL(
+                CESMRGlobalNote::EESMRCannotDisplayMuchMore );
+
+        HBufC* text = iDescription->GetTextInHBufL();
+        CleanupDeletePushL( text );
+        if ( text )
+            {
+            TInt curPos = iDescription->CursorPos();
+            if( curPos > iDescription->GetLimitLength() - 1 )
+                curPos = iDescription->GetLimitLength() - 1;
+            HBufC* newText =
+                text->Des().Mid( 0,
+                        iDescription->GetLimitLength() - 1 ).AllocLC();
+
+            iDescription->SetTextL ( newText );
+            CleanupStack::PopAndDestroy( newText );
+            newText = NULL;
+
+            iDescription->SetCursorPosL (curPos, EFalse );
+            iDescription->HandleTextChangedL();
+            iDescription->UpdateScrollBarsL();
+            SetFocus(ETrue);
+            }
+        CleanupStack::PopAndDestroy( text );
+        isUsed = ETrue;
+        }
+    else if ( EESMRCmdDisableWaypointIcon == aCommand )
+        {
+        isUsed = ETrue;
+        
+        // Clear location link
+        delete iLocationLink;
+        iLocationLink = NULL;
+        }
+    
+    return isUsed;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::CountComponentControls
+// ---------------------------------------------------------------------------
+//
+TInt CESMRDescriptionField::CountComponentControls() const
+    {
+    return KComponentCount;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::ComponentControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CESMRDescriptionField::ComponentControl( TInt aInd ) const
+    {
+    if( aInd == 0 )
+        {
+        return iDescription;
+        }
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::SizeChanged
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::SizeChanged()
+    {
+    TRect rect( Rect() );
+
+    // Optimization: Layouting only when necessary
+    if( iFieldRect != rect )
+        {
+        rect = NMRLayoutManager::GetFieldRowLayoutRect( rect, 1 ).Rect();
+
+        TAknLayoutText editorLayoutText = NMRLayoutManager::GetLayoutText(
+                        rect,
+                        NMRLayoutManager::EMRTextLayoutMultiRowTextEditor );
+
+        TRect editorRect = editorLayoutText.TextRect();
+
+        TRect bgRect( editorRect );
+        // Move focus rect so that it's relative to field's position.
+        bgRect.Move( -Position() );
+        if( iSize.iHeight > 0 )
+            {
+            bgRect.SetHeight( iSize.iHeight );
+            }
+        SetFocusRect( bgRect );
+
+        iDescription->SetRect(
+                TRect( editorRect.iTl,
+                        TSize( editorRect.Width(), iSize.iHeight ) ) );
+
+        // Set also correct font for description field
+        TRAP_IGNORE( iDescription->SetFontL( editorLayoutText.Font() ) );
+
+        iFieldRect = rect;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::MinimumSize
+// ---------------------------------------------------------------------------
+//
+TSize CESMRDescriptionField::MinimumSize()
+    {
+    TRect rect( Parent()->Rect() );
+    TRect listRect =
+        NMRLayoutManager::GetLayoutRect(
+                rect,
+                NMRLayoutManager::EMRLayoutListArea ).Rect();
+    TRect fieldRect =
+        NMRLayoutManager::GetFieldLayoutRect( listRect, 1 ).Rect();
+    TRect rowRect =
+        NMRLayoutManager::GetFieldRowLayoutRect( fieldRect, 1 ).Rect();
+    TRect viewerRect =
+        NMRLayoutManager::GetLayoutText(
+                rowRect,
+                NMRLayoutManager::EMRTextLayoutMultiRowTextEditor ).TextRect();
+
+    fieldRect.Resize( 0, iSize.iHeight - viewerRect.Height() );
+
+    return fieldRect.Size();
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRRepeatUntilField::SetContainerWindowL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::SetContainerWindowL(
+        const CCoeControl& aContainer )
+    {
+    CCoeControl::SetContainerWindowL( aContainer );
+    iDescription->SetContainerWindowL( aContainer );
+
+    iDescription->SetParent( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::StoreGeoValueL
+// ---------------------------------------------------------------------------
+//
+void CESMRDescriptionField::StoreGeoValueL(
+        CCalEntry& aCalEntry,
+        const TDesC& aLocationUrl )
+    {
+    TReal lat, lon;
+    CCalGeoValue* geoVal = aCalEntry.GeoValueL();
+
+    if ( !geoVal || ! geoVal->GetLatLong( lat, lon ) )
+        {
+        // GEO value not set. Convert URL
+        geoVal = UrlParserL().CreateGeoValueLC( aLocationUrl );
+        aCalEntry.SetGeoValueL( *geoVal );
+        CleanupStack::Pop( geoVal );
+
+        NotifyEventL( EESMRCmdEnableWaypointIcon );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRDescriptionField::UrlParserL
+// ---------------------------------------------------------------------------
+//
+CESMRUrlParserPlugin& CESMRDescriptionField::UrlParserL()
+    {
+    if ( !iUrlParser )
+        {
+        iUrlParser = CESMRUrlParserPlugin::NewL();
+        }
+
+    return *iUrlParser;
+    }
+
+// EOF