/*
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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: Internal class definition for WidgetUI application.
*
*/
#include "cpspublisher.h"
#include <LiwServiceHandler.h>
#include <LiwVariant.h>
#include <LiwGenericParam.h>
#include <Liwcommon.h>
#include <liwcommon.hrh>
#include <AknsFrameBackgroundControlContext.h>
#include <fbs.h>
#include <aknsdrawutils.h>
// TODO use global definitions!
_LIT8( KCPService, "Service.ContentPublishing" );
_LIT8( KCPInterface, "IDataSource" );
_LIT8( KType, "type" );
_LIT( KCpData, "cp_data" );
_LIT8( KPublisherId, "publisher" );
_LIT8( KContentType, "content_type" );
_LIT8( KContentId, "content_id" );
_LIT8( KDataMap, "data_map" );
_LIT8( KItem, "item" );
_LIT8( KAdd, "Add" );
_LIT(KP,"ai3templatedwidget");
_LIT(KCT,"wideimage");
_LIT8( KImageKey, "image1");
_LIT8( KMask, "_mask");
_LIT(KP1,"ai3homescreen");
_LIT(KCT1,"wideimage");
_LIT( KImageContainer, "image_container" );
_LIT8( KWidth, "width");
_LIT8( KHeight, "height");
_LIT8( KFilter, "filter" );
_LIT8( KResults, "results");
_LIT8( KOperation, "operation" );
_LIT8( KRequestNotification, "RequestNotification" );
_LIT( KUpdate, "update" );
_LIT8( KChangeInfo, "change_info" );
const TInt KSkinGfxInnerRectShrink = 5;
static void DoResetAndDestroy( TAny* aPtr )
{
__ASSERT_DEBUG( aPtr, User::Invariant() );
reinterpret_cast< RCriteriaArray* >( aPtr )->ResetAndDestroy();
}
// -----------------------------------------------------------------------------
// InvertBitmap
// Sets white pixels black and other ones white.
// -----------------------------------------------------------------------------
static void InvertBitmap( CFbsBitmap*& aBitmap )
{
TSize inSize = aBitmap->SizeInPixels();
TBitmapUtil bitmapUtil( aBitmap );
bitmapUtil.Begin( TPoint(0,0) );
TInt xPos;
for ( TInt yPos = 0; yPos < inSize.iHeight; yPos++ )
{
bitmapUtil.SetPos( TPoint( 0,yPos ));
for ( xPos = 0; xPos < inSize.iWidth; xPos++ )
{
//Inverts the pixel colors.
TInt pix = bitmapUtil.GetPixel();
if( pix == 0xff )
{
bitmapUtil.SetPixel( 0x00 );
}
else
{
bitmapUtil.SetPixel( 0xff );
}
bitmapUtil.IncXPos();
}
}
bitmapUtil.End();
}
// -----------------------------------------------------------------------------
// LoadMaskBitmapL
// Loads a mask bitmap from the skin.
// -----------------------------------------------------------------------------
static void LoadMaskBitmapL(
CFbsBitmap*& aBitmap,
TSize aSize)
{
const TRect rect( 0, 0, aSize.iWidth, aSize.iHeight );
TRect shrunkRect( rect );
shrunkRect.Shrink( KSkinGfxInnerRectShrink, KSkinGfxInnerRectShrink );
CAknsFrameBackgroundControlContext* skinContext =
CAknsFrameBackgroundControlContext::NewL( KAknsIIDQsnHomeBgWidget, rect, shrunkRect, EFalse );
CleanupStack::PushL( skinContext );
// Create an off-screen bitmap and context (CFbsBitGc)
// Also remember to take care of destruction / cleanup during leaves
aBitmap = new (ELeave) CFbsBitmap();
CleanupStack::PushL( aBitmap );
User::LeaveIfError( aBitmap->Create( aSize, EGray256 ) );
CFbsBitGc* bitGc = NULL;
CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( aBitmap );
CleanupStack::PushL( bitmapDevice );
User::LeaveIfError( bitmapDevice->CreateContext( bitGc ) );
// Draw the content on the off-screen bitmap
AknsDrawUtils::DrawBackground( AknsUtils::SkinInstance(), skinContext,
NULL, *bitGc, TPoint(0,0), rect, KAknsDrawParamNoClearUnderImage );
CleanupStack::PopAndDestroy( bitmapDevice );
CleanupStack::Pop( aBitmap );
CleanupStack::PopAndDestroy( skinContext );
}
CCpsPublisher* CCpsPublisher::NewL()
{
CCpsPublisher* self = new (ELeave) CCpsPublisher();
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
CCpsPublisher::~CCpsPublisher()
{
TRAP_IGNORE(ExecuteRegistrationCommandL( KLiwOptCancel ));
if( iCpsInterface )
{
iCpsInterface->Close();
iCpsInterface = NULL;
}
if( iServiceHandler )
{
iServiceHandler->Reset();
delete iServiceHandler;
iServiceHandler = NULL;
}
delete iMaskBitmap;
__UHEAP_MARKEND;
}
CLiwDefaultMap* ElementSizeFilterLC()
{
//Create filter criteria for requested entries in form of LIW map:
CLiwDefaultMap* filter = CLiwDefaultMap::NewLC();
filter->InsertL( KPublisherId, TLiwVariant( KP1 ));
filter->InsertL( KContentType, TLiwVariant( KCT1 ));
filter->InsertL( KContentId, TLiwVariant( KImageContainer ));
return filter;
}
void UpdateElementSizeL( CLiwDefaultMap *outDataMap, TSize& aSize )
{
TLiwVariant variant;
variant.PushL();
if ( outDataMap->FindL( KWidth, variant ) )
{
variant.Get( aSize.iWidth );
}
variant.Reset();
if ( outDataMap->FindL( KHeight, variant ) )
{
variant.Get( aSize.iHeight );
}
CleanupStack::PopAndDestroy( &variant );
}
CCpsPublisher::CCpsPublisher()
{
}
void CCpsPublisher::ConstructL()
{
__UHEAP_MARK;
RDebug::Printf("CCpsPublisher::InitCPS");
InitCpsInterfaceL();
RDebug::Printf("CCpsPublisher::Register");
ExecuteRegistrationCommandL( 0 );
RDebug::Printf("CCpsPublisher::GetBitmapSize");
GetBitmapSizeL();
RDebug::Printf("CCpsPublisher::EndConstructL");
}
TSize CCpsPublisher::BitmapSize()
{
return iSize;
}
void CCpsPublisher::PublishBitmapL( CFbsBitmap& aBitmap, const TDesC& aBundleName )
{
// Load the mask bitmap from skin
if( !iMaskBitmap ||
aBitmap.SizeInPixels() != iMaskBitmap->SizeInPixels())
{
RDebug::Printf("CCpsPublisher::LoadMaskBitmapL");
delete iMaskBitmap;
iMaskBitmap = NULL;
LoadMaskBitmapL( iMaskBitmap, aBitmap.SizeInPixels() );
InvertBitmap( iMaskBitmap );
}
TInt handle = aBitmap.Handle();
TInt maskHandle = KErrBadHandle;
if( iMaskBitmap )
{
maskHandle = iMaskBitmap->Handle();
}
RDebug::Printf("CCpsPublisher::PublishBitmapL");
AddImageHandleL( KP() ,KCT(), aBundleName,
handle, maskHandle, KImageKey() );
}
void CCpsPublisher::GetBitmapSizeL()
{
CLiwDefaultMap *outDataMap = CLiwDefaultMap::NewLC();
CLiwDefaultMap* filter = ElementSizeFilterLC();
ExecuteCommandL( filter, outDataMap, KCpData );
CleanupStack::PopAndDestroy( filter );
UpdateElementSizeL( outDataMap, iSize );
CleanupStack::PopAndDestroy( outDataMap );
}
void CCpsPublisher::ExecuteRegistrationCommandL(
TUint aOption )
{
CLiwDefaultMap* filter = ElementSizeFilterLC();
filter->InsertL( KOperation, TLiwVariant( KUpdate ));
CLiwGenericParamList& inParamList = iServiceHandler->InParamListL();
CLiwGenericParamList& outParamList = iServiceHandler->OutParamListL();
// Fill in input list for RequestNotification command
inParamList.AppendL( TLiwGenericParam( KType,TLiwVariant( KCpData )));
inParamList.AppendL( TLiwGenericParam( KFilter ,TLiwVariant( filter )));
iCpsInterface->ExecuteCmdL(
KRequestNotification,
inParamList,
outParamList,
aOption,
this );
outParamList.Reset();
inParamList.Reset();
CleanupStack::PopAndDestroy( filter );
}
TInt CCpsPublisher::HandleNotifyL(
TInt /*aCmdId*/,
TInt /*aEventId*/,
CLiwGenericParamList& aEventParamList,
const CLiwGenericParamList& /*aInParamList*/ )
{
__UHEAP_MARK;
TInt pos(0);
aEventParamList.FindFirst( pos, KChangeInfo );
if (pos != KErrNotFound)
{
// Get list of maps
TLiwVariant variant = ( aEventParamList )[pos].Value();
variant.PushL();
const CLiwList* changeMapsList = variant.AsList();
TPtrC operation;
// Iter through list content
for (TInt i = 0; i < changeMapsList->Count(); ++i)
{
if ( changeMapsList->AtL( i, variant ))
{
const CLiwMap* map = variant.AsMap();
// Check what triggered a notification
if ( map->FindL( KOperation, variant ))
{
operation.Set( variant.AsDes());
}
if ( operation == KUpdate )
{
GetBitmapSizeL();
}
}
}
CleanupStack::PopAndDestroy( &variant );
}
__UHEAP_MARKEND;
return KErrNone;
}
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
void CCpsPublisher::AddImageHandleL(
const TDesC& aPublisherId, const TDesC& aContentType,
const TDesC& aContentId, const TInt& aHandle, const TInt& aMaskHandle,
const TDesC8& aImageKey )
{
__UHEAP_MARK;
CLiwGenericParamList& inparam = iServiceHandler->InParamListL();
CLiwGenericParamList& outparam = iServiceHandler->OutParamListL();
TLiwGenericParam cptype( KType, TLiwVariant( KCpData ));
cptype.PushL();
inparam.AppendL( cptype );
CLiwDefaultMap* cpdatamap = CLiwDefaultMap::NewLC();
CLiwDefaultMap* map = CLiwDefaultMap::NewLC();
// Add bitmap handle to data map
map->InsertL( aImageKey, TLiwVariant( aHandle )); // key - aKey, value - map (stringsMap)
HBufC8* maskKey = HBufC8::NewLC( aImageKey.Length() + KMask().Length() );
TPtr8 maskKeyPtr = maskKey->Des();
maskKeyPtr.Append(aImageKey);
maskKeyPtr.Append(KMask);
map->InsertL( maskKeyPtr, TLiwVariant( aMaskHandle ));
CleanupStack::PopAndDestroy( maskKey );
// Create content data map
cpdatamap->InsertL( KPublisherId, TLiwVariant( aPublisherId ));
cpdatamap->InsertL( KContentType, TLiwVariant( aContentType ));
cpdatamap->InsertL( KContentId, TLiwVariant( aContentId ));
cpdatamap->InsertL( KDataMap, TLiwVariant(map) );
TLiwGenericParam item( KItem, TLiwVariant( cpdatamap ));
item.PushL();
inparam.AppendL( item );
iCpsInterface->ExecuteCmdL( KAdd , inparam, outparam);
CleanupStack::PopAndDestroy(); // item
CleanupStack::PopAndDestroy( map );
CleanupStack::PopAndDestroy( cpdatamap );
CleanupStack::PopAndDestroy(); // cptype
outparam.Reset();
inparam.Reset();
__UHEAP_MARKEND;
}
void CCpsPublisher::ExecuteCommandL(CLiwDefaultMap* aInFilter, CLiwDefaultMap* aOutDataMap, const TDesC16& aRegistry )
{
CLiwGenericParamList* inParamList = &iServiceHandler->InParamListL();
CLiwGenericParamList* outParamList = &iServiceHandler->OutParamListL();
TLiwGenericParam type( KType, TLiwVariant( aRegistry ) );
inParamList->AppendL( type );
//append filter to input param
TLiwGenericParam item( KFilter, TLiwVariant( aInFilter ));
inParamList->AppendL( item );
// It is assumed that interface is already initiated
iCpsInterface->ExecuteCmdL( _L8("GetList"), *inParamList, *outParamList);
type.Reset();
item.Reset();
inParamList->Reset();
//extracts data map
TInt pos = 0;
outParamList->FindFirst( pos, KResults );
if( pos != KErrNotFound )
// results present
{
//extract iterator on results list
TLiwVariant variant = (*outParamList)[pos].Value();
CLiwIterable* iterable = variant.AsIterable();
iterable->Reset();
//get next result
if( iterable->NextL( variant ) )
{
//extract content map
CLiwDefaultMap *map = CLiwDefaultMap::NewLC();
variant.Get( *map );
if( map->FindL( KDataMap, variant) )
{
variant.Get( *aOutDataMap );
}
variant.Reset();
CleanupStack::PopAndDestroy( map );
}
iterable->Reset();
}
outParamList->Reset();
}
void CCpsPublisher::InitCpsInterfaceL()
{
if( !iServiceHandler )
{
iServiceHandler = CLiwServiceHandler::NewL();
}
CLiwGenericParamList& inParam = iServiceHandler->InParamListL();
CLiwGenericParamList& outParam = iServiceHandler->OutParamListL();
RCriteriaArray a;
TCleanupItem item( DoResetAndDestroy, &a );
CleanupStack::PushL( item );
CLiwCriteriaItem* crit = CLiwCriteriaItem::NewLC( KLiwCmdAsStr, KCPInterface,
KCPService );
crit->SetServiceClass( TUid::Uid(KLiwClassBase) );
a.AppendL(crit);
CleanupStack::Pop( crit );
iServiceHandler->AttachL( a );
iServiceHandler->ExecuteServiceCmdL( *crit, inParam, outParam );
CleanupStack::PopAndDestroy(); // item;
// find service interface
TInt pos = 0;
MLiwInterface* msgInterface = NULL;
outParam.FindFirst( pos, KCPInterface );
if ( pos != KErrNotFound )
{
msgInterface = (outParam)[pos].Value().AsInterface();
}
outParam.Reset();
inParam.Reset();
iCpsInterface = msgInterface;
}
// END OF FILE