meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrconflictpopup.cpp
branchRCL_3
changeset 26 67369d1b217f
parent 24 b5fbb9b25d57
--- a/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrconflictpopup.cpp	Tue May 11 15:57:15 2010 +0300
+++ b/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrconflictpopup.cpp	Tue May 25 12:23:16 2010 +0300
@@ -23,6 +23,10 @@
 #include <eikenv.h>
 #include <esmrgui.rsg>
 #include <avkon.rsg>
+#include <ct/rcpointerarray.h>
+#include <AknUtils.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <layoutmetadata.cdl.h>
 
 #include "emailtrace.h"
 
@@ -31,26 +35,89 @@
 
 const TInt KTimeDelayBeforeShow(0);  // 0 Seconds
 const TInt KTimeForView(5000);          // 5 Seconds
-const TInt KZero(0);
 const TInt KTimeStringLength(20);
-const TInt KMaxSummaryLength(25);
+const TInt KArrayGranularity( 4 );
+
+const TInt KPortraitWindowVariety( 4 );
+const TInt KLandscapeWindowVariety( 7 );
+const TInt KTextLineVariety( 5 );
+
+const TInt KNumTitleLines( 1 );
+const TInt KNumLocationLines( 2 );
+
+/**
+ * Clips given text and allocates new buffer if needed.
+ * @param aSource text to clip
+ * @param aNumLines number of popup note lines available for visual text.
+ * @return new buffer or NULL if aSource must not be clipped
+ */
+
+HBufC* ClipTextL( const TDesC& aSource, TInt aNumLines )
+    {
+    TRect mainPane;
+    AknLayoutUtils::LayoutMetricsRect(
+                AknLayoutUtils::EMainPane,
+                mainPane );
+
+    // Get the correct popup window text line layout
+    TInt windowVariety( KPortraitWindowVariety );
+    if ( Layout_Meta_Data::IsLandscapeOrientation() )
+        {
+        windowVariety = KLandscapeWindowVariety;
+        }
+
+    TAknWindowComponentLayout popupNoteWindow =
+            AknLayoutScalable_Avkon::popup_preview_text_window( windowVariety );
+    TAknLayoutRect popupNoteRect;
+    popupNoteRect.LayoutRect( mainPane, popupNoteWindow );
+
+    TAknTextComponentLayout popupNoteTextLine =
+            AknLayoutScalable_Avkon::popup_preview_text_window_t3( KTextLineVariety );
+    TAknLayoutText textLayout;
+    textLayout.LayoutText( popupNoteRect.Rect(), popupNoteTextLine );
 
-_LIT( KNewLine, "\n");
-_LIT( KMessageStart, "(");
-_LIT( KMessageEnd, ")");
-_LIT( KStringCont, "...\n");
-_LIT (KSpace , " " );
-const TInt KFullTimeStringSize(256);
+    TInt lineWidth( textLayout.TextRect().Width() );
+    const CFont* font = textLayout.Font();
+
+    HBufC* text = NULL;
+
+    if ( font->TextWidthInPixels( aSource ) > lineWidth )
+        {
+        // Text must be clipped to fit
+        // Allocate result buffer and reserve space for line feeds
+        text = HBufC::NewLC(
+                aSource.Length() + aNumLines );
+
+        CArrayFix<TInt>* lineWidthArray =
+                new( ELeave ) CArrayFixFlat<TInt>( aNumLines );
+        CleanupStack::PushL( lineWidthArray );
+        for ( TInt i = 0; i < aNumLines; ++i )
+            {
+            lineWidthArray->AppendL( lineWidth );
+            }
 
-void CalEntryPointerArrayCleanup( TAny* aArray )
-    {
-    RPointerArray<CCalEntry>* entryArray =
-        static_cast<RPointerArray<CCalEntry>*>( aArray );
+        CPtrC16Array* strings = new( ELeave ) CPtrC16Array( aNumLines );
+        CleanupStack::PushL( strings );
+        TPtr des( text->Des() );
+
+        // Wrap string
+        AknTextUtils::WrapToStringAndClipL(
+                aSource,
+                *lineWidthArray,
+                *font,
+                des );
 
-    entryArray->ResetAndDestroy();
-    entryArray->Close();
+        // Trim trailing line feeds
+        des.TrimRight();
+
+        CleanupStack::PopAndDestroy( 2, lineWidthArray );
+        CleanupStack::Pop( text );
+        }
+
+    return text;
     }
 
+
 }//namespace
 
 // ======== MEMBER FUNCTIONS ========
