/*
* 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 Conflict popup implementation
*
*/
#include "cesmrconflictpopup.h"
#include "mesmrcalentry.h"
#include "mesmrmeetingrequestentry.h"
#include <AknInfoPopupNoteController.h>
#include <StringLoader.h>
#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"
// Unnamed namespace for local definitions
namespace{
const TInt KTimeDelayBeforeShow(0); // 0 Seconds
const TInt KTimeForView(5000); // 5 Seconds
const TInt KTimeStringLength(20);
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 );
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 );
}
CPtrC16Array* strings = new( ELeave ) CPtrC16Array( aNumLines );
CleanupStack::PushL( strings );
TPtr des( text->Des() );
// Wrap string
AknTextUtils::WrapToStringAndClipL(
aSource,
*lineWidthArray,
*font,
des );
// Trim trailing line feeds
des.TrimRight();
CleanupStack::PopAndDestroy( 2, lineWidthArray );
CleanupStack::Pop( text );
}
return text;
}
}//namespace
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CESMRConflictPopup::NewL
// ---------------------------------------------------------------------------
//
CESMRConflictPopup* CESMRConflictPopup::NewL( MESMRCalEntry& aEntry)
{
FUNC_LOG;
CESMRConflictPopup* self = new (ELeave) CESMRConflictPopup();
CleanupStack::PushL( self );
self->ConstructL(aEntry);
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::CESMRConflictPopup
// ---------------------------------------------------------------------------
//
CESMRConflictPopup::CESMRConflictPopup()
{
FUNC_LOG;
//do nothing
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::~CESMRConflictPopup
// ---------------------------------------------------------------------------
//
CESMRConflictPopup::~CESMRConflictPopup()
{
FUNC_LOG;
delete iNote;
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::ConstructL
// ---------------------------------------------------------------------------
//
void CESMRConflictPopup::ConstructL(MESMRCalEntry& aEntry)
{
FUNC_LOG;
if ( MESMRCalEntry::EESMRCalEntryMeetingRequest == aEntry.Type() )
{
iEntry = static_cast<MESMRMeetingRequestEntry*>(&aEntry);
}
else
{
User::Leave( KErrNotSupported );
}
iNote = CAknInfoPopupNoteController::NewL();
InitializeL();
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::PrepareDisplayStringL
// ---------------------------------------------------------------------------
//
void CESMRConflictPopup::PrepareDisplayStringL()
{
FUNC_LOG;
RCPointerArray<CCalEntry> entryArray;
CleanupClosePushL( entryArray );
TInt ret = iEntry->FetchConflictingEntriesL( entryArray );
if( ret == KErrNotFound )
{
User::Leave( KErrNotFound );
}
// Pointer descriptor for R_QTN_MEET_REQ_CONFLICT_UNNAMED
TPtrC unnamedTitle( KNullDesC );
// Actual title to shown in popup
TPtrC meetingTitle( KNullDesC );
// 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.Set( entryArray[ 0 ]->SummaryL() );
meetingLocation.Set( entryArray[ 0 ]->LocationL() );
if ( ( meetingLocation.Length() == 0 ) && ( meetingTitle.Length() == 0 ) )
{
// if no title, set unnamed text:
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* conflictLabel = StringLoader::LoadLC(
R_QTN_MEET_REQ_CONFLICTS_WITH_LABEL,
env );
HBufC* timeFormatString = StringLoader::LoadLC(
R_QTN_TIME_USUAL_WITH_ZERO,
env );
TBuf<KTimeStringLength> startBuf;
TBuf<KTimeStringLength> endBuf;
startTime.FormatL( startBuf, *timeFormatString );
endTime.FormatL( endBuf, *timeFormatString );
CPtrC16Array* strings = new( ELeave ) CPtrC16Array( KArrayGranularity );
CleanupStack::PushL( strings );
strings->AppendL( startBuf ); //start time string
strings->AppendL( endBuf ); //end time string
HBufC* finalTimeBuf =
StringLoader::LoadLC(
R_QTN_MEET_REQ_TIME_SEPARATOR,
*strings,
env );
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 );
// Prepare location
locationBuf = ClipTextL( meetingLocation, KNumLocationLines );
if ( locationBuf )
{
CleanupStack::PushL( locationBuf );
meetingLocation.Set( *locationBuf );
}
strings->AppendL( meetingLocation );
}
else
{
// Prepare location
locationBuf = ClipTextL(
meetingLocation,
KNumTitleLines + KNumLocationLines );
if ( locationBuf )
{
CleanupStack::PushL( locationBuf );
meetingLocation.Set( *locationBuf );
}
strings->AppendL( meetingLocation );
strings->AppendL( KNullDesC() );
}
HBufC* displayString = StringLoader::LoadLC(
R_MEET_REQ_CONFLICT_TEXT_FORMAT,
*strings,
env );
// 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( conflictLabel );
if ( unnamedTitle.Length() > 0 )
{
CleanupStack::PopAndDestroy(); // R_QTN_MEET_REQ_CONFLICT_UNNAMED
}
CleanupStack::PopAndDestroy( &entryArray );
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::ShowPopup
// ---------------------------------------------------------------------------
//
void CESMRConflictPopup::ShowPopup()
{
FUNC_LOG;
TRAPD( error, PrepareDisplayStringL());
if ( error != KErrNone )
{
CEikonEnv::Static()-> // codescanner::eikonenvstatic
HandleError(error);
}
iNote->ShowInfoPopupNote();
}
// ---------------------------------------------------------------------------
// CESMRConflictPopup::InitializeL
// ---------------------------------------------------------------------------
//
void CESMRConflictPopup::InitializeL()
{
FUNC_LOG;
iNote->SetTimeDelayBeforeShow(KTimeDelayBeforeShow); // 2 Seconds
iNote->SetTimePopupInView(KTimeForView); // 5 Seconds
}
// EOF