Fixed "extra qualification" syntax errors.
/*
* 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: SVG Implementation source file
*
*/
// INCLUDE FILES
#include "SVGDiscardElementImpl.h"
#include "SVGDocumentImpl.h"
#include "SVGSchemaData.h"
#include "SVGAnimTimingParser.h"
#include "SVGEngineImpl.h"
#include "SVGAnimationBase.h"
#include "SVGRectElementImpl.h"
#include "SVGEvent.h"
#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif
// ============================= LOCAL FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// RemoveTargetElement: A utility function that renmoves target element.
// Remove target element and all its child from its parent level.
// Allocated Style properties of the target elements have to be deleted here.
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::RemoveTargetElement()
{
if (iTargetElement!= NULL)
{
CSvgElementImpl* lParent = (CSvgElementImpl*)iTargetElement->ParentNode();
if ( lParent != NULL )
{
lParent->RemoveChild(iTargetElement);
}
else if ( iTargetElement->ElemID() == KSvgSvgElement )
{
// remove all children
CSvgElementImpl* child = (CSvgElementImpl*)iTargetElement->FirstChild();
CSvgElementImpl* sib = (CSvgElementImpl*) NULL;
while ( (child != NULL ) || sib != (CSvgElementImpl*) NULL )
{
sib = (CSvgElementImpl*)child->NextSibling();
// remove myself later
if (child != this)
{
iTargetElement->RemoveChild(child);
delete child;
}
child = sib;
}
}
// make sure that the target element is not root
if ( iTargetElement->ElemID() != KSvgSvgElement )
{
delete iTargetElement;
iTargetElement = NULL;
}
iRemoveMyself = ETrue;
}
}
// -----------------------------------------------------------------------------
// FindTargetElementL: A utility function that finds target element
// and adjust the begin time.
//
// Returns: TBool ETrue if target is set.
// EFalse if target is not found.
// -----------------------------------------------------------------------------
//
TBool CSvgDiscardElementImpl::FindTargetElementL()
{
if (iTargetElement)
return ETrue;
// Target could be set from one of the following ways:
// 1) Defined as SyncBased value. ==> get element
// 2) xlink-href defined. ==> get element
// 3) Invalid element id ==> Ignore
// 4) No specified xlink-href nor other element id. ==> Use parent
if ( iHrefValueDefined )
{
// Case 2 & 3
TPtrC lPtr = iTargetId->Des();
iTargetElement = ( CSvgElementImpl * )
((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(lPtr);
if (iTargetElement == NULL)
{
// Case 3
// Ignore and remove myself later.
iRemoveMyself = ETrue;
return EFalse;
}
}
else // Case 4
{
// Set parent to target only when the parent is an animation element
iTargetElement = ( CSvgElementImpl * ) ParentNode();
}
// Target element should be determined by now.
// Check to see if the target element is animatable.
// If not, remove myself.
// Calculate begin time.
if ( iSyncValueDefined )
{
// Get reference target element
iRefTargetElement = ( CSvgElementImpl * )
((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(iBeginSyncElementId);
// Only Syncbased begin time
if (!iEventValueDefined)
{
// If specified element doesn't exist or the element is not animated,
// remove myself.
if ((iRefTargetElement == NULL) /*|| !IsAnimationElement(iRefTargetElement)*/)
{
// No referenced element or not animatable element (no begin/end attr)
// ==> Ignore and remove myself later.
iRemoveMyself = ETrue;
return EFalse;
}
// re-calculate begin time. e.g. id1.start+5s
if (iBeginReferenceEvent == ESvgEventBeginEvent)
{
iAbsoluteBeginTime +=
((CSvgAnimationBase*)iRefTargetElement)->GetAbsoluteBeginTime();
}
else if (iBeginReferenceEvent == ESvgEventEndEvent)
{
iAbsoluteBeginTime +=
((CSvgAnimationBase*)iRefTargetElement)->GetEndTime();
}
}
else // iEventValueDefined is TRUE
{
// Listen external events
((CSvgDocumentImpl*)
iOwnerDocument)->AddToEventReceiverListL(iRefTargetElement,
KSvgEventMaskExternalUI);
}
}
else if (iEventValueDefined)
{
// Listen external events
((CSvgDocumentImpl*)
iOwnerDocument)->AddToEventReceiverListL(iTargetElement,
KSvgEventMaskExternalUI);
}
return ETrue; // Set Target element
}
// -----------------------------------------------------------------------------
// HasAnimationElements: A utility function that check if the element
// contains animation element(s).
//
// Returns: TBool ETrue if the element contains animation element(s)
// EFalse if the element doesn't animated.
// -----------------------------------------------------------------------------
//
/*
TBool CSvgDiscardElementImpl::HasAnimationElements(CSvgElementImpl* aElement)
{
TBool lFound = EFalse;
// Return immediately if the target element is already an animation element.
if (IsAnimationElement(aElement))
return ETrue;
// Look through childs
CSvgElementImpl* child = (CSvgElementImpl*)aElement->FirstChild();
while ( child != NULL )
{
if ( IsAnimationElement(child) )
{
lFound = ETrue;
break;
}
child = (CSvgElementImpl*)child->NextSibling();
}
if (lFound)
return ETrue;
return EFalse;
}
*/
// -----------------------------------------------------------------------------
// IsAnimationElement: A utility function that check if the element
// is an animation element.
//
// Returns: TBool ETrue if the element is a animation element.
// EFalse if the element is not an animation element.
// -----------------------------------------------------------------------------
//
/*
TBool CSvgDiscardElementImpl::IsAnimationElement(CSvgElementImpl* aElement)
{
TInt id = aElement->ElemID();
return (( id == KSvgAnimateElement ) ||
( id == KSvgAnimateMotionElement ) ||
( id == KSvgAnimateTransformElement ) ||
( id == KSvgSetElement ) ||
( id == KSvgAnimateColorElement ));
}
*/
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// SetAttributeL: The implemented function will be called from CSvgContentHandler.
//
// From CSvgElementImpl
//
// There will be two attributes been set: begin and xlink:href.
// If xlink:href is not specified, the target element will be parent element
// If begin time is not specifid, the target element will be remove immdeiately.
//
// Returns: ETrue always in this case.
// -----------------------------------------------------------------------------
//
TInt CSvgDiscardElementImpl::SetAttributeL( const TDesC& aName,
const TDesC& aValue )
{
_LIT( KTmpXlinkHref, "xlink:href" );
_LIT( KTmpBegin, "begin" );
// If not xlink:href, it must be attribute "begin"
if ( aName == KTmpXlinkHref )
{
// STEP 1 - Get the reference element
// If the first char is '#' then remove it
// This is possible if coming from cXML parser and not the Decoder
iHrefValueDefined = ETrue;
TInt pos = aValue.Locate( '#' );
if ( pos == 0 )
{
if (iTargetId)
{
delete iTargetId;
iTargetId = NULL;
}
iTargetId = aValue.AllocL();
TPtr tPtr = iTargetId->Des();
tPtr.Delete(pos, 1);
}
}
else if ( aName == KTmpBegin )
{
CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( aValue, this );
TInt32 clockValue;
TReal32 lRepeatBeginValue;
atParser->Parse( iBeginSyncElementId,
iBeginReferenceEvent,
clockValue,
lRepeatBeginValue,
ETrue);
iAbsoluteBeginTime = clockValue;
if ( iBeginSyncElementId.Size() != 0 )
{
iSyncValueDefined = ETrue;
}
if ( iBeginReferenceEvent != ESvgEventNone )
{
iEventValueDefined = ETrue;
iRefBeginTime = clockValue;
iAbsoluteBeginTime = KTimeIndefinite;
if (iBeginReferenceEvent == ESvgEventKey)
{
iKeyValue = atParser->AccekeyValue();
}
}
CleanupStack::PopAndDestroy( 1 ); // atParser
}
CSvgElementImpl::SetAttributeL(aName,aValue);
return KErrNone;
}
// -----------------------------------------------------------------------------
// ReceiveEventL: The implemented function will be called whenever subscribed
// events are received.
//
// From MSvgEventReceiver
//
// Return: TBool ETrue if redraw is needed
// EFalse if redraw is not needed
// -----------------------------------------------------------------------------
//
TBool CSvgDiscardElementImpl::ReceiveEventL( MSvgEvent* aEvent )
{
if (iRemoveMyself)
{
// Two reasons to remove myself.
// 1) when discard element is not sepcified inside of the target
// element so the object is not removed automatically along with
// target element.
// 2) Invalid begin time
iTargetElement = ( CSvgElementImpl * ) ParentNode();
iTargetElement->RemoveChild(this);
delete this;
return EFalse;
}
// Looking for target as soon as first event received. Also adject time
// according to timeing attribute.
if (!FindTargetElementL())
{
// Target not found, exit and remove myself next time
return EFalse;
}
// Target element should be identified by now.
CSvgEngineImpl* engine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine();
if (engine == NULL)
{
return EFalse;
}
TInt32 lEngineCurrentTime = engine->CurrentTIme();
// User input event
if (aEvent->EventType() == ESvgEngineEventKeyPress)
{
MSvgUiKeyEvent* evt = ( MSvgUiKeyEvent* ) aEvent;
if (evt->KeyCode() == iKeyValue)
{
// Remove target immediately
RemoveTargetElement();
engine->RedrawL();
return ETrue;
}
return EFalse;
}
// Timer event
if (aEvent->EventMask() == KSvgEventMaskTimer)
{
if (lEngineCurrentTime >= iAbsoluteBeginTime)
{
// Time to remove target
RemoveTargetElement();
}
}
// Internal event
else if ((aEvent->EventMask() == KSvgEventMaskInternal )
&& (!iRefBeginTimeSet))
{
MSvgInternalEvent* evt = ( MSvgInternalEvent* ) aEvent;
TSvgEvent s_evt = evt->SvgEvent();
if (s_evt == iBeginReferenceEvent)
{
// Event other than AccessKey
// Check to see if there is a clock associated with the event.
if (s_evt == iBeginReferenceEvent)
{
// This is some form of event+(-)clock so delay removing
// Note that once the reference time is set, the absolutetime
// can't be changed with other events.
if (iRefTargetElement != NULL)
{
// This is a syncbased event
if (evt->ObjectAddress() == iRefTargetElement)
{
iAbsoluteBeginTime = lEngineCurrentTime + iRefBeginTime;
iRefBeginTimeSet = ETrue;
return EFalse;
}
}
else
{
// Not syncbased event
if (evt->ObjectAddress() == iTargetElement)
{
iAbsoluteBeginTime = lEngineCurrentTime + iRefBeginTime;
iRefBeginTimeSet = ETrue;
return EFalse;
}
}
} // if (s_evt == iBeginReferenceEvent)...
else
{
// No clock assoicated with the event.
if (iRefTargetElement != NULL)
{
// This is a syncbased event
if (evt->ObjectAddress() == iRefTargetElement)
{
// Remove target immediately
RemoveTargetElement();
}
}
// Not syncbased event
else if (evt->ObjectAddress() == iTargetElement)
{
// Remove target immediately
RemoveTargetElement();
}
}
} // if (s_evt == iBeginReferenceEvent)...
} //if ((aEvent->EventMask() == KSvgEventMaskInte...
else
{
// Not interested event
return EFalse;
}
// return true to be redrawn
return ETrue;
}
// Setter functions
// -----------------------------------------------------------------------------
// SetTargetId: Set iTargetId to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetTargetId(const TDesC& aTargetId)
{
delete iTargetId;
iTargetId = NULL;
TRAPD(err, iTargetId = aTargetId.AllocL());
if (err != KErrNone)
{
// Only display error message. If this failed, iTargetId can safely to be null.
#ifdef _DEBUG
RDebug::Printf("CSvgDiscardElementImpl::SetTargetId Error: memory allocation failed.");
#endif
}
}
// -----------------------------------------------------------------------------
// SetSyncValueDefined: Set iSyncValueDefined to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetSyncValueDefined(TBool aSyncValueDefined)
{
iSyncValueDefined = aSyncValueDefined;
}
// -----------------------------------------------------------------------------
// SetEventValueDefined: Set iEventValueDefined to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetEventValueDefined(TBool aEventValueDefined)
{
iEventValueDefined = aEventValueDefined;
}
// -----------------------------------------------------------------------------
// SetHrefValueDefined: Set iHrefValueDefined to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetHrefValueDefined(TBool aHrefValueDefined)
{
iHrefValueDefined = aHrefValueDefined;
}
// -----------------------------------------------------------------------------
// SetBeginSyncElementId: Set aBeginSyncElementId to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetBeginSyncElementId(const TDesC& aBeginSyncElementId)
{
iBeginSyncElementId.SetLength(0);
iBeginSyncElementId.Append(aBeginSyncElementId);
}
// -----------------------------------------------------------------------------
// SetAbsoluteBeginTime: Set iAbsoluteBeginTime to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetAbsoluteBeginTime(TInt aAbsoluteBeginTime)
{
if (aAbsoluteBeginTime == -1)
{
iAbsoluteBeginTime = KTimeIndefinite;
}
else
{
iAbsoluteBeginTime = aAbsoluteBeginTime;
}
}
// -----------------------------------------------------------------------------
// SetRefBeginTime: Set aRefBeginTime to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetRefBeginTime(TInt aRefBeginTime)
{
iRefBeginTime = aRefBeginTime;
}
// -----------------------------------------------------------------------------
// SetKeyValue: Set aKeyValue to the object. Mainly used by decoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetKeyValue(TInt aKeyValue)
{
iKeyValue = aKeyValue;
}
// -----------------------------------------------------------------------------
// TargetId: Returns iBeginReferenceEvent that is specified in begin attribute.
// Mainly used by encoder.
//
// Returns: void
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::SetBeginReferenceEvent(TSvgEvent aBeginReferenceEvent)
{
iBeginReferenceEvent = aBeginReferenceEvent;
}
// Getter functions
// -----------------------------------------------------------------------------
// TargetId: Returns the target element's id. Mainly used by encoder.
//
// Returns: Descriptor of target element's id
// -----------------------------------------------------------------------------
//
const TDesC& CSvgDiscardElementImpl::TargetId()
{
return (TDesC&) *iTargetId;
}
// -----------------------------------------------------------------------------
// BeginSyncElementId: Returns element's id that is specified in begin attribute.
// Mainly used by encoder.
//
// Returns: Descriptor of the element's id
// -----------------------------------------------------------------------------
//
const TDesC& CSvgDiscardElementImpl::BeginSyncElementId()
{
return iBeginSyncElementId;
}
// -----------------------------------------------------------------------------
// AbsoluteBeginTime: Returns the absolute begin time that is identified in
// SetAttribute. The begin time may be changed when using with SyncBase or
// EventBased attribute.
//
// Mainly used by encoder.
//
// Returns: TInt AbsoluteBeginTime
// -----------------------------------------------------------------------------
//
TInt CSvgDiscardElementImpl::AbsoluteBeginTime()
{
if (iAbsoluteBeginTime == KTimeIndefinite)
{
// write -1 in case both encorder and decoder understand.
return -1;
}
else
{
return iAbsoluteBeginTime;
}
}
// -----------------------------------------------------------------------------
// IsSyncValueDefined: Returns the flag iSyncValueDefined that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TBool iSyncValueDefined
// -----------------------------------------------------------------------------
//
TBool CSvgDiscardElementImpl::IsSyncValueDefined()
{
return iSyncValueDefined;
}
// -----------------------------------------------------------------------------
// IsEventValueDefined: Returns the flag iEventValueDefined that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TBool iEventValueDefined
// -----------------------------------------------------------------------------
//
TBool CSvgDiscardElementImpl::IsEventValueDefined()
{
return iEventValueDefined;
}
// -----------------------------------------------------------------------------
// IsHrefValueDefined: Returns the flag iHrefValueDefined that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TBool iHrefValueDefined
// -----------------------------------------------------------------------------
//
TBool CSvgDiscardElementImpl::IsHrefValueDefined()
{
return iHrefValueDefined;
}
// -----------------------------------------------------------------------------
// RefBeginTime: Returns the reference begin time that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TInt iRefBeginTime
// -----------------------------------------------------------------------------
//
TInt CSvgDiscardElementImpl::RefBeginTime()
{
return iRefBeginTime;
}
// -----------------------------------------------------------------------------
// KeyValue: Returns the key value (scan code) that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TInt iKeyValue
// -----------------------------------------------------------------------------
//
TInt CSvgDiscardElementImpl::KeyValue()
{
return iKeyValue;
}
// -----------------------------------------------------------------------------
// KeyValue: Returns the iBeginReferenceEvent that was set in
// SetAttribute.
//
// Mainly used by encoder.
//
// Returns: TSvgEvent iBeginReferenceEvent
// -----------------------------------------------------------------------------
//
TSvgEvent CSvgDiscardElementImpl::BeginReferenceEvent()
{
return iBeginReferenceEvent;
}
// -----------------------------------------------------------------------------
// CloneL: Perform a deep clone of this object
//
// Returns: MXmlElement pointer to the newly created element.
// -----------------------------------------------------------------------------
//
MXmlElement* CSvgDiscardElementImpl::CloneL(MXmlElement* aParentElement)
{
CSvgDiscardElementImpl* newElement = CSvgDiscardElementImpl::NewL( this->ElemID(),
((CSvgDocumentImpl*)iOwnerDocument) );
CleanupStack::PushL(newElement);
newElement->iParentNode = aParentElement;
// copy everything over
this->CopyL(newElement);
CleanupStack::Pop();
return newElement;
}
// -----------------------------------------------------------------------------
// CopyL: Perform a deep copy of this object
//
// Returns: none
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::CopyL( CSvgDiscardElementImpl* aDestElement )
{
if(aDestElement)
{
aDestElement->iOwnerDocument = this->iOwnerDocument;
// copy stuff from superclass
this->CSvgElementImpl::CopyL(aDestElement);
}
}
// -----------------------------------------------------------------------------
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSvgDiscardElementImpl* CSvgDiscardElementImpl::NewL( const TUint8 aElemID,
CSvgDocumentImpl* aDoc)
{
CSvgDiscardElementImpl* self = new (ELeave)CSvgDiscardElementImpl(aDoc);
CleanupStack::PushL( self );
self->ConstructL( aElemID );
CleanupStack::Pop();
return self;
}
// -----------------------------------------------------------------------------
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSvgDiscardElementImpl* CSvgDiscardElementImpl::NewLC( const TUint8 aElemID,
CSvgDocumentImpl* aDoc)
{
CSvgDiscardElementImpl* self = new (ELeave) CSvgDiscardElementImpl(aDoc);
CleanupStack::PushL( self );
self->ConstructL( aElemID );
return self;
}
// -----------------------------------------------------------------------------
// C++ default constructor
// -----------------------------------------------------------------------------
//
CSvgDiscardElementImpl::CSvgDiscardElementImpl( CSvgDocumentImpl* aDoc )
{
SetOwnerDocument(aDoc);
}
// -----------------------------------------------------------------------------
// Symbian default constructor that can leave.
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::ConstructL( const TUint8 aElemID )
{
CXmlElementImpl::InitializeL( aElemID );
iTargetElement = NULL;
iTargetId = HBufC::NewL(0);
iAbsoluteBeginTime = 0;
iRemoveMyself = EFalse;
iHrefValueDefined = EFalse;
iBeginReferenceEvent = (TSvgEvent)NULL;
iSyncValueDefined = EFalse;
iEventValueDefined = EFalse;
iRefBeginTime = 0;
iRefTargetElement = NULL;
iRefBeginTimeSet = EFalse;
iKeyValue = 0;
iBeginSyncElementId.SetLength(0);
((CSvgDocumentImpl*)
iOwnerDocument)->AddToEventReceiverListL(this, KSvgEventMaskTimer |
KSvgEventMaskInternal | KSvgEventMaskExternalUI);
}
// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CSvgDiscardElementImpl::~CSvgDiscardElementImpl()
{
delete iTargetId;
}
// -----------------------------------------------------------------------------
// Print
// -----------------------------------------------------------------------------
//
void CSvgDiscardElementImpl::Print( TBool aIsEncodeOn )
{
if (!aIsEncodeOn)
{
#ifdef _DEBUG
RDebug::Printf("<discard xlink:href =\"hmm\" begin=\"%d\" />", /*Href(),*/ (int)iAbsoluteBeginTime);
#endif
}
}
// End of File