@@ -118,51 +185,56 @@
 void CESMRConflictPopup::PrepareDisplayStringL()
     {
     FUNC_LOG;
-    RPointerArray<CCalEntry> entryArray;
-    CleanupStack::PushL(
-            TCleanupItem(
-                CalEntryPointerArrayCleanup,
-                &entryArray ) );
-    
+    RCPointerArray<CCalEntry> entryArray;
+    CleanupClosePushL( entryArray );
+
     TInt ret = iEntry->FetchConflictingEntriesL( entryArray );
     if( ret == KErrNotFound )
         {
         User::Leave( KErrNotFound );
         }
 
-    TInt numEnteries = entryArray.Count();
-    TInt dispStrLength(KZero);
-    TBuf <KFullTimeStringSize> meetingTitle     ;
-    TBuf <KFullTimeStringSize> meetingLocation ;
-    TTime startTime     ;
-    TTime endTime       ;
+    // Pointer descriptor for R_QTN_MEET_REQ_CONFLICT_UNNAMED
+    TPtrC unnamedTitle( KNullDesC );
+
+    // Actual title to shown in popup
+    TPtrC meetingTitle( KNullDesC );
 
-    if (numEnteries != KZero)
+    // Location to show in popup
+    TPtrC meetingLocation( KNullDesC );
+
+    TTime startTime;
+    TTime endTime;
+
+    CCoeEnv* env = CCoeEnv::Static();
+
+    if ( entryArray.Count() > 0 )
         {// there is atleast one entry
         // get the first conflicting entry and set the string for display
-        meetingTitle    = entryArray[KZero]->SummaryL();
-        meetingLocation = entryArray[KZero]->LocationL();
+        meetingTitle.Set( entryArray[ 0 ]->SummaryL() );
+        meetingLocation.Set( entryArray[ 0 ]->LocationL() );
 
-        
-        if ( ( meetingLocation.Length()== 0 ) && ( meetingTitle.Length() == 0 ) )
+        if ( ( meetingLocation.Length() == 0 ) && ( meetingTitle.Length() == 0 ) )
         	{
             // if no title, set unnamed text:
-            HBufC* title = StringLoader::LoadLC ( R_QTN_MEET_REQ_CONFLICT_UNNAMED );
-            meetingTitle.Copy( *title );
-            CleanupStack::PopAndDestroy( title );
-        	}
-        
-        dispStrLength = meetingTitle.Length() + meetingLocation.Length();
-        startTime   = entryArray[KZero]->StartTimeL().TimeLocalL();
-        endTime     = entryArray[KZero]->EndTimeL().TimeLocalL();
+            HBufC* title = StringLoader::LoadLC(
+                    R_QTN_MEET_REQ_CONFLICT_UNNAMED,
+                    env );
+            unnamedTitle.Set( *title );
+            meetingTitle.Set( unnamedTitle );
+            }
+
+        startTime = entryArray[ 0 ]->StartTimeL().TimeLocalL();
+        endTime = entryArray[ 0 ]->EndTimeL().TimeLocalL();
         }
 
-    HBufC*  stringHolder =
-            StringLoader::LoadLC(R_QTN_MEET_REQ_CONFLICTS_WITH_LABEL);
-    dispStrLength = stringHolder->Length() + meetingTitle.Length()
-                    +  meetingLocation.Length() + KFullTimeStringSize;
+    HBufC*  conflictLabel = StringLoader::LoadLC(
+            R_QTN_MEET_REQ_CONFLICTS_WITH_LABEL,
+            env );
 
-    HBufC* timeFormatString = CCoeEnv::Static()->AllocReadResourceLC(R_QTN_TIME_USUAL_WITH_ZERO);
+    HBufC* timeFormatString = StringLoader::LoadLC(
+            R_QTN_TIME_USUAL_WITH_ZERO,
+            env );
 
     TBuf<KTimeStringLength> startBuf;
     TBuf<KTimeStringLength> endBuf;
@@ -170,49 +242,103 @@
     startTime.FormatL( startBuf, *timeFormatString );
     endTime.FormatL( endBuf, *timeFormatString );
 
-    CDesCArrayFlat* strings = new(ELeave) CDesCArrayFlat( 2 );
+    CPtrC16Array* strings = new( ELeave ) CPtrC16Array( KArrayGranularity );
     CleanupStack::PushL( strings );
