diff -r 4ea6f81c838a -r 0e9bb658ef58 widgetmodel/alfwidgetmodel/src/alfvisualtemplate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgetmodel/alfwidgetmodel/src/alfvisualtemplate.cpp Wed Sep 01 12:23:18 2010 +0100 @@ -0,0 +1,671 @@ +/* +* Copyright (c) 2007 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: Visual template class for alfred widget model. +* This class creates and updates visual tree. +* +*/ + + + + +//INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "alf/alfperf.h" +#include +#include +#include "alf/alfvisualtemplate.h" +#include "alf/alfvarianttype.h" +#include "alf/ialfattributesetter.h" +#include "alf/alfattributecontainer.h" +#include "alf/alfattribute.h" + +// The number of attribute setters is usually between 1 and 5 +static const int KAttributeArrayGranularity = 4; +static const int KContainerArrayGranularity = 4; + +namespace Alf + { + +struct DeleteTemplate +{ + void operator()(const IAlfVisualTemplate* aTemplate) const + { + delete aTemplate; + } +}; + +// ----------------------------------------------------------------------------- +// Helper function to iterate through a visual template hierarchy and +// investigate whether a given visual template exists in it. +// ----------------------------------------------------------------------------- +bool existsInHierarchy(IAlfVisualTemplate& aRoot, const IAlfVisualTemplate& aTemplate) + { + // Check the template against the root node. + if(&aTemplate == &aRoot) + { + return true; + } + + // Iterate through all the root's children + for(int i = 0; i < aRoot.numChildTemplates(); ++i) + { + if(existsInHierarchy(aRoot.childTemplate(i), aTemplate)) + { + return true; + } + } + + return false; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create() + { + return new( EMM ) AlfVisualTemplate; + } + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create(TAlfVisualType aType) + { + return new( EMM ) AlfVisualTemplate( aType ); + } + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate* AlfVisualTemplate::create(TAlfLayoutType aType) + { + return new( EMM ) AlfVisualTemplate( aType ); + } + +// ============================ MEMBER FUNCTIONS =============================== + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate(): + mVisualType(EAlfVisualTypeVisual), + mAttributeArray(KAttributeArrayGranularity), + mContainerArray(KContainerArrayGranularity), + mSelectOneChild(false), + mOwner(0), + mParent(0) + { + } + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate(TAlfVisualType aType): + mVisualType(aType), + mAttributeArray(KAttributeArrayGranularity), + mContainerArray(KContainerArrayGranularity), + mSelectOneChild(false), + mOwner(0), + mParent(0) + { + } + +// --------------------------------------------------------------------------- +// Description : Constructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate::AlfVisualTemplate(TAlfLayoutType aType): + mVisualType(-1 - aType), + mAttributeArray(KAttributeArrayGranularity), + mContainerArray(KContainerArrayGranularity), + mSelectOneChild(false), + mOwner(0), + mParent(0) + { + } + +// --------------------------------------------------------------------------- +// Description : Destructor +// --------------------------------------------------------------------------- +OSN_EXPORT AlfVisualTemplate::~AlfVisualTemplate() + { + mBrushArray.clear(); + mAttributeArray.clear(); + mContainerArray.clear(); + + // Remove this visual template from it's parent or owner + if(parent()) + { + parent()->removeChildTemplate(*this); + } + if(owner()) + { + owner()->removeVisualTemplate(); + } + + // Destroy child visual templates in two passes, since destructor of a child + // visual template could affect the content of the this visual template's child vector. + vector children(mChildren); + mChildren.clear(); + for_each(children.begin(), children.end(), DeleteTemplate()); + } + +// --------------------------------------------------------------------------- +// Description : Set the owner element. +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setOwner(IAlfElement* aOwner) throw() + { + if(aOwner != mOwner) + { + // Remove this visual template from it's parent. Parent and owner are + // mutually exclusive properties on a visual template. + if(aOwner && (parent() != 0)) + { + parent()->removeChildTemplate(*this); + } + + // Set the owner of this visual template. + mOwner = aOwner; + } + } + +OSN_EXPORT IAlfElement* AlfVisualTemplate::owner() const throw() + { + return mOwner; + } + +// --------------------------------------------------------------------------- +// Description : Set the name of the visual, i.e., the tag. +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setName(const char* aName) + { + mVisualName = UString(aName); + } + +// --------------------------------------------------------------------------- +// Description : Get the name of the visual, i.e., the tag. +// --------------------------------------------------------------------------- +OSN_EXPORT const char* AlfVisualTemplate::name() const throw() + { + return mVisualName.getUtf8(); + } + +// --------------------------------------------------------------------------- +// Description : Add a child visual template. +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::addChildTemplate(IAlfVisualTemplate& aChild) + { + insertChildTemplate(aChild, mChildren.size()); + } + +// --------------------------------------------------------------------------- +// Description : Inserts a child visual template at given index +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::insertChildTemplate(IAlfVisualTemplate& aChild, int aIndex) + { + if(!(aIndex >=0 && aIndex <= mChildren.size())) + ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::insertChildTemplate() - Index out of bounds."); + + // Verify that the given argument is valid + if(existsInHierarchy(*this, aChild)) + { + ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Adding a child visual template that is already in the hierarchy."); + } + if(existsInHierarchy(aChild, *this)) + { + ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Attempt to create a recursive visual template tree."); + } + if(layoutType() < 0) + { + ALF_THROW(AlfException, EInvalidHierarchy, "AlfVisualTemplate::insertChildTemplate() - Attempt to add a child visual into a non-layout visual template."); + } + + // Insert child visual template to the array + mChildren.insert(mChildren.begin() + aIndex, &aChild); + + // Remove child from previous hierarchy and add it under this visual template. + if(aChild.parent()) + { + // Visual template cannot have a parent and owner at the same time. + assert(aChild.owner() == 0); + aChild.parent()->removeChildTemplate(aChild); + } + if(aChild.owner()) + { + // Visual template cannot have a parent and owner at the same time. + assert(aChild.parent() == 0); + aChild.owner()->removeVisualTemplate(); + } + + // Set a new parent for this visual template. + aChild.setParent(this); + } + +// --------------------------------------------------------------------------- +// Description : Destroyes a child visual template at given index +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::destroyChildTemplate(int aIndex) throw() + { + // Remove and destroy a child template by the given index + if(aIndex >=0 && aIndex < mChildren.size()) + { + IAlfVisualTemplate* child = mChildren[aIndex]; + removeChildTemplate(*child); + delete child; + } + } + +// --------------------------------------------------------------------------- +// Description : Destroyes a child visual template.with the given name +// --------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::destroyChildTemplate(const char* aName) throw() + { + // Search through the children for the given name. + for(int i = 0; i < mChildren.size() ;i++) + { + if(!strcmp(mChildren[i]->name(), aName)) + { + // Remove and destroy the found child visual template + IAlfVisualTemplate* child = mChildren[i]; + removeChildTemplate(*child); + delete child; + } + } + } + +// --------------------------------------------------------------------------- +// Description : Get the number of child visual templates. +// --------------------------------------------------------------------------- +OSN_EXPORT int AlfVisualTemplate::numChildTemplates() const throw() + { + return mChildren.size(); + } + +// --------------------------------------------------------------------------- +// Description : Get a child visual template. +// --------------------------------------------------------------------------- +OSN_EXPORT IAlfVisualTemplate& AlfVisualTemplate::childTemplate(int aIndex) const + { + if((aIndex < 0) || (aIndex >= numChildTemplates())) + { + ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::childTemplate() - Index out of bounds."); + } + return *mChildren[aIndex]; + } + +// ----------------------------------------------------------------------------- +// Description : Add a new visual attribute setter. The ownership is not passed. +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::addAttributeSetter( + IAlfAttributeSetter* aSetter, AlfAttributeContainer* aContainer ) + { + mAttributeArray.resize(mAttributeArray.count()+1); + mContainerArray.resize(mContainerArray.count()+1); + + mAttributeArray.insert(mAttributeArray.count(),aSetter); + mContainerArray.insert(mContainerArray.count(),aContainer); + } + +// ----------------------------------------------------------------------------- +// Description : Get the number of visual attribute setters. +// ----------------------------------------------------------------------------- +OSN_EXPORT int AlfVisualTemplate::numAttributeSetters() const throw() + { + return mAttributeArray.count(); + } + +// ----------------------------------------------------------------------------- +// Description : Get a visual attribute setter. +// ----------------------------------------------------------------------------- +OSN_EXPORT IAlfAttributeSetter& AlfVisualTemplate::attributeSetter(int aIndex) const + { + if((aIndex < 0) || (aIndex >= mAttributeArray.count())) + { + ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::attributeSetter() - Index out of bounds."); + } + return *mAttributeArray[aIndex]; + } + +// ----------------------------------------------------------------------------- +// Description : +// ----------------------------------------------------------------------------- +OSN_EXPORT AlfAttributeContainer& AlfVisualTemplate::attributeContainer(int aIndex) const + { + if((aIndex < 0) || (aIndex >= mContainerArray.count())) + { + ALF_THROW(AlfException, EInvalidArrayIndex, "AlfVisualTemplate::attributeContainer() - Index out of bounds."); + } + return *mContainerArray[aIndex]; + } + +// ----------------------------------------------------------------------------- +// Description : Update an existing visual tree with new values +// ----------------------------------------------------------------------------- +OSN_EXPORT CAlfVisual* AlfVisualTemplate::updateVisualTree(IAlfMap* aData, IAlfMap* aOldData, CAlfVisual& aVisual) + { + + CAlfVisual* retVisual = &aVisual; + // Update the attributes. + for (int i = 0; i < mAttributeArray.count(); ++i) + { + try + { + //ALF_PERF_START( perfdata, "AlfVisualTemplate-updateVisualTree-SetAttributeValue") + mAttributeArray[i]->setAttributeValue(aVisual, mContainerArray[i], aData); + //ALF_PERF_STOP( perfdata, "AlfVisualTemplate-updateVisualTree-setAttributeValue") + } + catch (...) + { + ALF_THROW(AlfAttributeException,EInvalidAttributeValue,"AlfVisualTemplate") + } + } + // Pass to children + if (mChildren.size()) + { + int ind = selectedChildInd( aData ); + if (ind >= 0 && ind < mChildren.size()) + { + CAlfLayout *layout = (CAlfLayout *)&aVisual; + int indOld = selectedChildInd( aOldData ); + if ( ind == indOld ) + { + mChildren[ind]->updateVisualTree( aData, aOldData, *layout ); + } + else + { + CAlfControl& c(aVisual.Owner()); + + //new visual tree is created. Replaces the current (now old) layout, + //which is removed from its parent and destroyed. + //new layout is returned from the function. + CAlfLayout* parentLayout = layout->Layout(); + TInt ind = parentLayout->FindVisual(layout); + parentLayout->Remove(layout); + layout->RemoveAndDestroyAllD(); + CAlfLayout* newLayout = (CAlfLayout *) createVisualTree(c, aData, parentLayout, ind); + retVisual = newLayout; + } + } + else + { + CAlfLayout *layout = (CAlfLayout *)&aVisual; + for (int i = 0; i < mChildren.size(); ++i) + { + mChildren[i]->updateVisualTree(aData, aOldData, layout->Visual(i)); + } + } + } + return retVisual; + } + +// ----------------------------------------------------------------------------- +// Description : create a new visual tree and initialize the visuals +// ----------------------------------------------------------------------------- +OSN_EXPORT CAlfVisual* AlfVisualTemplate::createVisualTree(CAlfControl& aControl, + IAlfMap* aData, CAlfLayout* aParentLayout, int aLayoutIndex) + { + // create the visual + CAlfVisual *result = NULL; + CAlfLayout *layout = NULL; + if (!mSelectOneChild) + { + if (mVisualType < 0) + { + //ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-NewLayout") + // create layout + result = layout = AlfVisualFactory::NewLayoutL( + (TAlfLayoutType)(-1 - mVisualType), aParentLayout, aControl, aControl.Env()); + //ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-NewLayout") + if (!result) + { + ALF_THROW(AlfVisualException,ECanNotCreateVisual,"AlfVisualTemplate") + } + } + else + { + // create visual + //ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-NewVisual") + result = AlfVisualFactory::NewVisualL( + (TAlfVisualType)mVisualType, aParentLayout, aControl, aControl.Env()); + //ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-NewVisual") + if (!result) + { + ALF_THROW(AlfVisualException,ECanNotCreateVisual,"AlfVisualTemplate") + } + + //Add the brushes to the visual + result->EnableBrushesL(true); + for (int i=0; i < mBrushArray.count(); i++) + { + result->Brushes()->AppendL(mBrushArray[i], EAlfDoesNotHaveOwnership); + } + } + if (aParentLayout && + aLayoutIndex >= 0 && aLayoutIndex <= aParentLayout->Count()) + { + //when aConstructedWithParentInformation- parameter is ETrue, + //no message sent to server + aParentLayout->Append(result, ETrue); + + //reorder, if needed. + if (aLayoutIndex != aParentLayout->Count() - 1) + { + aParentLayout->Reorder(*result, aLayoutIndex); + } + } + aControl.Append(result); + + if (mVisualName.isNull()) + mVisualName = UString(""); + result->SetTagL(TPtrC8((unsigned char*)mVisualName.getUtf8())); + + // Set the attributes + for (int i = 0; i < mAttributeArray.count(); ++i) + { + try + { + //ALF_PERF_START( perfdata, "AlfVisualTemplate-createVisualTree-setAttributeValue") + // set dirtines of all attribute in createvisualtree + for(int j = 0; j < mContainerArray[i]->attributeCount() ;j++ ) + { + mContainerArray[i]->getAttribute(j).setDirty(true); + } + mAttributeArray[i]->setAttributeValue(*result, mContainerArray[i], aData); + //ALF_PERF_STOP( perfdata, "AlfVisualTemplate-createVisualTree-setAttributeValue") + } + catch (...) + { + ALF_THROW(AlfAttributeException,EInvalidAttributeValue,"AlfVisualTemplate") + } + } + } + + // Pass to children + int ind = selectedChildInd( aData ); + if (ind >= 0 && ind < mChildren.size()) + { + result = mChildren[ind]->createVisualTree(aControl, aData, aParentLayout, aLayoutIndex); + } + else if (!mSelectOneChild) + { + for (int i = 0; i < mChildren.size(); ++i) + { + mChildren[i]->createVisualTree(aControl, aData, layout, i); + } + } + return result; + } + +// ----------------------------------------------------------------------------- +// reads and returns selected ind from data, if set. If not set returns -1. +// ----------------------------------------------------------------------------- +int AlfVisualTemplate::selectedChildInd( IAlfMap* aData ) + { + int ind = -1; + if (aData && mSelectOneChild) + { + IAlfVariantType* data = aData->item(mChildIndFieldName); + + //field value contains index to child array. + //if field contains no data and template has only one + // child, assume it's the child wanted. + bool valueIsEmpty = false; + if (!data) + { + valueIsEmpty = true; + } + else + { + switch ( data->type() ) + { + case IAlfVariantType::EInt: + ind = data->integer(); + break; + default: + break; + } + } + if ( valueIsEmpty && mChildren.size() == 1 ) + { + ind = 0; + } + } + return ind; + } + +// ----------------------------------------------------------------------------- +// Description : Removes a visual template from the child array without +// destroying the child template object. +// ----------------------------------------------------------------------------- +void AlfVisualTemplate::removeChildTemplate(IAlfVisualTemplate& aChild) throw() + { + std::vector::iterator it = find(mChildren.begin(), mChildren.end(), &aChild); + if(it != mChildren.end()) + { + mChildren.erase(it); + aChild.setParent(0); + } + } + +// ----------------------------------------------------------------------------- +// Description : Returns the parent visual template object +// ----------------------------------------------------------------------------- +OSN_EXPORT IAlfVisualTemplate* AlfVisualTemplate::parent() const throw() + { + return mParent; + } + +// ----------------------------------------------------------------------------- +// Description : Set the visual type +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setParent(IAlfVisualTemplate* aParent) throw() + { + mParent = aParent; + } + +// ----------------------------------------------------------------------------- +// Description : Set the visual type +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setVisualType(TAlfVisualType aType) + { + mVisualType = aType; + } + +// ----------------------------------------------------------------------------- +// Description : Get the visual type +// ----------------------------------------------------------------------------- +OSN_EXPORT int AlfVisualTemplate::visualType() const throw() + { + return mVisualType; + } +// ----------------------------------------------------------------------------- +// Description : Set the layout type +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setLayoutType(TAlfLayoutType aType) + { + mVisualType = -1 - aType; + } + +// ----------------------------------------------------------------------------- +// Description : Get the layout type +// ----------------------------------------------------------------------------- +OSN_EXPORT int AlfVisualTemplate::layoutType() const throw() + { + return -1 - mVisualType; + } + +// ----------------------------------------------------------------------------- +// Description : Adds brush to the brush array. +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::addBrush(CAlfBrush& aBrush) + { + mBrushArray.resize(mBrushArray.count()+1); + mBrushArray.insert(mBrushArray.count(),&aBrush); + } + +// ----------------------------------------------------------------------------- +// Description : Get the munber of brushes +// ----------------------------------------------------------------------------- +OSN_EXPORT int AlfVisualTemplate::numBrushes() const + { + return mBrushArray.count(); + } + +// ----------------------------------------------------------------------------- +// Description : Get a Brush +// ----------------------------------------------------------------------------- +OSN_EXPORT CAlfBrush& AlfVisualTemplate::brush(int aIndex) const + { + return *mBrushArray[aIndex]; + } + + +// ----------------------------------------------------------------------------- +// Description : puts the class in to selected child mode. +// ----------------------------------------------------------------------------- +OSN_EXPORT void AlfVisualTemplate::setSelectChildMode(bool aSelectChild, + const UString& aChildIndFieldName ) + { + mSelectOneChild = aSelectChild; + mChildIndFieldName = aChildIndFieldName; + } + + +// --------------------------------------------------------------------------- +// From class IAlfInterfaceBase. +// Getter for interfaces provided by the visual template. +// --------------------------------------------------------------------------- +// +OSN_EXPORT IAlfInterfaceBase* AlfVisualTemplate::makeInterface( const IfId& aType ) + { + UString param(aType.mImplementationId); + if (param == IAlfVisualTemplate::type().mImplementationId) + { + return static_cast(this); + } + return NULL; + } + + } //Alf