diff -r 8ca85d2f0db7 -r aabf2c525e0f uifw/AvKon/src/AknSmileyModel.cpp --- a/uifw/AvKon/src/AknSmileyModel.cpp Fri Feb 19 23:04:46 2010 +0200 +++ b/uifw/AvKon/src/AknSmileyModel.cpp Fri Mar 12 15:43:43 2010 +0200 @@ -15,7 +15,6 @@ * */ - #include #include #include @@ -23,6 +22,9 @@ #include #include +#include +#include + #include #include @@ -40,21 +42,17 @@ } TSmileyIconInfo::TSmileyIconInfo(const TSmileyIconInfo& aInfo) : -iName(aInfo.iName), -iId(aInfo.iId), iSkinItemID(aInfo.iSkinItemID), -iDefaultThumbnailID(aInfo.iDefaultThumbnailID), -iDefaultAnimationID(aInfo.iDefaultAnimationID) +iDefaultStillImageID(aInfo.iDefaultStillImageID), +iDefaultAnimationImageID(aInfo.iDefaultAnimationImageID) { } void TSmileyIconInfo::Reset() { - iName.Zero(); - iId = 0; iSkinItemID.Set(0, 0); - iDefaultThumbnailID = 0; - iDefaultAnimationID = 0; + iDefaultStillImageID = 0; + iDefaultAnimationImageID = 0; } @@ -63,76 +61,83 @@ // CSmileyIcon /////////////////////////////////////////////////////////////////////////////////////////////// -CSmileyIcon* CSmileyIcon::NewL(const TSmileyIconInfo& aInfo, MSmileyIconObserver* aObserver) +CSmileyIcon* CSmileyIcon::NewL(const TSmileyIconInfo& aInfo, MAknSmileyObserver* aObserver) { - CSmileyIcon* self = new (ELeave) CSmileyIcon(aInfo, aObserver); + CSmileyIcon* self = new (ELeave) CSmileyIcon(aObserver); CleanupStack::PushL(self); - self->ConstructL(); + self->ConstructL(aInfo); CleanupStack::Pop(); // self; return self; } -void CSmileyIcon::ConstructL() +void CSmileyIcon::ConstructL(const TSmileyIconInfo& aInfo) { - iThumbnailImage = CSmileyImage::NewL(iInfo.iSkinItemID, iInfo.iDefaultThumbnailID, FALSE, this); + iIndex = aInfo.iIndex; + + iStillImage = CSmileyImage::NewL(aInfo.iSkinItemID, aInfo.iDefaultStillImageID, EFalse, this); - if(iInfo.iSkinItemID.iMinor==0 && iInfo.iDefaultAnimationID>0) + if(aInfo.iSkinItemID.iMinor==0 && aInfo.iDefaultAnimationImageID>0) { - iAnimationImage = CSmileyImage::NewL(iInfo.iSkinItemID, iInfo.iDefaultAnimationID, TRUE, this); + TAknsItemID nullID; + nullID.Set(0, 0); + iAnimationImage = CSmileyImage::NewL(nullID, aInfo.iDefaultAnimationImageID, ETrue, this); } } -CSmileyIcon::CSmileyIcon(const TSmileyIconInfo& aInfo, MSmileyIconObserver* aObserver) : -iInfo(aInfo), iSmileyIconObserver(aObserver) +CSmileyIcon::CSmileyIcon(MAknSmileyObserver* aObserver) : iSmileyIconObserver(aObserver) { } CSmileyIcon::~CSmileyIcon() { - delete iThumbnailImage; + delete iStillImage; delete iAnimationImage; - } - -TBool CSmileyIcon::ReadyToDraw() const - { - TBool thumbnailCanDraw = iThumbnailImage->ReadyToDraw(); - TBool animationCanDraw = iAnimationImage ? iAnimationImage->ReadyToDraw() : FALSE; - return (thumbnailCanDraw || animationCanDraw); + iTextArray.Close(); } const CFbsBitmap* CSmileyIcon::Image() const { - if(ShouldShowAnimation()) + if(AnimationImageIsReadyToDraw()) { return iAnimationImage->Image(); } else { - return iThumbnailImage->Image(); + return iStillImage->Image(); } } const CFbsBitmap* CSmileyIcon::Mask() const { - if(ShouldShowAnimation()) + if(AnimationImageIsReadyToDraw()) { return iAnimationImage->Mask(); } else { - return iThumbnailImage->Mask(); + return iStillImage->Mask(); } } -void CSmileyIcon::LoadThumbnailL() +TBool CSmileyIcon::ReadyToDraw() const { - iThumbnailImage->LoadL(); + return StillImageIsReadyToDraw() || AnimationImageIsReadyToDraw(); } -TBool CSmileyIcon::ThumbnailReady() const +void CSmileyIcon::SetSize(const TSize& aSize) { - return iThumbnailImage->ReadyToDraw(); + iStillImage->SetSize(aSize); + + if(iAnimationImage) + { + iAnimationImage->SetSize(aSize); + } + } + +const TSize& CSmileyIcon::Size() const + { + return iStillImage->Size(); } void CSmileyIcon::PlayAnimationL(TInt aRepeat, TInt aDelay) @@ -151,36 +156,72 @@ } } -void CSmileyIcon::SetSize(const TSize& aSize) +void CSmileyIcon::BitmapChanged(CSmileyImage* aSmileyImage, CFbsBitmap* /*aBitmap*/) { - iThumbnailImage->SetSize(aSize); - - if(iAnimationImage) + if(aSmileyImage == iStillImage) { - iAnimationImage->SetSize(aSize); + if(iSmileyIconObserver) iSmileyIconObserver->SmileyStillImageLoaded(this); + } + else + { + if(iSmileyIconObserver) iSmileyIconObserver->SmileyAnimationChanged(this); } } -const TSize& CSmileyIcon::Size() const +TInt CSmileyIcon::Index() const + { + return iIndex; + } + +void CSmileyIcon::LoadStillImageL(TInt aDelay) { - return iThumbnailImage->Size(); + iStillImage->LoadL(0, aDelay); + } + +TBool CSmileyIcon::StillImageIsReadyToDraw() const + { + return iStillImage->ReadyToDraw(); + } + +TBool CSmileyIcon::AnimationImageIsReadyToDraw() const + { + return (iAnimationImage && iAnimationImage->ReadyToDraw()); } -void CSmileyIcon::BitmapChanged(CSmileyImage* aSmileyImage, CFbsBitmap* /*aBitmap*/) +void CSmileyIcon::AddText(const TDesC& aText) // for spliting strings = ":P :p :-P :-p"; { - if(aSmileyImage == iThumbnailImage) + TPtrC ptr(aText); + + while(ptr.Length()) { - if(iSmileyIconObserver) iSmileyIconObserver->ThumbnailLoaded(this); + TInt left = ptr.Find(_L(" ")); + TInt right = ptr.Length() - left - 1; + if(left == KErrNotFound) + { + left = ptr.Length(); + right = 0; + } + + iTextArray.Append(ptr.Left(left)); + ptr.Set(ptr.Right(right)); + } + } + +const TDesC& CSmileyIcon::Text(TInt aVariate) const + { + if(aVariate>=0 && aVariateAnimationChanged(this); + return KNullDesC; } } -TBool CSmileyIcon::ShouldShowAnimation() const +TInt CSmileyIcon::TextVariate() const { - return (iAnimationImage && iAnimationImage->ReadyToDraw()); + return iTextArray.Count(); } @@ -196,15 +237,16 @@ CSmileyTnumbnailAsynLoader::~CSmileyTnumbnailAsynLoader() { - iTaskArray.Close(); + iLoadingTaskArray.Close(); } void CSmileyTnumbnailAsynLoader::AddTaskL(CSmileyIcon* aSmileyIcon) { if(aSmileyIcon) { - iTaskArray.Append(aSmileyIcon); - if(!iIsLoading) + TBool isIdel = (TaskCount() == 0); + iLoadingTaskArray.Append(aSmileyIcon); + if(isIdel) { DoNextTaskL(); } @@ -213,45 +255,203 @@ void CSmileyTnumbnailAsynLoader::DiscardAll() { - iTaskArray.Reset(); + iLoadingTaskArray.Reset(); } TInt CSmileyTnumbnailAsynLoader::TaskCount() const { - return iTaskArray.Count(); + return iLoadingTaskArray.Count(); } void CSmileyTnumbnailAsynLoader::DoNextTaskL() { - TInt count = TaskCount(); - if(count > 0) + if(TaskCount() > 0) { - CSmileyIcon* icon = iTaskArray[0]; - iTaskArray.Remove(0); + CSmileyIcon* icon = iLoadingTaskArray[0]; + iLoadingTaskArray.Remove(0); - if(icon->ThumbnailReady()) + if(icon->StillImageIsReadyToDraw()) { DoNextTaskL(); } else { - icon->LoadThumbnailL(); - iIsLoading = TRUE; + icon->LoadStillImageL(1); // 1 is for asynchronous } } + } + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// CSmileyTextTreeNode +/////////////////////////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CSmileyTextTreeNode) : public CBase + { +public: + CSmileyTextTreeNode(TChar aChar); + ~CSmileyTextTreeNode(); + + TChar Char() const; + TChar LastChildChar() const; + TChar FirstChildChar() const; + + CSmileyTextTreeNode* AddTreeL(const TDesC& aText, TChar aCode); + TInt ChildCount() const; + CSmileyTextTreeNode* Child(TInt aIndex) const; + CSmileyTextTreeNode* Child(TChar aChar) const; + +private: + CSmileyTextTreeNode* AddChildL(TChar aChar); + +private: + TChar iChar; + + typedef CArrayPtrFlat CSmileyTextTreeNodeArrayPtrFlat; + CSmileyTextTreeNodeArrayPtrFlat* iChildArray; + + }; + + +CSmileyTextTreeNode::CSmileyTextTreeNode(TChar aChar) : iChar(aChar) + { + } + +CSmileyTextTreeNode::~CSmileyTextTreeNode() + { + if(iChildArray) + { + iChildArray->ResetAndDestroy(); + delete iChildArray; + } + } + +TChar CSmileyTextTreeNode::Char() const + { + return iChar; + } + +TChar CSmileyTextTreeNode::LastChildChar() const + { + if(iChildArray) + { + TInt index = iChildArray->Count() - 1; + return iChildArray->At(index)->Char(); + } + else + { + return 0; + } + } + +TChar CSmileyTextTreeNode::FirstChildChar() const + { + if(iChildArray) + { + return iChildArray->At(0)->Char(); + } else { - iIsLoading = FALSE; + return 0; + } + } + +CSmileyTextTreeNode* CSmileyTextTreeNode::AddTreeL(const TDesC& aText, TChar aCode) + { + TInt length = aText.Length(); + if(length > 0) + { + CSmileyTextTreeNode* node = AddChildL(aText[0]); + return node->AddTreeL(aText.Right(length-1), aCode); + } + else + { + return AddChildL(aCode); + } + } + +TInt CSmileyTextTreeNode::ChildCount() const + { + if(iChildArray) + { + return iChildArray->Count(); + } + else + { + return 0; + } + } + +CSmileyTextTreeNode* CSmileyTextTreeNode::Child(TInt aIndex) const + { + if(aIndex>=0 && aIndexAt(aIndex); + } + else + { + return NULL; } } +CSmileyTextTreeNode* CSmileyTextTreeNode::Child(TChar aChar) const + { + if(iChildArray) + { + for(TInt i=iChildArray->Count()-1; i>=0; i--) + { + CSmileyTextTreeNode* node = iChildArray->At(i); + if(node->Char() == aChar) + { + return node; + } + } + } + + return NULL; + } + +CSmileyTextTreeNode* CSmileyTextTreeNode::AddChildL(TChar aChar) + { + // new + if(!iChildArray) + { + iChildArray = new (ELeave) CSmileyTextTreeNodeArrayPtrFlat(1); + } + + // sequential search + TInt pos = 0; + for(; posCount(); pos++) + { + CSmileyTextTreeNode* node = iChildArray->At(pos); + TChar character = node->Char(); + if(aChar == character) + { + return node; + } + else if(aChar < character) + { + break; + } + } + + CSmileyTextTreeNode* node = new (ELeave) CSmileyTextTreeNode(aChar); + iChildArray->InsertL(pos, node); + return node; + } + /////////////////////////////////////////////////////////////////////////////////////////////// // CSmileyModel /////////////////////////////////////////////////////////////////////////////////////////////// -CSmileyModel::CSmileyModel(MSmileyIconObserver* aObserver) : iSmileyIconObserver(aObserver) +const TUint16 KBaseCodeOn = 0xf880; +const TUint16 KBaseCodeOff = 0x7FFF; +_LIT(KPlaceHolder, "\xf880i"); + +CSmileyModel::CSmileyModel(MAknSmileyObserver* aObserver) : iSmileyIconObserver(aObserver) { } @@ -265,18 +465,6 @@ void CSmileyModel::LoadResourceL() { if(Count() > 0) return; - - // append sct & smiley switch icon - { - TSmileyIconInfo info; - info.iSkinItemID = KAknsIIDQgnIndiSwitchSmiley2; - info.iDefaultThumbnailID = EMbmSmileyQgn_indi_switch_smiley2; - iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); - - info.iSkinItemID = KAknsIIDQgnIndiSwitchSct2; - info.iDefaultThumbnailID = EMbmSmileyQgn_indi_switch_sct2; - iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); - } // append image resourece TResourceReader reader; @@ -285,48 +473,74 @@ TInt offset = CCoeEnv::Static()->AddResourceFileL(smileyRscName); CCoeEnv::Static()->CreateResourceReaderLC(reader, R_SMILEY_ICONS_INFO); + iBaseCode = KBaseCodeOn; + TInt index = 0; + + iTextSearchTree = new (ELeave) CSmileyTextTreeNode(0); + TInt count(reader.ReadInt16()); - for(TInt id(1); id<=count; id++) + for(TInt i(0); i code) iBaseCode = code; + + info.iIndex = index++; + if(bmpId2 > 0) { - info.iDefaultThumbnailID = bmpId2; - info.iDefaultAnimationID = bmpId1; + info.iDefaultStillImageID = bmpId2; + info.iDefaultAnimationImageID = bmpId1; } else { - info.iDefaultThumbnailID = bmpId1; - info.iDefaultAnimationID = 0; + info.iDefaultStillImageID = bmpId1; + info.iDefaultAnimationImageID = 0; } TBuf<64> smileyName = reader.ReadTPtrC(); // strings - TInt pos = smileyName.Find(_L(" ")); - if(pos > 0) smileyName.SetLength(pos); - info.iName = smileyName; - - iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); + + CSmileyIcon* icon = CSmileyIcon::NewL(info, this); + icon->AddText(smileyName); + iSmileyIconArray.Append(icon); + + // build text search tree + for(TInt j=0; jTextVariate(); j++) + { + iTextSearchTree->AddTreeL(icon->Text(j), SmileyCode(i,j)); + } } CCoeEnv::Static()->DeleteResourceFile(offset); CleanupStack::PopAndDestroy(); // reader + + // sct & smiley switch icon + TSmileyIconInfo info; + info.iIndex = index++; + info.iSkinItemID = KAknsIIDQgnIndiSwitchSmiley2; + info.iDefaultStillImageID = EMbmSmileyQgn_indi_switch_smiley2; + iSmileyIconArray.Append(CSmileyIcon::NewL(info,this)); + + info.iIndex = index++; + info.iSkinItemID = KAknsIIDQgnIndiSwitchSct2; + info.iDefaultStillImageID = EMbmSmileyQgn_indi_switch_sct2; + iSmileyIconArray.Append(CSmileyIcon::NewL(info,this)); } void CSmileyModel::ReleaseResource() { + if(Count() == 0) return; + // reset array - for(TInt i(0); iLastChildChar(); + TChar firstChar = node->FirstChildChar(); + TInt matchedLength = 0; + + // deal all + TInt pos = 0; + while(pos < aText.Length()) + { + TChar character = aText[pos++]; + iConvertBuffer.Append(character); + + if(!(characterlastChar)) // is possible + { + CSmileyTextTreeNode* find = node->Child(character); + if(find) + { + matchedLength++; // character is mathed + + CSmileyTextTreeNode* child = find->Child(0); + if(child && child->ChildCount()==0) // whole combination is matched + { + converted++; + + TChar code = child->Char(); + + // replace with code + iConvertBuffer.SetLength(iConvertBuffer.Length() - matchedLength); + iConvertBuffer.Append(code); + iConvertBuffer.Append('i'); + + // load thumnail + LoadStillImageL(code); + + // restart + matchedLength = 0; + node = iTextSearchTree; + } + else + { + node = find; + } + + lastChar = node->LastChildChar(); + firstChar = node->FirstChildChar(); + continue; + } + } + + // character is not matched + if(matchedLength) + { + matchedLength = 0; + node = iTextSearchTree; + lastChar = node->LastChildChar(); + firstChar = node->FirstChildChar(); + } + } + + // replace + if(converted) + { + aText.Copy(iConvertBuffer); + } + + return converted; + } + +TBool CSmileyModel::IsSmiley(TChar aCode) const + { + return (aCode >= iBaseCode); + } + +const TDesC& CSmileyModel::Text(TChar aCode) const + { + TInt index, variate; + if(DecodeSmileyCode(aCode, index, variate)) + { + return Text(index, variate); + } + else + { + return KNullDesC; + } } void CSmileyModel::SetSize(const TSize& aSize) { - for(TInt i(0); iSize()!=aSize) + { + for(TInt i(0); iSetSize(aSize); + } + } + } + +void CSmileyModel::SetSizeByFont(const CFont* aFont) + { + TSize size(aFont->TextWidthInPixels(KPlaceHolder),aFont->HeightInPixels()); + SetSize(size); + } + +void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TPoint& aPosition) const + { + TPtrC ptr = aText; + TPoint pos = aPosition; + + aGc.UseFont(aFont); + + TBool metSmileyNotReady = EFalse; + + while(ptr.Length()) { - iSmileyIconArray[i]->SetSize(aSize); + TInt i = 0; + for(; i 0) // have text + { + TPtrC txt = ptr.Left(i); + aGc.DrawText(txt, pos); + pos += TPoint(aFont->TextWidthInPixels(txt),0); + + ptr.Set(ptr.Right(ptr.Length()-i)); + i = 0; + } + + if(ptr.Length()) // breaked by smiley code + { + CAknSmileyIcon* icon = Smiley(ptr[i]); + if(icon) + { + TSize size = icon->Size(); + TPoint tl = pos; + tl.iY = tl.iY - (size.iHeight + aFont->HeightInPixels()) / 2; + if(!metSmileyNotReady && icon->ReadyToDraw()) + { + aGc.BitBltMasked(tl, icon->Image(), TRect(size), icon->Mask(), EFalse); + } + else + { + metSmileyNotReady = ETrue; + } + pos += TPoint(aFont->TextWidthInPixels(ptr.Left(2)),0); + } + + ptr.Set(ptr.Right(ptr.Length()-2)); + } } } -CSmileyIcon* CSmileyModel::operator[](TInt aIndex) const +void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const TAknLayoutText& aLayout, TBool aUseLogicalToVisualConversion) const + { + // adapter variables + const CFont* font = aLayout.Font(); + TRect textRect = aLayout.TextRect(); + TInt offset = aLayout.BaselineOffset(); + CGraphicsContext::TTextAlign align = aLayout.Align(); + + // belows are all from + // void TAknLayoutText::DrawText(CGraphicsContext& aGc,const TDesC& aText,TBool aUseLogicalToVisualConversion, const TRgb &aColor) const + + __ASSERT_DEBUG(font, Panic(EAknPanicLayoutTextNotCalled)); + + //aGc.UseFont( font ); + //aGc.SetPenColor( aColor ); + if ( aText.Length() ) + { + HBufC* visualBuf = NULL; + TPtrC text( aText ); + + if ( aUseLogicalToVisualConversion ) + { + visualBuf = HBufC::New( aText.Length() + KAknBidiExtraSpacePerLine ); + + // In OOM, logical to visual conversion is not performed... + + if ( visualBuf ) + { + *visualBuf = aText; // copy + TPtr ptr = visualBuf->Des(); + + TInt maxWidth = textRect.Size().iWidth; + + // Logical to visual conversion. + AknBidiTextUtils::ConvertToVisualAndClip( + aText, + ptr, + *font, + maxWidth, + maxWidth ); + + // for smiley begin + const TInt length = ptr.Length(); + if(length>1 && IsSmiley(ptr[length-2])) + { + if(ptr[length-1] != 'i') + { + // smiley is clipped for visual, del this smiley + ptr.Delete(length-2, 1); + } + } + // for smiley end + + text.Set( ptr ); + } + } + + // Calculate x-offset based on the used alignment + TInt margin = 0; + if ( align != CGraphicsContext::ELeft ) + { + // Measure the full width of the text (ie. what DrawText needs) + TInt textWidth = AknBidiTextUtils::MeasureTextBoundsWidth( *font, text,CFont::TMeasureTextInput::EFVisualOrder ); + + const TInt extraWidth = textRect.Width() - textWidth; + if ( align == CGraphicsContext::ECenter ) + { + margin = extraWidth / 2; + } + else // right aligned + { + margin = extraWidth; + } + } + + // Need to make the drawing rectangle bigger to account for underlines + TRect drawRect(textRect); + TInt height = drawRect.Height(); + // The underline position is not available from the GC. The following code imitates what Symbian CFbsBitGC implements. + // (height-offset) is the part below the baseline. Check if it sufficient + TInt extraHeightForUnderlining = 1 + Max(1, height/10)-(height-offset); + if ( extraHeightForUnderlining > 0 ) + drawRect.iBr.iY += extraHeightForUnderlining; + + // for smiley + //aGc.DrawText( text, drawRect, offset, CGraphicsContext::ELeft, margin ); + DrawText(aGc, text, font, drawRect, offset, CGraphicsContext::ELeft, margin); + + delete visualBuf; + } + + //aGc.DiscardFont(); // Release the font cache + } + +void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TRect& aBox, TInt aBaselineOffset, + CGraphicsContext::TTextAlign aAlignment, TInt aLeftMargin) const { - if(aIndex>=0 && aIndexTextWidthInPixels(aText); + + TPoint offset; + offset.iY = aBaselineOffset; + + switch(aAlignment) + { + case CGraphicsContext::ELeft: + offset.iX = aLeftMargin; + break; + + case CGraphicsContext::ERight: + offset.iX = boxWidth - textWidth - aLeftMargin; + break; + + case CGraphicsContext::ECenter: + offset.iX = (boxWidth - textWidth) / 2; + break; + + default: + break; + } + + DrawText(aGc, aText, aFont, aBox, offset); + } + +void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TRect& aBox, const TPoint& aOffset) const + { + TPtrC ptr = aText; + TPoint offset = aOffset; + + aGc.UseFont(aFont); + + TInt fontH = aFont->HeightInPixels(); + + TBool metSmileyNotReady = EFalse; + + while(ptr.Length()) + { + TInt i = 0; + for(; i 0) // have text + { + TPtrC txt = ptr.Left(i); + aGc.DrawText(txt, aBox, offset.iY, CGraphicsContext::ELeft, offset.iX); + offset.iX += aFont->TextWidthInPixels(txt); + + ptr.Set(ptr.Right(ptr.Length()-i)); + i = 0; + } + + if(ptr.Length()) // breaked by smiley code + { + CAknSmileyIcon* icon = Smiley(ptr[i]); + if(icon) + { + TSize size = icon->Size(); + TPoint tl = aBox.iTl + offset; + tl.iY = tl.iY - (size.iHeight + fontH) / 2; + TRect imgWindow(tl, size); + imgWindow.Intersection(aBox); + if(!imgWindow.IsEmpty()) + { + TRect innerRect = TRect(imgWindow.iTl-tl,imgWindow.Size()); + if(!metSmileyNotReady && icon->ReadyToDraw()) + { + aGc.BitBltMasked(imgWindow.iTl, icon->Image(), innerRect, icon->Mask(), EFalse); + } + else + { + metSmileyNotReady = ETrue; + } + } + + offset += TPoint(aFont->TextWidthInPixels(ptr.Left(2)),0); + } + + ptr.Set(ptr.Right(ptr.Length()-2)); + } + } + } + +CAknSmileyIcon* CSmileyModel::Smiley(TChar aCode) const + { + TInt index, variate; + if(DecodeSmileyCode(aCode, index, variate)) + { + return (*this)[index]; + } + else + { + return NULL; + } + } + +CAknSmileyIcon* CSmileyModel::operator[](TInt aIndex) const + { + if(aIndex>=0 && aIndex(aSmileyIcon); + return EncodeSmileyCode(icon->Index(), 0); + } + else + { + return 0; + } + } + +void CSmileyModel::LoadStillImagesL(const TDesC& aText) + { + for(TInt i(0); i(Smiley(aChar)); + iSmileyLoader.AddTaskL(icon); + } + +const TDesC& CSmileyModel::Text(TInt aIndex, TInt aVariate) const + { + CSmileyIcon* icon = static_cast((*this)[aIndex]); + if(icon) + { + return icon->Text(aVariate); + } + else + { + return KNullDesC; + } + } + +TInt CSmileyModel::ArrayCount() const + { return iSmileyIconArray.Count(); } -void CSmileyModel::ThumbnailLoaded(CSmileyIcon* aSmileyIcon) +TChar CSmileyModel::EncodeSmileyCode(TInt aIndex, TInt aVariate) const { - TRAP_IGNORE(iSmileyThumbnailLoader.DoNextTaskL()); - - if(iSmileyIconObserver) iSmileyIconObserver->ThumbnailLoaded(aSmileyIcon); + if(aVariate) + { + return (iBaseCode + aIndex + (aVariate<<8)); + } + else + { + return (iBaseCode + aIndex); + } } -void CSmileyModel::AnimationChanged(CSmileyIcon* aSmileyIcon) +#define KMaskL 0x00FF + +TBool CSmileyModel::DecodeSmileyCode(TChar aCode, TInt& aIndex, TInt& aVariate) const { - if(iSmileyIconObserver) iSmileyIconObserver->AnimationChanged(aSmileyIcon); + if(aCode >= iBaseCode) + { + aIndex = (aCode&KMaskL) - (iBaseCode&KMaskL); + aVariate = (aCode>>8) - (iBaseCode>>8); + return ETrue; + } + else + { + return EFalse; + } + } + +void CSmileyModel::SmileyStillImageLoaded(CAknSmileyIcon* aSmileyIcon) + { + TRAP_IGNORE(iSmileyLoader.DoNextTaskL()); + + if(iSmileyIconObserver) iSmileyIconObserver->SmileyStillImageLoaded(aSmileyIcon); + } + +void CSmileyModel::SmileyAnimationChanged(CAknSmileyIcon* aSmileyIcon) + { + if(iSmileyIconObserver) iSmileyIconObserver->SmileyAnimationChanged(aSmileyIcon); }