-    strings->AppendL( startBuf ); //First string
-    strings->AppendL( endBuf ); //Second string
+    strings->AppendL( startBuf ); //start time string
+    strings->AppendL( endBuf ); //end time string
 
     HBufC* finalTimeBuf =
-        StringLoader::LoadL(
+        StringLoader::LoadLC(
                 R_QTN_MEET_REQ_TIME_SEPARATOR,
                 *strings,
-                CEikonEnv::Static() ); // codescanner::eikonenvstatic
-    CleanupStack::PopAndDestroy( strings );
-    CleanupStack::PushL( finalTimeBuf );
+                env );
 
-    HBufC* displayString = HBufC::NewLC(dispStrLength);
-    displayString->Des().Append(stringHolder->Des());
-    displayString->Des().Append(KNewLine);
-    displayString->Des().Append(finalTimeBuf->Des());
+    if ( meetingLocation.Length() > 0 )
+        {
+        // format Meeting location
+        HBufC* formatText = StringLoader::LoadLC(
+                R_MEET_REQ_CONFLICT_LOCATION_FORMAT,
+                meetingLocation,
+                env );
+        meetingLocation.Set( *formatText );
+        }
+
+    // Format final display string
+    strings->Reset();
+    strings->AppendL( *conflictLabel );
+    strings->AppendL( *finalTimeBuf );
+
+    HBufC* titleBuf = NULL;
+    HBufC* locationBuf = NULL;
 
+    if ( meetingTitle.Length() > 0 )
+        {
+        // Prepare title
+        titleBuf = ClipTextL( meetingTitle, KNumTitleLines );
+        if ( titleBuf )
+            {
+            CleanupStack::PushL( titleBuf );
+            meetingTitle.Set( *titleBuf );
+            }
+        strings->AppendL( meetingTitle );
 
-    displayString->Des().Append(KMessageStart);
-    // Check the length of meetingTitle
-    // If its greater than some KMaxSummaryLength value then
-    // truncate to some reasonable value & append KStringCont
-    if ( meetingTitle.Length() > KMaxSummaryLength )
-        {
-        displayString->Des().Append(meetingTitle.Ptr(),KMaxSummaryLength);
-        displayString->Des().Append(KStringCont);
+        // Prepare location
+        locationBuf = ClipTextL( meetingLocation, KNumLocationLines );
+        if ( locationBuf )
+            {
+            CleanupStack::PushL( locationBuf );
+            meetingLocation.Set( *locationBuf );
+            }
+        strings->AppendL( meetingLocation );
         }
     else
         {
-        displayString->Des().Append(meetingTitle);
-        displayString->Des().Append(KSpace);
+        // Prepare location
+        locationBuf = ClipTextL(
+                meetingLocation,
+                KNumTitleLines + KNumLocationLines );
+        if ( locationBuf )
+            {
+            CleanupStack::PushL( locationBuf );
+            meetingLocation.Set( *locationBuf );
+            }
+        strings->AppendL( meetingLocation );
+        strings->AppendL( KNullDesC() );
         }
 
-    displayString->Des().Append(meetingLocation);
-    displayString->Des().Append(KMessageEnd);
+    HBufC* displayString = StringLoader::LoadLC(
+            R_MEET_REQ_CONFLICT_TEXT_FORMAT,
+            *strings,
+            env );
 
-    iNote->SetTextL(displayString->Des() );
+    // Trim trailing white space
+    displayString->Des().TrimRight();
+
+    // Set display string to popup note
+    iNote->SetTextL( *displayString );
 
+    // Clean allocated buffers
     CleanupStack::PopAndDestroy( displayString );
+    if ( locationBuf )
+        {
+        CleanupStack::PopAndDestroy( locationBuf );
+        }
+    if ( titleBuf )
+        {
+        CleanupStack::PopAndDestroy( titleBuf );
+        }
+    if ( meetingLocation.Length() > 0 )
+        {
+        CleanupStack::PopAndDestroy(); // R_MEET_REQ_CONFLICT_LOCATION_FORMAT
+        }
     CleanupStack::PopAndDestroy( finalTimeBuf );
+    CleanupStack::PopAndDestroy( strings );
     CleanupStack::PopAndDestroy( timeFormatString );
-    CleanupStack::PopAndDestroy( stringHolder );
+    CleanupStack::PopAndDestroy( conflictLabel );
+    if ( unnamedTitle.Length() > 0 )
+        {
+        CleanupStack::PopAndDestroy(); // R_QTN_MEET_REQ_CONFLICT_UNNAMED
+        }
     CleanupStack::PopAndDestroy( &entryArray );
     }