--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgutils/unidatautils/unidatamodel/src/UniSmilModel.cpp Mon May 03 12:29:07 2010 +0300
@@ -0,0 +1,2578 @@
+/*
+* Copyright (c) 2005 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:
+* CUniSmilModel, Storage for Smil presentation data.
+*
+*
+*/
+
+
+// ========== INCLUDE FILES ================================
+
+
+#include <e32def.h>
+#include <eikenv.h>
+#include <eikfutil.h> // CopyFile
+
+#include <mtclbase.h> // for CBaseMtm
+#include <msvstd.h> // for TMsvId
+#include <msvids.h> // for KMsvTempIndexEntryId
+#include <msvstore.h>
+#include <mmsvattachmentmanager.h>
+#include <mmsvattachmentmanagersync.h>
+#include <cmsvattachment.h>
+
+#include <bautils.h> // NearestLanguageFile
+
+#include <coemain.h>
+
+// LAF
+/*
+#include <AknUtils.h>
+#include <AknLayoutScalable_Avkon.cdl.h>
+#include <AknLayoutScalable_Apps.cdl.h>
+#include <LayoutMetadata.cdl.h>
+*/
+
+// DOM
+#include <gmxmldocument.h>
+#include <gmxmlnode.h>
+#include <gmxmlelement.h>
+
+// MsgMedia
+#include <MsgMedia.hrh>
+#include <MsgMediaInfo.h>
+#include <MmsConformance.h>
+#include <mmsversion.h>
+#include <MsgTextInfo.h>
+
+
+// MsgDataUTILS
+#include <UniDataModel.rsg> // Viewer/Editor Mimetype strings
+#include "UniModelConst.h" // Definitions and enums
+#include "UniDataUtils.h"
+#include "UniSmilSlide.h"
+#include "UniSmilModel.h"
+#include "UniObjectList.h"
+#include "UniObject.h"
+#include "UniTextObject.h"
+#include "UniMimeInfo.h"
+#include "UniSmilUtils.h"
+#include "UniSmilParams.h"
+
+#include "fileprotectionresolver.h" // EFileProtDrm2
+#include "MsgMimeTypes.h"
+
+// Logging
+//#include "//MsgDataUTILSLOGGing.h"
+
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+
+_LIT( KSmilIntFormat, "%d" );
+_LIT( KSmilMsecFormat, "%dms" );
+const TUint KSlideArrayGranularity( 16 );
+
+// SMIL size estimates
+const TInt KSizeMandatorySmilTags = 148;
+const TInt KSizeHeadOneRegion = 85;
+const TInt KSizeHeadTwoRegions = 170;
+const TInt KSizeEmptyPar = 27;
+const TInt KSizeNonEmptyPar = 41;
+const TInt KSizeAudioTag = 38;
+const TInt KSizeImageTag = 52;
+const TInt KSizeTextTag = 51;
+const TInt KSizeVideoTag = 53;
+
+const TInt KSizeLowResHeight = 208;
+const TInt KSizeLowResWidth = 176;
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::NewL
+//
+// Factory method.
+// ---------------------------------------------------------
+//
+EXPORT_C CUniSmilModel* CUniSmilModel::NewLC( RFs& aFs,
+ CBaseMtm& aMtm,
+ CUniDataUtils& aData,
+ CUniObjectList& aObjectList )
+ {
+ CUniSmilModel* self = new ( ELeave )
+ CUniSmilModel( aFs, aMtm, aData, aObjectList );
+
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::NewL
+//
+// Factory method.
+// ---------------------------------------------------------
+//
+EXPORT_C CUniSmilModel* CUniSmilModel::NewL( RFs& aFs,
+ CBaseMtm& aMtm,
+ CUniDataUtils& aData,
+ CUniObjectList& aObjectList )
+ {
+ CUniSmilModel* self = NewLC( aFs, aMtm, aData, aObjectList );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::CUniSmilModel
+//
+// Constructor.
+// ---------------------------------------------------------
+//
+CUniSmilModel::CUniSmilModel( RFs& aFs,
+ CBaseMtm& aMtm,
+ CUniDataUtils& aData,
+ CUniObjectList& aObjectList ) :
+ iFs( aFs ),
+ iMtm( aMtm ),
+ iData( aData ),
+ iObjectList( aObjectList ),
+ iSlideLayout( EUniUndefinedLayout ),
+ iSmilParams( 0 ),
+ iScreenSize( 0, 0 ),
+ iSizeEstimateUpToDate( EFalse ),
+ iSizeEstimate( 0 )
+ {
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::~CUniSmilModel
+//
+// Destructor.
+// ---------------------------------------------------------
+//
+CUniSmilModel::~CUniSmilModel()
+ {
+ if (iSlideArray)
+ {
+ iSlideArray->ResetAndDestroy();
+ }
+ delete iSlideArray;
+ delete iSmilParams;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::ParseL
+//
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CUniSmilModel::ParseL( CMDXMLDocument* aDom )
+ {
+ //MsgDataUTILSLOGGER_ENTERFN( "CUniSmilModel::ParseL()" );
+
+ Reset();
+
+ if ( aDom )
+ {
+ TRAPD( error, DoPresentationFromDomL( aDom ) );
+ if ( error )
+ {
+ Reset();
+ User::Leave( error );
+ }
+ else
+ {
+ iParseResult |= EParsedFromSmil;
+ }
+ }
+ else
+ {
+ // No SMIL -> Do presentation from object list
+ if ( IsMessageSlide() )
+ {
+ // Determine layout. Make slide.
+ DoNoSmilOneSlideL();
+ }
+ else
+ {
+ // Do slide for each media object
+ DoNoSmilManySlideL();
+ }
+ iParseResult |= EParsedFromList;
+ }
+
+ return iParseResult;
+ }
+
+
+//**********************************************************
+//*
+//* SMIL COMPOSING FUNCTIONS
+//*
+//**********************************************************
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::¨ComposeL
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CMDXMLDocument* CUniSmilModel::ComposeL()
+ {
+ //MsgDataUTILSLOGGER_ENTERFN( "CUniSmilModel::ComposeL()" );
+
+ // Reset region id's
+ iTextRegionId.Set( KNullDesC );
+ iImageRegionId.Set( KNullDesC );
+
+ // Read default smil parameters
+ if( !iSmilParams )
+ {
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Creating smil parameter structures." );
+ iSmilParams = CUniSmilParams::NewL( iFs );
+ }
+
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Creating new DOM." );
+ //delete iDom;
+ //iDom = 0;
+ CMDXMLDocument* dom = CMDXMLDocument::NewLC();
+
+ // Create smil node
+ TPtrC name( KSMILWREleSmil );
+ CMDXMLElement* root = CMDXMLElement::NewLC( ETrue, dom, name );
+ // Append
+ dom->DocumentElement()->AppendChild( root ); // Ownership to dom
+ CleanupStack::Pop( root );
+
+ // Create Head
+ CreateHeadL( dom, root );
+
+ // Create Body
+ CreateBodyL( dom, root );
+
+ // TODO: Move to Document and to use smil list
+ //iObjectList.CreateSmilAttachmentL( smilAttaId, iDom, iFs );
+ CleanupStack::Pop( dom );
+ return dom;
+ }
+
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::RemoveEmptySlides
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::RemoveEmptySlides()
+ {
+ TInt count = iSlideArray->Count();
+ // Must be done from end to beginning because
+ // slides might be removed.
+ while ( count-- )
+ {
+ if ( !iSlideArray->At( count )->ObjectCount() )
+ {
+ RemoveSlide( count );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddSlideL
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::AddSlideL( TInt aSlideNum )
+ {
+ DoAddSlideL( aSlideNum );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::RemoveSlide
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::RemoveSlide( TInt aSlideNum )
+ {
+ if ( !IsSlide( aSlideNum ) )
+ {
+ //__ASSERT_DEBUG( EFalse, DataUtilsPanic( EMmsNotASlide ) );
+ return;
+ }
+ CUniSmilSlide* slide = iSlideArray->At( aSlideNum );
+ if ( slide->ObjectCount() )
+ {
+ //__ASSERT_DEBUG( EFalse, DataUtilsPanic( EMmsSlideNotEmpty ) );
+ return;
+ }
+
+ iSlideArray->Delete( aSlideNum );
+ delete slide;
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Empty slide removed." );
+ iSizeEstimateUpToDate = EFalse;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::MoveSlideL
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::MoveSlideL( TInt aSlideToMove, TInt aPlaceToMove )
+ {
+ TInt slideCount = iSlideArray->Count();
+ if ( !slideCount
+ || aSlideToMove < 0
+ || aSlideToMove >= slideCount
+ || aSlideToMove == aPlaceToMove )
+ {
+ return;
+ }
+ TInt place = Min( Max( 0, aPlaceToMove ), slideCount - 1 );
+ CUniSmilSlide* slide = iSlideArray->At( aSlideToMove );
+
+ iSlideArray->Delete( aSlideToMove );
+ iSlideArray->InsertL( place, slide );
+ iSizeEstimateUpToDate = EFalse;
+ }
+
+// ---------------------------------------------------------
+// SortSlidesL
+//
+// Sorts slides accoring to a separate comparison function
+// called SortSlidesCompare().
+//
+// Insertion sort algorithm.
+//
+// Notice! Intended to be used with SendAs when there
+// are multiple slides - each slide containing only
+// one object
+// ---------------------------------------------------------
+EXPORT_C void CUniSmilModel::SortSlidesL()
+ {
+ TInt i = 1; // index 1, i.e. second slide
+ TInt count = SlideCount();
+ while ( i < count )
+ {
+ CUniSmilSlide* slide1 = iSlideArray->At( i );
+ TInt j = i - 1;
+ while ( j >= 0 )
+ {
+ CUniSmilSlide* slide2 = iSlideArray->At( j );
+ if ( SortSlidesCompare( slide1, slide2 ) > 0 )
+ {
+ break;
+ }
+ j--;
+ }
+ j++;
+ if ( j < i )
+ {
+ // slide1 was not in the right place
+ iSlideArray->Delete( i );
+ iSlideArray->InsertL( j, slide1 );
+ }
+ i++;
+ }
+ iSizeEstimateUpToDate = EFalse;
+ }
+
+
+// ---------------------------------------------------------
+// SortSlidesCompare
+//
+// Compares slides according to time. Most recent is greatest.
+//
+// Empty slides are greater than non-empty slides.
+// If aSlide1 "is greater than" aSlide2 returns positive value.
+// If aSlide1 "is smaller than" aSlide2 returns negative value.
+// If aSlide1 and aSlide2 "are equal" returns zero.
+// ---------------------------------------------------------
+//
+TInt CUniSmilModel::SortSlidesCompare( CUniSmilSlide* aSlide1,
+ CUniSmilSlide* aSlide2 )
+ {
+ if ( !aSlide1->ObjectCount() )
+ {
+ //if both are empty returns 0
+ //if slide2 is non-empty -> slide1 "is greater"
+ return aSlide2->ObjectCount();
+ }
+ else if ( !aSlide2->ObjectCount() )
+ {
+ //empty slide is always "greatest"
+ return -1;
+ }
+ else
+ {
+ TTime time1;
+ TTime time2;
+ aSlide1->GetObjectByIndex( 0 )->MediaInfo()->ModificationTime( time1 );
+ aSlide2->GetObjectByIndex( 0 )->MediaInfo()->ModificationTime( time2 );
+ if ( time1 < time2 )
+ {
+ return -1;
+ }
+ else if ( time1 == time2 )
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::IsSlide
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CUniSmilModel::IsSlide( TInt aSlideNum ) const
+ {
+ if( aSlideNum >= 0 &&
+ aSlideNum < iSlideArray->Count() )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddTextObjectL
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CUniTextObject* CUniSmilModel::AddTextObjectL(
+ TInt aSlideNum,
+ CEikRichTextEditor* aText )
+ {
+ CUniTextObject* obj = CUniTextObject::NewLC( iFs, iMtm, iData, aText );
+ iObjectList.AddObjectL( obj );
+ CleanupStack::Pop( obj );
+ iSlideArray->At(aSlideNum)->AddObjectL( obj );
+ iSizeEstimateUpToDate = EFalse;
+ return obj;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddTempObjectL
+//
+// ---------------------------------------------------------
+//
+/*
+EXPORT_C CUniObject* CUniSmilModel::AddTempObjectL( TInt aSlideNum,
+ CMsgMediaInfo* aMedia )
+ {
+ if ( !IsSlide( aSlideNum ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CUniObject* obj = CUniObject::NewLC( iFs, iMtm, iData, aMedia );
+
+ // Update model
+ iObjectList.AddObjectL( obj );
+ CleanupStack::Pop( obj );
+ iSlideArray->At( aSlideNum )->AddObjectL( obj );
+ SetLayoutFromObjectTypeL( obj->MediaType() );
+ iSizeEstimateUpToDate = EFalse;
+ return obj;
+ }
+*/
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddObjectL
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CUniObject* CUniSmilModel::AddObjectL( MUniObjectSaveObserver& aObserver,
+ TInt aSlideNum,
+ CMsgMediaInfo* aMedia )
+ {
+ if ( !IsSlide( aSlideNum ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CUniObject* obj = CUniObject::NewLC( iFs, iMtm, iData, aMedia );
+
+ // Update model
+ iObjectList.AddObjectL( obj );
+ CleanupStack::Pop( obj );
+ obj->Save( aObserver, CMsvAttachment::EMsvLinkedFile );
+ iSlideArray->At(aSlideNum)->AddObjectL( obj );
+ iSizeEstimateUpToDate = EFalse;
+ return obj;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddStoredObjectL
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CUniObject* CUniSmilModel::AddStoredObjectL( TInt aSlideNum,
+ TMsvAttachmentId aAttachmentId,
+ CMsgMediaInfo* aMedia )
+ {
+ if ( !IsSlide( aSlideNum ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CMsvStore* store = iMtm.Entry().EditStoreL();
+ CleanupStack::PushL( store );
+ MMsvAttachmentManager& manager = store->AttachmentManagerL();
+ MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL();
+ CMsvAttachment* attachment = manager.GetAttachmentInfoL( aAttachmentId );
+ CleanupStack::PushL( attachment );
+
+ CUniObject* obj = NULL;
+
+ if ( aMedia &&
+ aMedia->MediaType() == EMsgMediaText )
+ {
+ CMsgTextInfo* textInfo = static_cast<CMsgTextInfo*>( aMedia );
+ obj = CUniTextObject::NewLC( iFs, iMtm, iData, textInfo, manager, *attachment );
+ }
+ else
+ {
+ obj = CUniObject::NewLC( iFs, iMtm, iData, aMedia, manager, *attachment );
+ }
+ managerSync.ModifyAttachmentInfoL( attachment );
+ CleanupStack::Pop( 2, attachment ); //obj, attachment
+ CleanupStack::PushL( obj );
+ store->CommitL();
+
+ // Update model
+ iObjectList.AddObjectL( obj );
+ CleanupStack::Pop( obj );
+ CleanupStack::PopAndDestroy( store );
+ iSlideArray->At(aSlideNum)->AddObjectL( obj );
+ iSizeEstimateUpToDate = EFalse;
+ return obj;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::RemoveObjectL
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::RemoveObjectL( TInt aSlideNum,
+ CUniObject* aObject,
+ TBool aLeaveToStore/* = EFalse*/ )
+ {
+ if ( !IsSlide( aSlideNum ) ||
+ !iSlideArray->At( aSlideNum )->IsObject( aObject ) )
+ {
+ return;
+ }
+ // TODO: Check that object exists on the slide.
+
+ //if ( !IsObject( aSlideNum, aObjectType ) )
+ // {
+ // return;
+ // }
+ DoRemoveObjectL( aSlideNum, aObject, aLeaveToStore );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::RemoveObjectByIndexL
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::RemoveObjectByIndexL( TInt aSlideNum, TInt aObjectNum )
+ {
+ if ( !IsSlide( aSlideNum ) )
+ {
+ return;
+ }
+ CUniObject* obj = iSlideArray->At( aSlideNum )->GetObjectByIndex( aObjectNum );
+ DoRemoveObjectL( aSlideNum, obj );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::DoRemoveObjectL
+//
+//
+// ---------------------------------------------------------
+//
+void CUniSmilModel::DoRemoveObjectL( TInt aSlideNum, CUniObject* aObject, TBool aLeaveToStore/* = EFalse*/ )
+ {
+ //MsgDataUTILSLOGGER_ENTERFN( "CUniSmilModel : DoRemoveObjectL()" );
+
+ TBool removeObj = ( aObject->ReferenceCount() - 1 <= 0 );
+ //if last reference was (will be) removed, remove from
+ //attachment list (and msg store)
+ if ( removeObj )
+ {
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Removing from atta list and store." );
+ iObjectList.RemoveObjectL( aObject, !aLeaveToStore );
+ }
+
+ CUniSmilSlide* slide = iSlideArray->At( aSlideNum );
+ slide->RemoveObject( aObject );
+ iSizeEstimateUpToDate = EFalse;
+
+ if ( removeObj )
+ {
+ delete aObject;
+ }
+
+ //MsgDataUTILSLOGGER_LEAVEFN( "CUniSmilModel : DoRemoveObjectL()" );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetObject
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CUniObject* CUniSmilModel::GetObjectByIndex( TInt aSlideNum,
+ TInt aObjectNum ) const
+ {
+ if( !IsSlide( aSlideNum ) )
+ {
+ return NULL;
+ }
+ return iSlideArray->At( aSlideNum )->GetObjectByIndex( aObjectNum );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetObject
+//
+//
+// ---------------------------------------------------------
+//
+EXPORT_C CUniObject* CUniSmilModel::GetObject( TInt aSlideNum,
+ TUniRegion aRegion ) const
+ {
+ if( !IsSlide( aSlideNum ) )
+ {
+ return NULL;
+ }
+ return iSlideArray->At( aSlideNum )->GetObject( aRegion );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::SetLayoutL
+//
+// Mutator.
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniSmilModel::SetLayoutL( TUniLayout aNewLayout )
+ {
+ iSlideLayout = aNewLayout;
+ TUint slideCnt = iSlideArray->Count();
+ for (TUint i = 0; i < slideCnt; i++ )
+ {
+ iSlideArray->At(i)->UpdateLayoutL( iSlideLayout );
+ }
+ iSizeEstimateUpToDate = EFalse;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::SmilComposeSize()
+//
+// Total size
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CUniSmilModel::SmilComposeSize()
+ {
+ TInt slideCount = iSlideArray->Count();
+ if ( !slideCount )
+ {
+ return 0;
+ }
+ if ( !iSizeEstimateUpToDate )
+ {
+ iSizeEstimate = SmilComposeSize(
+ slideCount,
+ iSlideArray->At( slideCount - 1 )->ObjectCount() );
+ iSizeEstimateUpToDate = ETrue;
+ }
+ return iSizeEstimate;
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::SmilComposeSize()
+//
+// Size from beginning
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CUniSmilModel::SmilComposeSize( TInt aToSlideNum, TInt aToObjectNum )
+ {
+ //__ASSERT_DEBUG(
+ // ( aToSlideNum > 0 && aToSlideNum <= iSlideArray->Count() ),
+ // DataUtilsPanic( EMmsIllegalSlide ) );
+ //__ASSERT_DEBUG(
+ // ( aToObjectNum <= iSlideArray->At( aToSlideNum - 1 )->ObjectCount() ),
+ // DataUtilsPanic( EMmsIllegalObject ) );
+
+ TInt size( KSizeMandatorySmilTags );
+ TBool imageRegion = EFalse;
+ TBool textRegion = EFalse;
+
+ for ( TInt i = 0; i < aToSlideNum; ++i )
+ {
+ CUniSmilSlide* slide = iSlideArray->At( i );
+ TInt toObj = slide->ObjectCount();
+ if ( i == aToSlideNum - 1 )
+ {
+ toObj = aToObjectNum;
+ }
+ if ( !toObj )
+ {
+ //No objects on the slide
+ size += KSizeEmptyPar;
+ }
+ else
+ {
+ //One or more objects
+ size += KSizeNonEmptyPar;
+ }
+ for ( TInt ii = 0; ii < toObj; ++ii )
+ {
+ CUniObject* obj = slide->GetObjectByIndex( ii );
+ switch ( obj->MediaType() )
+ {
+ case EMsgMediaAudio:
+ size += KSizeAudioTag;
+ break;
+ case EMsgMediaImage:
+ case EMsgMediaSvg:
+ size += KSizeImageTag;
+ imageRegion = ETrue;
+ break;
+ case EMsgMediaText:
+ case EMsgMediaXhtml:
+ size += KSizeTextTag;
+ textRegion = ETrue;
+ break;
+ case EMsgMediaVideo:
+ size += KSizeVideoTag;
+ imageRegion = ETrue;
+ break;
+ default:
+ //Should never come here
+ //Don't increase size
+ break;
+ }
+ }
+ }
+
+ TInt regions = 0;
+ if ( imageRegion )
+ {
+ regions++;
+ }
+ if ( textRegion )
+ {
+ regions++;
+ }
+ switch ( regions )
+ {
+ case 1:
+ size += KSizeHeadOneRegion;
+ break;
+ case 2:
+ size += KSizeHeadTwoRegions;
+ break;
+ default:
+ //Should be zero
+ //Don't increase size
+ break;
+ }
+ return size;
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::ObjectCount
+//
+// Accessor
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CUniSmilModel::ObjectCount() const
+ {
+ TInt objCnt(0);
+
+ for ( TInt i = iSlideArray->Count(); --i >= 0 ;)
+ {
+ objCnt += iSlideArray->At(i)->ObjectCount();
+ }
+
+ return objCnt;
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::SlideObjectCount
+//
+// Accessor
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CUniSmilModel::SlideObjectCount(TInt aSlideNum) const
+ {
+ if ( !IsSlide(aSlideNum) )
+ {
+ return 0;
+ }
+
+ return iSlideArray->At( aSlideNum )->ObjectCount();
+ }
+
+//**********************************************************
+//*
+//* CONTRUCTION FUNCTIONS
+//*
+//**********************************************************
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::ConstructL
+//
+// 2nd phase constructor.
+// ---------------------------------------------------------
+//
+void CUniSmilModel::ConstructL()
+ {
+ iSlideArray = new ( ELeave ) CSmilSlideArray( KSlideArrayGranularity );
+ iTextRegionId.Set( KNullDesC );
+ iImageRegionId.Set( KNullDesC );
+
+ // Set default layout to "Text first"
+ iSlideLayout = EUniTextFirst;
+
+ // Fix for NSIA-6CKFJA. Sets same screen size that SMIL Player is using. MH
+/*
+ TRect appWindowRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow, appWindowRect );
+
+ TAknLayoutRect mainPane;
+ mainPane.LayoutRect( appWindowRect, AknLayoutScalable_Avkon::main_pane( 0 ) );
+
+ TAknLayoutRect mainSmilPane;
+ mainSmilPane.LayoutRect( mainPane.Rect(), AknLayoutScalable_Apps::main_smil_pane() );
+
+ iScreenSize = mainSmilPane.Rect().Size();
+*/
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::Reset
+//
+//
+// ---------------------------------------------------------
+//
+void CUniSmilModel::Reset()
+ {
+ iParseResult = 0;
+ iSlideLayout = EUniTextFirst;
+ iTextRegionId.Set( KNullDesC );
+ iImageRegionId.Set( KNullDesC );
+ if ( iSlideArray )
+ {
+ // Reset slide array
+ iSlideArray->ResetAndDestroy();
+ }
+ TInt objCount = iObjectList.Count();
+ while ( objCount-- )
+ {
+ iObjectList.GetByIndex( objCount )->SetReferenceCount( 0 );
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::DoPresentationFromDomL
+//
+// When this functios is called DOM should be validated as MMS SMIL.
+// ---------------------------------------------------------
+//
+void CUniSmilModel::DoPresentationFromDomL( CMDXMLDocument* aDom )
+ {
+ RemoveMetaTagsAndComments( aDom );
+ // Resolve layout of the slide
+ iSlideLayout = GetMmsSmilLayout( aDom );
+
+ CMDXMLNode* node = GetNode( aDom, KSMILWREleBody );
+
+ if ( node && node->FirstChild() )
+ {
+ // Only one slide in the message since no <par> tag found
+ if ( node->FirstChild()->NodeName().Compare( KSMILWRElePar ) != 0 )
+ {
+ // Add slide - the one and only
+ AddSlideFromDomL( node );
+ }
+
+ // Other node types than <par> not possible as this is MMS SMIL.
+ else
+ {
+ // Traverse through every page
+ CMDXMLNode* page = node->FirstChild();
+ while ( page )
+ {
+ AddSlideFromDomL( page );
+ // Go to next page.
+ page = page->NextSibling();
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddSlideFromDomL
+//
+// ---------------------------------------------------------
+//
+void CUniSmilModel::AddSlideFromDomL( CMDXMLNode* aPage )
+ {
+ CUniObject* obj = NULL;
+ CUniSmilSlide* slide = DoAddSlideL();
+ CMDXMLNode* node = aPage->FirstChild();
+
+ // Traverse through every object in page.
+ while ( node )
+ {
+ if ( UniSmilUtils::IsMediaElem( node ) )
+ {
+ obj = iObjectList.GetByNodeL( node );
+ if ( obj )
+ {
+ if ( slide )
+ {
+ obj->SetMediaTypeBySmilTag( UniSmilUtils::MediaElemType( node ) );
+ AddObjectFromDomL(
+ slide,
+ obj,
+ GetRegionType( node ) );
+ }
+ else
+ {
+ iObjectList.RemoveObjectL( obj, ETrue );
+ delete obj;
+ iParseResult |= EObjectRemoved;
+ }
+ }
+ }
+ node = node->NextSibling();
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::AddObjectFromDomL
+//
+// ---------------------------------------------------------
+//
+void CUniSmilModel::AddObjectFromDomL( CUniSmilSlide* aSlide,
+ CUniObject* aObj,
+ TUniRegion aRegion )
+ {
+ if ( !aObj )
+ {
+ // Smil presentation refers to attachment that's not in the message
+ iParseResult |= EMissingObjects;
+ // Not actually error that should prevent message viewing.
+ return;
+ }
+
+ TMsgMediaType mediaBySmilTag = aObj->MediaTypeBySmilTag();
+ TMsgMediaType media = aObj->MediaType();
+
+ if ( media == EMsgMediaSvg )
+ {
+ // SVG considered an image.
+ // (...because "image" tag is used for SVG while composing SMIL.)
+ media = EMsgMediaImage;
+ }
+
+ if ( media == EMsgMediaXhtml )
+ {
+ // XHTML is considered as a text.
+ // (...because "text" tag is used for xhtml while composing SMIL.)
+ media = EMsgMediaText;
+ }
+
+ if ( !( media == EMsgMediaText ||
+ media == EMsgMediaImage ||
+ media == EMsgMediaAudio ||
+ media == EMsgMediaVideo ) )
+ {
+ // Unsupported format
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Parsing: Message has unsupported objects." );
+ iParseResult |= EUnsupportedObjects;
+ // Not actually error that should prevent message viewing.
+ }
+
+ // NOTE: Smil standard allows <img src="aa.txt"> references, but conformance
+ // Data forbids these.
+ if ( media != EMsgMediaUnknown && //Unknown matches anything
+ mediaBySmilTag != EMsgMediaRef && //<ref> matches anything
+ media != mediaBySmilTag )
+ {
+ // SMIL does not describe content as it should
+ //MsgDataUTILSLOGGER_WRITE( "CUniSmilModel: Parsing: Smil object type differs from message object type." );
+ iParseResult |= EBadlyReferencedObjects;
+ }
+
+ TUniRegion regionBySmilTag = EUniRegionUnresolved;
+ switch ( mediaBySmilTag )
+ {
+ case EMsgMediaAudio:
+ {
+ regionBySmilTag = EUniRegionAudio;
+ break;
+ }
+ case EMsgMediaImage:
+ case EMsgMediaVideo:
+ {
+ regionBySmilTag = EUniRegionImage;
+ break;
+ }
+ case EMsgMediaText:
+ {
+ regionBySmilTag = EUniRegionText;
+ break;
+ }
+ default:
+ break;
+ }
+
+ TUniRegion regionByMediaType = EUniRegionUnresolved;
+ switch ( media )
+ {
+ case EMsgMediaAudio:
+ {
+ regionByMediaType = EUniRegionAudio;
+ break;
+ }
+ case EMsgMediaImage:
+ case EMsgMediaVideo:
+ {
+ regionByMediaType = EUniRegionImage;
+ break;
+ }
+ case EMsgMediaText:
+ {
+ regionByMediaType = EUniRegionText;
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Check that region type matches object media type
+ if ( aRegion != EUniRegionUnresolved &&
+ regionByMediaType != EUniRegionUnresolved &&
+ aRegion != regionByMediaType )
+ {
+ iParseResult |= ERegionMediaTypeMismatch;
+ aRegion = regionByMediaType;
+ }
+ else if ( regionByMediaType == EUniRegionUnresolved &&
+ aRegion == EUniRegionText )
+ {
+ // do not put every possible content into text reqion
+ iParseResult |= ERegionMediaTypeMismatch;
+ aRegion = EUniRegionUnresolved;
+ }
+ else if ( aRegion == EUniRegionUnresolved )
+ {
+ // If region couldn't be resolved from the region tag
+ // follow the media type. If that's not possible follow
+ // the smil media tag name. If everything fails
+ // "aRegion" will remain "unresolved".
+ aRegion = ( regionByMediaType != EUniRegionUnresolved )
+ ? regionByMediaType
+ : regionBySmilTag;
+ }
+
+ CMsgMediaInfo* mediaInfo = aObj->MediaInfo();
+ // DRM2 must be put into object view in the viewer
+ if ( mediaInfo &&
+ ( /*mediaInfo->HandlerApplicationUid().iUid == 0 ||*/
+ aObj->MediaInfo()->Protection() & EFileProtDrm2 ) )
+ {
+ aRegion = EUniRegionUnresolved;
+ }
+ // else - should not occur
+
+ if ( aRegion != EUniRegionUnresolved )
+ {
+ aSlide->AddObjectL( aObj, aRegion );
+ iSizeEstimateUpToDate = EFalse;
+ }
+ else
+ {
+ iParseResult |= EBadlyReferencedObjects;
+ // -> Something unknown in the SMIL.
+ // -> Don't add. Will be handled as an attachment.
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::IsMessageSlide
+//
+// ---------------------------------------------------------
+//
+TBool CUniSmilModel::IsMessageSlide()
+ {
+ TInt imageCnt( 0 );
+ TInt audioCnt( 0 );
+ TInt textCnt( 0 );
+
+ for ( TInt i = iObjectList.Count(); --i >= 0 ; )
+ {
+ switch( iObjectList.GetByIndex(i)->MediaType() )
+ {
+ case EMsgMediaSvg:
+ case EMsgMediaImage:
+ imageCnt++;
+ break;
+
+ case EMsgMediaAudio:
+ audioCnt++;
+ break;
+
+ case EMsgMediaText:
+ case EMsgMediaXhtml:
+ textCnt++;
+ break;
+
+ case EMsgMediaVideo:
+ //always consider video as image + audio
+ imageCnt++;
+ audioCnt++;
+ break;
+
+ case EMsgMediaUnknown:
+ default:
+ // Unsupported objects will be put into attachment list
+ // in FindAttachmentsL()
+ break;
+ } // switch
+ } // for
+
+ if ( imageCnt > 1 || audioCnt > 1 || textCnt > 1 )
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// DoNoSmilOneSlideL
+//
+// NOTE: Message should be a valid slide at this point.
+// ---------------------------------------------------------
+//
+void CUniSmilModel::DoNoSmilOneSlideL()
+ {
+ CUniSmilSlide* slide = NULL;
+
+ for ( TInt i = 0; i < iObjectList.Count(); ++i )
+ {
+ CUniObject* obj = iObjectList.GetByIndex(i);
+ TMsgMediaType media = obj->MediaType();
+ CMsgMediaInfo* mediaInfo = obj->MediaInfo();
+
+ // DRM2 must be put into objects view in the viewer
+ if ( ( media == EMsgMediaText ||
+ media == EMsgMediaXhtml ||
+ media == EMsgMediaImage ||
+ media == EMsgMediaSvg ||
+ media == EMsgMediaAudio ||
+ media == EMsgMediaVideo ) &&
+ mediaInfo &&
+ /*mediaInfo->HandlerApplicationUid().iUid &&*/
+ !( obj->MediaInfo()->Protection() & EFileProtDrm2 ) )
+ {
+ if ( !slide )
+ {
+ // Add slide
+ slide = DoAddSlideL();
+ }
+ slide->AddObjectL( obj );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// DoNoSmilManySlideL
+//
+//
+// ---------------------------------------------------------
+//
+void CUniSmilModel::DoNoSmilManySlideL()
+ {
+ for ( TInt i = 0; i < iObjectList.Count(); ++i )
+ {
+ CUniObject* obj = iObjectList.GetByIndex(i);
+ if (obj == NULL)
+ return;
+
+ TMsgMediaType media = obj->MediaType();
+ CMsgMediaInfo* mediaInfo = obj->MediaInfo();
+
+ // DRM2 must be put into objects view in the viewer
+ if ( ( media == EMsgMediaText ||
+ media == EMsgMediaXhtml ||
+ media == EMsgMediaImage ||
+ media == EMsgMediaSvg ||
+ media == EMsgMediaAudio ||
+ media == EMsgMediaVideo ) &&
+ mediaInfo &&
+ /*mediaInfo->HandlerApplicationUid().iUid &&*/
+ !( obj->MediaInfo()->Protection() & EFileProtDrm2 ) )
+ {
+ CUniSmilSlide* slide = DoAddSlideL();
+ if ( slide )
+ {
+ slide->AddObjectL( obj );
+ }
+ else
+ {
+ iObjectList.RemoveObjectL( obj, ETrue );
+ delete obj;
+ iParseResult |= EObjectRemoved;
+ i--;
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// DoAddSlideL
+//
+// ---------------------------------------------------------
+//
+CUniSmilSlide* CUniSmilModel::DoAddSlideL( TInt aSlideNum /*= -1*/ )
+ {
+ CUniSmilSlide* newSlide = NULL;
+ if ( iMaxSlideCount == 0 ||
+ iSlideArray->Count() < iMaxSlideCount )
+ {
+ newSlide = CUniSmilSlide::NewLC( iSlideLayout );
+ if ( aSlideNum == -1 || aSlideNum >= iSlideArray->Count() )
+ {
+ // Add to end of array
+ iSlideArray->AppendL( newSlide );
+ }
+ else
+ {
+ iSlideArray->InsertL( aSlideNum, newSlide );
+ }
+ CleanupStack::Pop( newSlide ); // newSlide
+ iSizeEstimateUpToDate = EFalse;
+ }
+ return newSlide;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CreateHeadL
+//
+// ---------------------------------------------------------
+void CUniSmilModel::CreateHeadL( CMDXMLDocument* aDom, CMDXMLElement* aRoot )
+ {
+
+ TPtrC name( KSMILWREleHead );
+ // Create Head node
+ CMDXMLElement* ele = CMDXMLElement::NewLC( ETrue, aDom, name );
+ // Append Head in Root node
+ aRoot->AppendChild( ele );
+
+ // Create Layout
+ CreateLayoutL( aDom, ele );
+ CleanupStack::Pop( ele );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::ChangeLayoutL
+//
+// ---------------------------------------------------------
+EXPORT_C TBool CUniSmilModel::ChangeLayoutL( CMDXMLDocument* aDom )
+ {
+ TBool retVal = EFalse;
+ if ( aDom )
+ {
+ CMDXMLElement* layout = (CMDXMLElement*) GetNode( aDom, KSMILWREleLayout );
+ if ( !layout )
+ {
+ // No layout. Nothing to do without composing
+ // SMIL from scratch.
+ return EFalse;
+ }
+ CMDXMLElement* head = (CMDXMLElement*) layout->ParentNode();
+
+ // Read default smil parameters
+ if( !iSmilParams )
+ {
+ iSmilParams = CUniSmilParams::NewL( iFs );
+ }
+ CMDXMLElement* rootLayout = NULL;
+ CMDXMLElement* textRegion = NULL;
+ CMDXMLElement* imageRegion = NULL;
+
+ GetLayoutElements(
+ layout,
+ rootLayout,
+ textRegion,
+ imageRegion );
+
+ if ( rootLayout )
+ {
+ rootLayout->RemoveAttribute( KSMILWRParaWidth );
+ rootLayout->RemoveAttribute( KSMILWRParaHeight );
+ }
+
+ if ( textRegion )
+ {
+ textRegion->RemoveAttribute( KSMILWRParaFit );
+ textRegion->RemoveAttribute( KSMILWRParaTop );
+ textRegion->RemoveAttribute( KSMILWRParaLeft );
+ textRegion->RemoveAttribute( KSMILWRParaBottom );
+ textRegion->RemoveAttribute( KSMILWRParaRight );
+ textRegion->RemoveAttribute( KSMILWRParaHeight );
+ textRegion->RemoveAttribute( KSMILWRParaWidth );
+ }
+ if ( imageRegion )
+ {
+ imageRegion->RemoveAttribute( KSMILWRParaFit );
+ imageRegion->RemoveAttribute( KSMILWRParaTop );
+ imageRegion->RemoveAttribute( KSMILWRParaLeft );
+ imageRegion->RemoveAttribute( KSMILWRParaBottom );
+ imageRegion->RemoveAttribute( KSMILWRParaRight );
+ imageRegion->RemoveAttribute( KSMILWRParaHeight );
+ imageRegion->RemoveAttribute( KSMILWRParaWidth );
+ }
+
+ CreateLayoutL( aDom, head, rootLayout, layout, textRegion, imageRegion );
+ retVal = ETrue;
+ }
+ return retVal;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CorrectTimingL
+//
+// ---------------------------------------------------------
+EXPORT_C TBool CUniSmilModel::CorrectTimingL( CMDXMLDocument* aDom )
+ {
+ if ( aDom )
+ {
+ CMDXMLElement* body = static_cast<CMDXMLElement*>( GetNode( aDom, KSMILWREleBody ) );
+ if ( !body )
+ {
+ // No body. Nothing to do without composing
+ // SMIL from scratch.
+ return EFalse;
+ }
+
+ if ( body && body->FirstChild() )
+ {
+ // Only one slide in the message since no <par> tag found
+ if ( body->FirstChild()->NodeName().Compare( KSMILWRElePar ) != 0 &&
+ !body->FirstChild()->NextSibling() )
+ {
+ // Correct slide timing to the one and only slide
+ CorrectSlideTimingL( body );
+ }
+ // Other node types than <par> not possible as this is MMS SMIL.
+ else
+ {
+ // Traverse through every page
+ CMDXMLNode* page = body->FirstChild();
+
+ while ( page != NULL )
+ {
+ if ( page->NodeName().Compare( KSMILWRElePar ) == 0 &&
+ page->NodeType() == CMDXMLNode::EElementNode )
+ {
+ CMDXMLElement* pageElement = static_cast<CMDXMLElement*>( page );
+ if ( !TimingSpecified( pageElement ) )
+ {
+ CorrectSlideTimingL( pageElement );
+ }
+ }
+ // Go to next page.
+ page = page->NextSibling();
+ }
+ }
+ }
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::IsSupportedMediaType
+//
+// ---------------------------------------------------------
+EXPORT_C TBool CUniSmilModel::IsSupportedMediaType( TMsgMediaType aMediaType ) const
+ {
+ if ( aMediaType == EMsgMediaAudio ||
+ aMediaType == EMsgMediaImage ||
+ aMediaType == EMsgMediaSvg ||
+ aMediaType == EMsgMediaXhtml ||
+ aMediaType == EMsgMediaVideo ||
+ aMediaType == EMsgMediaText )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::CreateLayoutL
+//
+// ---------------------------------------------------------
+void CUniSmilModel::CreateLayoutL( CMDXMLDocument* aDom,
+ CMDXMLElement* aRoot,
+ CMDXMLElement* aRootLayout,
+ CMDXMLElement* aLayout,
+ CMDXMLElement* aTextRegion,
+ CMDXMLElement* aImageRegion )
+ {
+
+ TPtrC name( KSMILWREleLayout );
+ // Create Layout node
+ if ( !aLayout )
+ {
+ aLayout = CMDXMLElement::NewLC( ETrue, aDom, name );
+ // Append Layout in Head
+ aRoot->InsertBefore( NULL, aLayout );
+ CleanupStack::Pop(); // layout
+ }
+
+ // Do we have images and text-objects on a slide with other media objects and
+ // do we have any video
+ TInt hasVideo( 0 );
+ TInt hasImage( 0 );
+ TInt hasText( 0 );
+
+ // Do we have media, which is alone on a slide? Also calculate how medias are alone on a slide.
+ // Video overrides any image region, it is not needed
+ TInt hasImageOneAndOnly( 0 );
+ TInt hasTextOneAndOnly( 0 );
+
+ for( TInt i = 0; i < iSlideArray->Count(); ++i )
+ {
+ CUniSmilSlide* s = iSlideArray->At( i );
+ TBool hasVideoOnThisSlide = EFalse;
+ TBool hasImageOnThisSlide = EFalse;
+ TBool hasTextOnThisSlide = EFalse;
+
+ CUniObject* imageRegionObj = s->GetObject( EUniRegionImage );
+ if ( imageRegionObj )
+ {
+ if ( imageRegionObj->MediaType() == EMsgMediaVideo )
+ {
+ hasVideoOnThisSlide = ETrue;
+ hasVideo++;
+ }
+ else
+ {
+ hasImageOnThisSlide = ETrue;
+ hasImage++;
+ }
+ }
+ if ( s->GetObject( EUniRegionText ) )
+ {
+ hasTextOnThisSlide = ETrue;
+ hasText++;
+ }
+
+ if ( !hasVideoOnThisSlide
+ && hasImageOnThisSlide
+ && !hasTextOnThisSlide )
+ {
+ hasImageOneAndOnly++;
+ }
+ if ( !hasVideoOnThisSlide
+ && !hasImageOnThisSlide
+ && hasTextOnThisSlide )
+ {
+ hasTextOneAndOnly++;
+ }
+ }
+
+ // we know:
+ // how many media objects of each type there are totally in the message and
+ // whether some regions have alone on a slide
+ // we conclude:
+ // if a media object has been alone on the slide and there is
+ // only one media object in the whole message
+ // or if there are several images without other content or several texts on several slides
+ // without other content then the media object is alone on a slide
+ // and is only one of its type in the message
+ // but: video is exception. It handling is ignored here. Following big if() statement handles it
+ // by handling video before exception case resolved
+ if ( hasImageOneAndOnly == hasImage )
+ {
+ // image does not occur with some other region
+ hasImage = 0;
+ }
+ else
+ {
+ // image occurs with some other region on some slide
+ hasImageOneAndOnly = 0;
+ }
+
+ if ( hasTextOneAndOnly == hasText )
+ {
+ // text does not occur with some other region
+ hasText = 0;
+ }
+ else
+ {
+ // text occurs with some other region on some slide
+ hasTextOneAndOnly = 0;
+ }
+
+/*
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+ TBool useSubQCIF( EFalse);
+
+ TRect appWin;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow, appWin );
+ TAknLayoutRect mainPane;
+
+ if ( isLandscape )
+ {
+ mainPane.LayoutRect(
+ appWin,
+ AknLayoutScalable_Apps::main_pane( 4 ).LayoutLine() );
+ }
+ else
+ {
+ mainPane.LayoutRect(
+ appWin,
+ AknLayoutScalable_Apps::main_pane( 6 ).LayoutLine() );
+ }
+
+ if ( isLandscape &&
+ appWin.Height() == KSizeLowResWidth &&
+ appWin.Width() == KSizeLowResHeight )
+ {
+ useSubQCIF = ETrue;
+ }
+
+ TAknLayoutRect smilLayout;
+ smilLayout.LayoutRect(
+ mainPane.Rect(),
+ AknLayoutScalable_Apps::main_smil2_pane().LayoutLine() );
+
+ TAknLayoutRect rootLayout;
+ TAknLayoutRect textLayout;
+ TAknLayoutRect imageLayout;
+ TAknLayoutRect videoLayout;
+
+ // For reader about notation:
+ // x + y == x and y are on the different slide
+ // x,y == x and y are on the same slide
+ // { <item> } item can occur 0 or more times
+ if ( hasText && hasImage && !hasVideo ) // text, image - no video
+ {
+ if ( isLandscape ) // landscape text & image
+ {
+ if ( iSlideLayout == EUniTextFirst )
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 4 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 4 ).LayoutLine() );
+ imageLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_image_pane( 3 ).LayoutLine() );
+ }
+ else
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 2 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 2 ).LayoutLine() );
+ imageLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_image_pane( 1 ).LayoutLine() );
+ }
+ }
+ else // portrait text & image
+ {
+ if ( iSlideLayout == EUniTextFirst )
+ {
+ // Option 3 in the layout spec
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 3 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 3 ).LayoutLine() );
+ imageLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_image_pane( 2 ).LayoutLine() );
+ }
+ else
+ {
+ // Option 1
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 1 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 1 ).LayoutLine() );
+ imageLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_image_pane( 0 ).LayoutLine() );
+ }
+ }
+ }
+ else if ( hasText && hasVideo ) // text, video or text, image + video
+ {
+ if ( isLandscape && useSubQCIF ) // landscape subQCIF text & video
+ {
+ if ( iSlideLayout == EUniTextFirst )
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 13 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 10 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 7 ).LayoutLine() );
+ }
+ else
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 12 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 9 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 6 ).LayoutLine() );
+ }
+ }
+ else if ( isLandscape && !useSubQCIF ) // landscape QCIF text & video
+ {
+ if ( iSlideLayout == EUniTextFirst )
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 10 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 8 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 4 ).LayoutLine() );
+ }
+ else
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 9 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 7 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 3 ).LayoutLine() );
+ }
+ }
+ else // portrait QCIF text & video
+ {
+ if ( iSlideLayout == EUniTextFirst )
+ {
+ // Option 8
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 8 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 6 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 2 ).LayoutLine() );
+ }
+ else
+ {
+ // Option 6
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 6 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 5 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 0 ).LayoutLine() );
+ }
+ }
+ }
+ // cases left:
+ // - 1) text {+ text}
+ // - 2) text {+ text} + video
+ // - 3) text {+ text} + image { + image }
+ // - 4) image {+ image} + video, no text
+ // - 5) image {+ image}
+ // - 6) video
+ // - no visual media content
+ else if ( hasVideo )
+ {
+ // 2) 'text {+ text} + video', 4) 'image {+ image} + video, no text' or 6) 'video'
+ if ( isLandscape )
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 11 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 5 ).LayoutLine() );
+ }
+ else
+ {
+ // Option 7
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 7 ).LayoutLine() );
+ videoLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_video_pane( 1 ).LayoutLine() );
+ }
+
+ if ( hasTextOneAndOnly ) // + text
+ {
+ // Option 0
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 0 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 0 ).LayoutLine() );
+ }
+
+ }
+ else if ( hasTextOneAndOnly
+ || hasImageOneAndOnly )
+ {
+ // 1) text {+ text}, 3) text {+ text} + image { + image ), 5) image {+ image}
+ if ( hasTextOneAndOnly ) // text
+ {
+ // Option 0
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 0 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 0 ).LayoutLine() );
+ }
+
+ // no else - rootLayouts are same
+ if ( hasImageOneAndOnly ) // image
+ {
+ // Option 5
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 5 ).LayoutLine() );
+ imageLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_image_pane( 4 ).LayoutLine() );
+ }
+ }
+ else // empty
+ {
+ rootLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_root_pane( 0 ).LayoutLine() );
+ textLayout.LayoutRect(
+ smilLayout.Rect(),
+ AknLayoutScalable_Apps::smil2_text_pane( 0 ).LayoutLine() );
+ }
+
+ iSmilParams->iComposeParams->iDisplayHeight = rootLayout.Rect().Height();
+ iSmilParams->iComposeParams->iDisplayWidth = rootLayout.Rect().Width();
+
+ // it does not matter anymore whether object is alone on the slide.
+ // Use one variable only in the if() statements
+ if ( hasImage || hasImageOneAndOnly )
+ {
+ hasImage = 1;
+ }
+ if ( hasText || hasTextOneAndOnly )
+ {
+ hasText = 1;
+ }
+
+ if ( hasText )
+ {
+ iSmilParams->iTextRegionParams->iSize = textLayout.Rect().Size();
+ iSmilParams->iTextRegionParams->iTopLeft =
+ textLayout.Rect().iTl - rootLayout.Rect().iTl;
+ }
+ if ( hasImage || hasVideo )
+ {
+ if ( hasVideo )
+ {
+ iSmilParams->iImageRegionParams->iSize = videoLayout.Rect().Size();
+ iSmilParams->iImageRegionParams->iTopLeft =
+ videoLayout.Rect().iTl - rootLayout.Rect().iTl;
+ }
+ else
+ {
+ iSmilParams->iImageRegionParams->iSize = imageLayout.Rect().Size();
+ iSmilParams->iImageRegionParams->iTopLeft =
+ imageLayout.Rect().iTl - rootLayout.Rect().iTl;
+ }
+ }
+
+*/
+
+ // Set Region IDs to defaults
+ if ( !iImageRegionId.Length() )
+ {
+ iImageRegionId.Set( KSMILWRRegIDImage );
+ }
+ if ( !iTextRegionId.Length() )
+ {
+ iTextRegionId.Set( KSMILWRRegIDText );
+ }
+
+ // Create root layout
+ name.Set( KSMILWREleRoot_layout );
+ TBool rlPop = EFalse;
+ if ( !aRootLayout )
+ {
+ aRootLayout = CMDXMLElement::NewLC( EFalse, aDom, name );
+ rlPop = ETrue;
+ }
+ // Set root layout parameters (attributes)
+ TBuf16<20> val;
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iComposeParams->iDisplayWidth );
+ aRootLayout->SetAttributeL( KSMILWRParaWidth,val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iComposeParams->iDisplayHeight );
+ aRootLayout->SetAttributeL( KSMILWRParaHeight, val );
+ if ( rlPop )
+ {
+ // Append root layout in Layout
+ aLayout->AppendChild( aRootLayout );
+ CleanupStack::Pop( aRootLayout );
+ }
+
+ // Create Image region (if needed)
+ name.Set( KSMILWREleRegion );
+ if ( hasImage || hasVideo )
+ {
+ TBool imgPop = EFalse;
+ if ( !aImageRegion )
+ {
+ aImageRegion = CMDXMLElement::NewLC( EFalse, aDom, name );
+ imgPop = ETrue;
+ }
+ // Set Image region attributes
+ aImageRegion->SetAttributeL( KSMILWRParaId, iImageRegionId );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iImageRegionParams->Width() );
+ aImageRegion->SetAttributeL( KSMILWRParaWidth, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iImageRegionParams->Height() );
+ aImageRegion->SetAttributeL( KSMILWRParaHeight, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iImageRegionParams->Top() );
+ aImageRegion->SetAttributeL( KSMILWRParaTop, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iImageRegionParams->Left() );
+ aImageRegion->SetAttributeL( KSMILWRParaLeft, val );
+ aImageRegion->SetAttributeL( KSMILWRParaFit, iSmilParams->iImageRegionParams->iFit->Des() );
+ if ( imgPop )
+ {
+ // Append region in Layout
+ aLayout->AppendChild( aImageRegion ); // Ownership to dom
+ CleanupStack::Pop( aImageRegion );
+ }
+ }
+
+ // Create Text region (if needed)
+ if ( hasText )
+ {
+ TBool txtPop = EFalse;
+ if ( !aTextRegion )
+ {
+ aTextRegion = CMDXMLElement::NewLC( EFalse, aDom, name );
+ txtPop = ETrue;
+ }
+ // Set Text region attributes
+ aTextRegion->SetAttributeL( KSMILWRParaId, iTextRegionId );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iTextRegionParams->Width() );
+ aTextRegion->SetAttributeL( KSMILWRParaWidth, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iTextRegionParams->Height() );
+ aTextRegion->SetAttributeL( KSMILWRParaHeight, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iTextRegionParams->Top() );
+ aTextRegion->SetAttributeL( KSMILWRParaTop, val );
+ val.Zero();
+ val.Format( KSmilIntFormat, iSmilParams->iTextRegionParams->Left() );
+ aTextRegion->SetAttributeL( KSMILWRParaLeft, val );
+ aTextRegion->SetAttributeL( KSMILWRParaFit, iSmilParams->iTextRegionParams->iFit->Des() );
+ if ( txtPop )
+ {
+ // Append region in Layout
+ aLayout->AppendChild( aTextRegion ); // Ownership to dom
+ CleanupStack::Pop( aTextRegion );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CreateBodyL
+//
+// ---------------------------------------------------------
+void CUniSmilModel::CreateBodyL( CMDXMLDocument* aDom, CMDXMLElement* aRoot )
+ {
+ TPtrC name( KSMILWREleBody );
+ // Create Body node
+ CMDXMLElement* body = CMDXMLElement::NewLC( ETrue, aDom, name );
+ // Append
+ aRoot->AppendChild( body );
+ CleanupStack::Pop( body );
+
+ // For each slide
+ for( TInt slide = 0; slide < iSlideArray->Count(); ++slide )
+ {
+ // Create par
+ CreateParL( aDom, body, slide );
+ }
+
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CreateParL
+//
+// ---------------------------------------------------------
+void CUniSmilModel::CreateParL( CMDXMLDocument* aDom, CMDXMLElement* aRoot, TInt aSlide )
+ {
+ TPtrC name( KSMILWRElePar );
+ // Create par node
+ CMDXMLElement* ele = CMDXMLElement::NewLC( ETrue, aDom, name );
+ // Append
+
+ // Get default page duration.
+ TInt slideDur = iSmilParams->iComposeParams->iSlideDuration;
+ TInt objDur = 0;
+ TBool unresolvedDur = EFalse;
+
+ CUniSmilSlide* s = iSlideArray->At( aSlide );
+
+ // For each object in slide
+ for ( TInt i = s->ObjectCount(); --i >= 0; )
+ {
+ // Create Item
+ CUniObject* obj = s->GetObjectByIndex( i );
+ objDur = CreateItemL( aDom, ele, obj );
+ if ( !obj->MediaInfo()->Parsed() &&
+ ( obj->MediaType() == EMsgMediaAudio ||
+ obj->MediaType() == EMsgMediaVideo ) )
+ {
+ unresolvedDur = ETrue;
+ }
+ else
+ {
+ slideDur = Max( slideDur, objDur );
+ }
+ }
+
+ if ( !unresolvedDur )
+ {
+ TBuf16<20> val;
+ val.Zero();
+ val.Format( KSmilMsecFormat, slideDur );
+
+ // Set par attributes
+ ele->SetAttributeL( KSMILWRParaDur, val );
+ }
+ aRoot->AppendChild( ele ); // Ownership to dom
+ CleanupStack::Pop( ele );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CreateItemL
+//
+// ---------------------------------------------------------
+TInt CUniSmilModel::CreateItemL( CMDXMLDocument* aDom, CMDXMLElement* aRoot, CUniObject* aObj )
+ {
+ CMDXMLElement* ele = NULL;
+ TPtrC name( KNullDesC );
+
+ // Create mediaobject node
+ switch ( aObj->Region() )
+ {
+ case EUniRegionImage:
+ {
+ if ( aObj->MediaType() == EMsgMediaVideo )
+ {
+ name.Set( KSMILWREleVideo );
+ ele = CMDXMLElement::NewLC( EFalse, aDom, name );
+ ele->SetAttributeL( KSMILWRParaRegion, KSMILWRRegIDImage );
+ }
+ else
+ {
+ // Considered an image - includes also SVG
+ name.Set( KSMILWREleImg );
+ ele = CMDXMLElement::NewLC( EFalse, aDom, name );
+ ele->SetAttributeL( KSMILWRParaRegion, KSMILWRRegIDImage );
+ }
+ }
+ break;
+ case EUniRegionText:
+ {
+ name.Set( KSMILWREleText );
+ ele = CMDXMLElement::NewLC( EFalse, aDom, name );
+ ele->SetAttributeL( KSMILWRParaRegion, KSMILWRRegIDText );
+ }
+ break;
+ case EUniRegionAudio:
+ {
+ name.Set( KSMILWREleAudio );
+ ele = CMDXMLElement::NewLC( EFalse, aDom, name );
+ }
+ break;
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+ // Set MediaObject node attributes
+ ele->SetAttributeL( KSMILWRParaSrc, aObj->MimeInfo()->ContentLocation() );
+
+ // Append
+ aRoot->AppendChild( ele ); // Ownership to dom
+ CleanupStack::Pop( ele );
+
+ return aObj->MediaInfo()->Duration();
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetMediaElemRegionIDs
+//
+// ---------------------------------------------------------
+void CUniSmilModel::GetMediaElemRegionIDs( CMDXMLNode* aPage )
+ {
+ CMDXMLNode* txtEle = NULL;
+ CMDXMLNode* imgEle = NULL;
+ CMDXMLNode* obj = aPage->FirstChild();
+
+ // Traverse through every object in page.
+ while ( obj )
+ {
+ if( UniSmilUtils::IsMediaElem( obj ) )
+ {
+ TMsgMediaType type = UniSmilUtils::MediaElemType( obj );
+ switch ( type )
+ {
+ case EMsgMediaImage:
+ case EMsgMediaVideo:
+ imgEle = obj;
+ break;
+
+ case EMsgMediaText:
+ case EMsgMediaXhtml:
+ txtEle = obj;
+ break;
+
+ // TODO: REF
+ default:
+ break;
+ }
+ }
+ obj = obj->NextSibling();
+ }
+
+ // Resolve ID:s
+ if ( !iTextRegionId.Length() && txtEle )
+ {
+ UniSmilUtils::GetRegionId( txtEle, iTextRegionId );
+ }
+ if ( !iImageRegionId.Length() && imgEle )
+ {
+ UniSmilUtils::GetRegionId( imgEle, iImageRegionId );
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetLayoutElements
+//
+// ---------------------------------------------------------
+void CUniSmilModel::GetLayoutElements( CMDXMLNode* aLayout,
+ CMDXMLElement*& aRlEle,
+ CMDXMLElement*& aTxtEle,
+ CMDXMLElement*& aImgEle )
+ {
+ if ( !aLayout )
+ {
+ return;
+ }
+
+ TPtrC value( KNullDesC );
+ CMDXMLNode* node = aLayout->FirstChild();
+
+ // Search REGIONS & RootLayout
+ while ( node )
+ {
+ // REGION PARAMETERS
+ if ( node->NodeName().CompareF( KSMILWREleRegion ) == 0 )
+ {
+
+ //UniSmilUtils::GetRegionId( node, value );
+ if( ((CMDXMLElement*) node)->IsAttributeSpecified( KSMILWRParaId ) )
+ {
+ ((CMDXMLElement*) node)->GetAttribute( KSMILWRParaId, value );
+ }
+ else
+ {
+ value.Set( KNullDesC );
+ }
+
+ // IMAGE REGION
+ if ( value.CompareF( iImageRegionId ) == 0 )
+ {
+ aImgEle = (CMDXMLElement*) node;
+ }
+
+ // TEXT REGION
+ else if ( value.CompareF( iTextRegionId ) == 0 )
+ {
+ aTxtEle = (CMDXMLElement*) node;
+ }
+
+ }
+ else if ( node->NodeName().CompareF( KSMILWREleRoot_layout ) == 0 )
+ {
+ aRlEle = (CMDXMLElement*) node;
+ }
+
+ node = node->NextSibling();
+
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetMmsSmilLayout
+//
+// ---------------------------------------------------------
+TUniLayout CUniSmilModel::GetMmsSmilLayout( CMDXMLDocument* aDom )
+ {
+ TUniLayout rval = EUniUndefinedLayout;
+
+ iTextRegionId.Set( KNullDesC );
+ iImageRegionId.Set( KNullDesC );
+
+ // --------------------------------------------
+ // Resolve region IDs used in media elements
+ // --------------------------------------------
+ CMDXMLNode* node = GetNode( aDom, KSMILWREleBody );
+ if ( !node )
+ {
+ return rval;
+ }
+
+ // Only one slide in the message since no <par> tag found
+ // Other node types than <par> not possible as this is MMS SMIL.
+ if ( node->FirstChild() )
+ {
+ if ( node->FirstChild()->NodeName().CompareF( KSMILWRElePar ) != 0 )
+ {
+ GetMediaElemRegionIDs( node );
+ }
+ else
+ {
+ CMDXMLNode* page = node->FirstChild();
+ while ( page )
+ {
+ GetMediaElemRegionIDs( page );
+
+ // Go to next page.
+ page = page->NextSibling();
+ }
+ }
+ }
+
+ // -------------------------------------
+ // Search layout elements
+ // -------------------------------------
+ node = GetNode( aDom, KSMILWREleLayout );
+ CMDXMLElement* rootLayout = NULL;
+ CMDXMLElement* textRegion = NULL;
+ CMDXMLElement* imageRegion = NULL;
+ GetLayoutElements( node, rootLayout, textRegion, imageRegion );
+
+ // ------------------------------
+ // Resolve Root Layout
+ // ------------------------------
+ TSize rootSize( 0, 0 );
+ GetRootLayoutSize( rootLayout, rootSize );
+
+ // ------------------------------------
+ // Resolve region parameters
+ // ------------------------------------
+ TRect imgRect( 0, 0, 0, 0 );
+ TRect txtRect( 0, 0, 0, 0 );
+ GetRegionRect( imageRegion, rootSize, imgRect );
+ GetRegionRect( textRegion, rootSize, txtRect );
+
+ // ------------------------------------
+ // Layout decision
+ // ------------------------------------
+ if ( textRegion && imageRegion )
+ {
+ if( imgRect.iTl.iY < txtRect.iTl.iY )
+ {
+ rval = EUniImageFirst;
+ }
+ else if ( imgRect.iTl.iY > txtRect.iTl.iY )
+ {
+ rval = EUniTextFirst;
+ }
+ else
+ {
+ if ( imgRect.iTl.iX <= txtRect.iTl.iX )
+ {
+ rval = EUniImageFirst;
+ }
+ else
+ {
+ rval = EUniTextFirst;
+ }
+ }
+ }
+ else if ( textRegion )
+ {
+ rval = EUniTextFirst;
+ }
+ else // if ( iImgEle ) or none
+ {
+ rval = EUniImageFirst;
+ }
+
+ return rval;
+
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetRootLayoutSize
+//
+// ---------------------------------------------------------
+
+void CUniSmilModel::GetRootLayoutSize( CMDXMLElement* aRl, TSize& aSize )
+ {
+ TPtrC value( KNullDesC );
+
+ if ( aRl )
+ {
+ if( aRl->IsAttributeSpecified( KSMILWRParaWidth ) )
+ {
+ aRl->GetAttribute( KSMILWRParaWidth, value );
+ aSize.iWidth = UniSmilUtils::StringToIntValue( value, 0 );
+ }
+ else
+ {
+ aSize.iWidth = iScreenSize.iWidth;
+ }
+
+ if( aRl->IsAttributeSpecified( KSMILWRParaHeight ) )
+ {
+ aRl->GetAttribute( KSMILWRParaHeight, value );
+ aSize.iHeight = UniSmilUtils::StringToIntValue( value, 0 );
+ }
+ else
+ {
+ aSize.iHeight = iScreenSize.iHeight;
+ }
+ }
+ else
+ {
+ aSize = iScreenSize;
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetRegionRect
+//
+// ---------------------------------------------------------
+
+void CUniSmilModel::GetRegionRect( CMDXMLElement* aRegion, TSize aRoot, TRect& aRect )
+ {
+ TPtrC value;
+
+ TInt width = 0;
+ TInt height = 0;
+
+ if ( aRegion )
+ {
+ if( aRegion->IsAttributeSpecified( KSMILWRParaWidth ) )
+ {
+ aRegion->GetAttribute( KSMILWRParaWidth, value );
+ width = UniSmilUtils::StringToIntValue( value, 0 ) ;
+ if ( value.Locate( '%' ) != KErrNotFound )
+ {
+ width = width * aRoot.iWidth / 100;
+ }
+ }
+
+ if( aRegion->IsAttributeSpecified( KSMILWRParaHeight ) )
+ {
+ aRegion->GetAttribute( KSMILWRParaHeight, value );
+ height = UniSmilUtils::StringToIntValue( value, 0 ) ;
+ if ( value.Locate( '%' ) != KErrNotFound )
+ {
+ height = height * aRoot.iHeight / 100;
+ }
+ }
+
+ if( aRegion->IsAttributeSpecified( KSMILWRParaTop ) )
+ {
+ aRegion->GetAttribute( KSMILWRParaTop, value );
+ aRect.iTl.iY = UniSmilUtils::StringToIntValue( value, 0 );
+ if ( value.Locate( '%' ) != KErrNotFound )
+ {
+ aRect.iTl.iY = aRect.iTl.iY * aRoot.iHeight / 100;
+ }
+ }
+ else
+ {
+ aRect.iTl.iY = 0;
+ }
+
+ if( aRegion->IsAttributeSpecified( KSMILWRParaLeft ) )
+ {
+ aRegion->GetAttribute( KSMILWRParaLeft, value );
+ aRect.iTl.iX = UniSmilUtils::StringToIntValue( value, 0 );
+ if ( value.Locate( '%' ) != KErrNotFound )
+ {
+ aRect.iTl.iX = aRect.iTl.iX * aRoot.iWidth / 100;
+ }
+ }
+ else
+ {
+ aRect.iTl.iX = 0;
+ }
+
+ aRect.iBr.iY = aRect.iTl.iY + height;
+ aRect.iBr.iX = aRect.iTl.iX + width;
+
+ }
+ else
+ {
+ aRect = TRect( 0, 0, 0, 0 );
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetRegionType
+// ---------------------------------------------------------
+//
+TUniRegion CUniSmilModel::GetRegionType( CMDXMLNode* aNodePtr )
+ {
+ if ( iImageRegionId.CompareF( iTextRegionId ) == 0 )
+ {
+ // Image and text regions are the same!
+ // Literally taken this is agains MMS SMIL, but
+ // we should still tolerate it.
+ iParseResult |= ETextAndImageRegionsSame;
+ return EUniRegionUnresolved;
+ }
+ TPtrC regId;
+ TInt err = UniSmilUtils::GetRegionId( aNodePtr, regId );
+ if ( !err )
+ {
+ if ( regId.CompareF( iImageRegionId ) == 0 )
+ {
+ return EUniRegionImage;
+ }
+ else if ( regId.CompareF( iTextRegionId ) == 0 )
+ {
+ return EUniRegionText;
+ }
+ else
+ {
+ return EUniRegionUnresolved;
+ }
+ }
+ else
+ {
+ return EUniRegionUnresolved;
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CUniSmilModel::GetNode
+//
+// ---------------------------------------------------------
+CMDXMLNode* CUniSmilModel::GetNode( CMDXMLDocument* aDom, const TDesC& aName )
+ {
+ CMDXMLNode* node = aDom->DocumentElement()->FirstChild();
+ while ( node )
+ {
+ if ( node->NodeName().CompareF( aName ) == 0 )
+ {
+ break;
+ }
+ else
+ {
+ node = UniSmilUtils::NextNode( node );
+ }
+ }
+ return node;
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::RemoveMetaTagsAndComments
+//
+// ---------------------------------------------------------
+void CUniSmilModel::RemoveMetaTagsAndComments( CMDXMLDocument* aDom )
+ {
+ CMDXMLNode* node = aDom->DocumentElement()->FirstChild();
+ while ( node )
+ {
+ if ( node->NodeType() == CMDXMLNode::ECommentNode ||
+ node->NodeName().CompareF( KSMILWREleMeta ) == 0 )
+ {
+ CMDXMLNode* removeNode = node;
+ node = removeNode->ParentNode();
+ /*TInt ignore =*/ node->RemoveChild( removeNode );
+ delete removeNode;
+ }
+ node = UniSmilUtils::NextNode( node );
+ }
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::CorrectSlideTimingL
+//
+// ---------------------------------------------------------
+void CUniSmilModel::CorrectSlideTimingL( CMDXMLElement* aPage )
+ {
+ CMDXMLNode* node = aPage->FirstChild();
+
+ // Traverse through every object in page.
+ while ( node != NULL )
+ {
+ if ( UniSmilUtils::IsMediaElem( node ) )
+ {
+ CMDXMLElement* nodeElement = static_cast<CMDXMLElement*>( node );
+
+ CUniObject* obj = iObjectList.GetByNodeL( node );
+
+ if( !obj ||
+ !obj->MediaInfo() ||
+ obj->MediaInfo()->Duration() != 0 ||
+ TimingSpecified( nodeElement ) )
+ {
+ // Return as non-static media was found from the page.
+ return;
+ }
+ else if ( nodeElement->IsAttributeSpecified( KSMILWRParaBegin ) )
+ {
+ // Remove invalid Begin element since no End or Dur attributes is specified.
+ nodeElement->RemoveAttribute( KSMILWRParaBegin );
+ }
+ else if ( nodeElement->IsAttributeSpecified( KSMILWRParaEnd ) )
+ {
+ // Remove invalid End element since no Begin or Dur attributes is specified.
+ nodeElement->RemoveAttribute( KSMILWRParaEnd );
+ }
+ }
+
+ node = node->NextSibling();
+ }
+
+ // Read default smil parameters
+ if ( !iSmilParams )
+ {
+ iSmilParams = CUniSmilParams::NewL( iFs );
+ }
+
+ TBuf16<20> defaultVal;
+ defaultVal.Zero();
+ defaultVal.Format( KSmilMsecFormat, iSmilParams->iComposeParams->iSlideDuration );
+
+ aPage->SetAttributeL( KSMILWRParaDur, defaultVal );
+ }
+
+// ---------------------------------------------------------
+// CUniSmilModel::TimingSpecified
+//
+// ---------------------------------------------------------
+TBool CUniSmilModel::TimingSpecified( CMDXMLElement* aNodePrt )
+ {
+ TBool result( EFalse );
+
+ // Timing is set if dur or begin & end parameters are found
+ if ( aNodePrt &&
+ ( aNodePrt->IsAttributeSpecified( KSMILWRParaDur ) ||
+ ( aNodePrt->IsAttributeSpecified( KSMILWRParaBegin ) &&
+ aNodePrt->IsAttributeSpecified( KSMILWRParaEnd ) ) ) )
+ {
+ result = ETrue;
+ }
+
+ return result;
+ }
+
+// End of file