38 { |
40 { |
39 Reset(); |
41 Reset(); |
40 } |
42 } |
41 |
43 |
42 TSmileyIconInfo::TSmileyIconInfo(const TSmileyIconInfo& aInfo) : |
44 TSmileyIconInfo::TSmileyIconInfo(const TSmileyIconInfo& aInfo) : |
43 iName(aInfo.iName), |
|
44 iId(aInfo.iId), |
|
45 iSkinItemID(aInfo.iSkinItemID), |
45 iSkinItemID(aInfo.iSkinItemID), |
46 iDefaultThumbnailID(aInfo.iDefaultThumbnailID), |
46 iDefaultStillImageID(aInfo.iDefaultStillImageID), |
47 iDefaultAnimationID(aInfo.iDefaultAnimationID) |
47 iDefaultAnimationImageID(aInfo.iDefaultAnimationImageID) |
48 { |
48 { |
49 } |
49 } |
50 |
50 |
51 void TSmileyIconInfo::Reset() |
51 void TSmileyIconInfo::Reset() |
52 { |
52 { |
53 iName.Zero(); |
|
54 iId = 0; |
|
55 iSkinItemID.Set(0, 0); |
53 iSkinItemID.Set(0, 0); |
56 iDefaultThumbnailID = 0; |
54 iDefaultStillImageID = 0; |
57 iDefaultAnimationID = 0; |
55 iDefaultAnimationImageID = 0; |
58 } |
56 } |
59 |
57 |
60 |
58 |
61 |
59 |
62 /////////////////////////////////////////////////////////////////////////////////////////////// |
60 /////////////////////////////////////////////////////////////////////////////////////////////// |
63 // CSmileyIcon |
61 // CSmileyIcon |
64 /////////////////////////////////////////////////////////////////////////////////////////////// |
62 /////////////////////////////////////////////////////////////////////////////////////////////// |
65 |
63 |
66 CSmileyIcon* CSmileyIcon::NewL(const TSmileyIconInfo& aInfo, MSmileyIconObserver* aObserver) |
64 CSmileyIcon* CSmileyIcon::NewL(const TSmileyIconInfo& aInfo, MAknSmileyObserver* aObserver) |
67 { |
65 { |
68 CSmileyIcon* self = new (ELeave) CSmileyIcon(aInfo, aObserver); |
66 CSmileyIcon* self = new (ELeave) CSmileyIcon(aObserver); |
69 CleanupStack::PushL(self); |
67 CleanupStack::PushL(self); |
70 self->ConstructL(); |
68 self->ConstructL(aInfo); |
71 CleanupStack::Pop(); // self; |
69 CleanupStack::Pop(); // self; |
72 return self; |
70 return self; |
73 } |
71 } |
74 |
72 |
75 void CSmileyIcon::ConstructL() |
73 void CSmileyIcon::ConstructL(const TSmileyIconInfo& aInfo) |
76 { |
74 { |
77 iThumbnailImage = CSmileyImage::NewL(iInfo.iSkinItemID, iInfo.iDefaultThumbnailID, FALSE, this); |
75 iIndex = aInfo.iIndex; |
78 |
76 |
79 if(iInfo.iSkinItemID.iMinor==0 && iInfo.iDefaultAnimationID>0) |
77 iStillImage = CSmileyImage::NewL(aInfo.iSkinItemID, aInfo.iDefaultStillImageID, EFalse, this); |
80 { |
78 |
81 iAnimationImage = CSmileyImage::NewL(iInfo.iSkinItemID, iInfo.iDefaultAnimationID, TRUE, this); |
79 if(aInfo.iSkinItemID.iMinor==0 && aInfo.iDefaultAnimationImageID>0) |
82 } |
80 { |
83 } |
81 TAknsItemID nullID; |
84 |
82 nullID.Set(0, 0); |
85 CSmileyIcon::CSmileyIcon(const TSmileyIconInfo& aInfo, MSmileyIconObserver* aObserver) : |
83 iAnimationImage = CSmileyImage::NewL(nullID, aInfo.iDefaultAnimationImageID, ETrue, this); |
86 iInfo(aInfo), iSmileyIconObserver(aObserver) |
84 } |
|
85 } |
|
86 |
|
87 CSmileyIcon::CSmileyIcon(MAknSmileyObserver* aObserver) : iSmileyIconObserver(aObserver) |
87 { |
88 { |
88 } |
89 } |
89 |
90 |
90 CSmileyIcon::~CSmileyIcon() |
91 CSmileyIcon::~CSmileyIcon() |
91 { |
92 { |
92 delete iThumbnailImage; |
93 delete iStillImage; |
93 delete iAnimationImage; |
94 delete iAnimationImage; |
|
95 |
|
96 iTextArray.Close(); |
|
97 iCodeArray.Close(); |
|
98 } |
|
99 |
|
100 const CFbsBitmap* CSmileyIcon::Image() const |
|
101 { |
|
102 if(AnimationImageIsReadyToDraw()) |
|
103 { |
|
104 return iAnimationImage->Image(); |
|
105 } |
|
106 else |
|
107 { |
|
108 return iStillImage->Image(); |
|
109 } |
|
110 } |
|
111 |
|
112 const CFbsBitmap* CSmileyIcon::Mask() const |
|
113 { |
|
114 if(AnimationImageIsReadyToDraw()) |
|
115 { |
|
116 return iAnimationImage->Mask(); |
|
117 } |
|
118 else |
|
119 { |
|
120 return iStillImage->Mask(); |
|
121 } |
94 } |
122 } |
95 |
123 |
96 TBool CSmileyIcon::ReadyToDraw() const |
124 TBool CSmileyIcon::ReadyToDraw() const |
97 { |
125 { |
98 TBool thumbnailCanDraw = iThumbnailImage->ReadyToDraw(); |
126 return StillImageIsReadyToDraw() || AnimationImageIsReadyToDraw(); |
99 TBool animationCanDraw = iAnimationImage ? iAnimationImage->ReadyToDraw() : FALSE; |
127 } |
100 |
128 |
101 return (thumbnailCanDraw || animationCanDraw); |
129 void CSmileyIcon::SetSize(const TSize& aSize) |
102 } |
130 { |
103 |
131 iStillImage->SetSize(aSize); |
104 const CFbsBitmap* CSmileyIcon::Image() const |
132 |
105 { |
133 if(iAnimationImage) |
106 if(ShouldShowAnimation()) |
134 { |
107 { |
135 iAnimationImage->SetSize(aSize); |
108 return iAnimationImage->Image(); |
136 } |
109 } |
137 } |
110 else |
138 |
111 { |
139 const TSize& CSmileyIcon::Size() const |
112 return iThumbnailImage->Image(); |
140 { |
113 } |
141 return iStillImage->Size(); |
114 } |
|
115 |
|
116 const CFbsBitmap* CSmileyIcon::Mask() const |
|
117 { |
|
118 if(ShouldShowAnimation()) |
|
119 { |
|
120 return iAnimationImage->Mask(); |
|
121 } |
|
122 else |
|
123 { |
|
124 return iThumbnailImage->Mask(); |
|
125 } |
|
126 } |
|
127 |
|
128 void CSmileyIcon::LoadThumbnailL() |
|
129 { |
|
130 iThumbnailImage->LoadL(); |
|
131 } |
|
132 |
|
133 TBool CSmileyIcon::ThumbnailReady() const |
|
134 { |
|
135 return iThumbnailImage->ReadyToDraw(); |
|
136 } |
142 } |
137 |
143 |
138 void CSmileyIcon::PlayAnimationL(TInt aRepeat, TInt aDelay) |
144 void CSmileyIcon::PlayAnimationL(TInt aRepeat, TInt aDelay) |
139 { |
145 { |
140 if(iAnimationImage) |
146 if(iAnimationImage) |
194 |
248 |
195 } |
249 } |
196 |
250 |
197 CSmileyTnumbnailAsynLoader::~CSmileyTnumbnailAsynLoader() |
251 CSmileyTnumbnailAsynLoader::~CSmileyTnumbnailAsynLoader() |
198 { |
252 { |
199 iTaskArray.Close(); |
253 iLoadingTaskArray.Close(); |
200 } |
254 } |
201 |
255 |
202 void CSmileyTnumbnailAsynLoader::AddTaskL(CSmileyIcon* aSmileyIcon) |
256 void CSmileyTnumbnailAsynLoader::AddTaskL(CSmileyIcon* aSmileyIcon) |
203 { |
257 { |
204 if(aSmileyIcon) |
258 if(aSmileyIcon) |
205 { |
259 { |
206 iTaskArray.Append(aSmileyIcon); |
260 TBool isIdel = (TaskCount() == 0); |
207 if(!iIsLoading) |
261 iLoadingTaskArray.Append(aSmileyIcon); |
|
262 if(isIdel) |
208 { |
263 { |
209 DoNextTaskL(); |
264 DoNextTaskL(); |
210 } |
265 } |
211 } |
266 } |
212 } |
267 } |
213 |
268 |
214 void CSmileyTnumbnailAsynLoader::DiscardAll() |
269 void CSmileyTnumbnailAsynLoader::DiscardAll() |
215 { |
270 { |
216 iTaskArray.Reset(); |
271 iLoadingTaskArray.Reset(); |
217 } |
272 } |
218 |
273 |
219 TInt CSmileyTnumbnailAsynLoader::TaskCount() const |
274 TInt CSmileyTnumbnailAsynLoader::TaskCount() const |
220 { |
275 { |
221 return iTaskArray.Count(); |
276 return iLoadingTaskArray.Count(); |
222 } |
277 } |
223 |
278 |
224 void CSmileyTnumbnailAsynLoader::DoNextTaskL() |
279 void CSmileyTnumbnailAsynLoader::DoNextTaskL() |
225 { |
280 { |
226 TInt count = TaskCount(); |
281 if(TaskCount() > 0) |
227 if(count > 0) |
282 { |
228 { |
283 CSmileyIcon* icon = iLoadingTaskArray[0]; |
229 CSmileyIcon* icon = iTaskArray[0]; |
284 iLoadingTaskArray.Remove(0); |
230 iTaskArray.Remove(0); |
285 |
231 |
286 if(icon->StillImageIsReadyToDraw()) |
232 if(icon->ThumbnailReady()) |
|
233 { |
287 { |
234 DoNextTaskL(); |
288 DoNextTaskL(); |
235 } |
289 } |
236 else |
290 else |
237 { |
291 { |
238 icon->LoadThumbnailL(); |
292 icon->LoadStillImageL(); |
239 iIsLoading = TRUE; |
293 } |
240 } |
294 } |
241 } |
295 } |
242 else |
296 |
243 { |
297 |
244 iIsLoading = FALSE; |
298 |
245 } |
299 /////////////////////////////////////////////////////////////////////////////////////////////// |
|
300 // CSmileyTextTreeNode |
|
301 /////////////////////////////////////////////////////////////////////////////////////////////// |
|
302 |
|
303 NONSHARABLE_CLASS(CSmileyTextTreeNode) : public CBase |
|
304 { |
|
305 public: |
|
306 CSmileyTextTreeNode(TChar aChar); |
|
307 ~CSmileyTextTreeNode(); |
|
308 |
|
309 TChar Char() const; |
|
310 |
|
311 CSmileyTextTreeNode* AddTreeL(const TDesC& aText, TChar aCode); |
|
312 TInt ChildCount() const; |
|
313 CSmileyTextTreeNode* Child(TInt aIndex) const; |
|
314 CSmileyTextTreeNode* Child(TChar aChar) const; |
|
315 |
|
316 private: |
|
317 CSmileyTextTreeNode* AddChildAscendingL(TChar aChar); |
|
318 |
|
319 private: |
|
320 TChar iChar; |
|
321 |
|
322 typedef CArrayPtrFlat<CSmileyTextTreeNode> CSmileyTextTreeNodeArrayPtrFlat; |
|
323 CSmileyTextTreeNodeArrayPtrFlat* iChildArray; |
|
324 |
|
325 }; |
|
326 |
|
327 |
|
328 CSmileyTextTreeNode::CSmileyTextTreeNode(TChar aChar) : iChar(aChar) |
|
329 { |
|
330 } |
|
331 |
|
332 CSmileyTextTreeNode::~CSmileyTextTreeNode() |
|
333 { |
|
334 if(iChildArray) |
|
335 { |
|
336 iChildArray->ResetAndDestroy(); |
|
337 delete iChildArray; |
|
338 } |
|
339 } |
|
340 |
|
341 TChar CSmileyTextTreeNode::Char() const |
|
342 { |
|
343 return iChar; |
|
344 } |
|
345 |
|
346 |
|
347 |
|
348 CSmileyTextTreeNode* CSmileyTextTreeNode::AddTreeL(const TDesC& aText, TChar aCode) |
|
349 { |
|
350 TInt length = aText.Length(); |
|
351 if(length > 0) |
|
352 { |
|
353 CSmileyTextTreeNode* node = AddChildAscendingL(aText[0]); |
|
354 return node->AddTreeL(aText.Right(length-1), aCode); |
|
355 } |
|
356 else |
|
357 { |
|
358 return AddChildAscendingL(aCode); |
|
359 } |
|
360 } |
|
361 |
|
362 TInt CSmileyTextTreeNode::ChildCount() const |
|
363 { |
|
364 if(iChildArray) |
|
365 { |
|
366 return iChildArray->Count(); |
|
367 } |
|
368 else |
|
369 { |
|
370 return 0; |
|
371 } |
|
372 } |
|
373 |
|
374 CSmileyTextTreeNode* CSmileyTextTreeNode::Child(TInt aIndex) const |
|
375 { |
|
376 if(aIndex>=0 && aIndex<ChildCount()) |
|
377 { |
|
378 return iChildArray->At(aIndex); |
|
379 } |
|
380 else |
|
381 { |
|
382 return NULL; |
|
383 } |
|
384 } |
|
385 |
|
386 CSmileyTextTreeNode* CSmileyTextTreeNode::Child(TChar aChar) const |
|
387 { |
|
388 if(iChildArray) |
|
389 { |
|
390 const TInt KFirstPos = 0; |
|
391 const TInt KEndPos = iChildArray->Count() - 1; |
|
392 if(aChar<iChildArray->At(KFirstPos)->Char() || aChar>iChildArray->At(KEndPos)->Char()) |
|
393 { |
|
394 return NULL; |
|
395 } |
|
396 for(TInt i=KEndPos; i>=KFirstPos; i--) |
|
397 { |
|
398 CSmileyTextTreeNode* node = iChildArray->At(i); |
|
399 if(node->Char() == aChar) |
|
400 { |
|
401 return node; |
|
402 } |
|
403 } |
|
404 } |
|
405 |
|
406 return NULL; |
|
407 } |
|
408 |
|
409 CSmileyTextTreeNode* CSmileyTextTreeNode::AddChildAscendingL(TChar aChar) |
|
410 { |
|
411 // new |
|
412 if(!iChildArray) |
|
413 { |
|
414 iChildArray = new (ELeave) CSmileyTextTreeNodeArrayPtrFlat(1); |
|
415 } |
|
416 |
|
417 // sequential search |
|
418 TInt pos = 0; |
|
419 for(; pos<iChildArray->Count(); pos++) |
|
420 { |
|
421 CSmileyTextTreeNode* node = iChildArray->At(pos); |
|
422 TChar character = node->Char(); |
|
423 if(aChar == character) |
|
424 { |
|
425 return node; |
|
426 } |
|
427 else if(aChar < character) |
|
428 { |
|
429 break; |
|
430 } |
|
431 } |
|
432 |
|
433 CSmileyTextTreeNode* node = new (ELeave) CSmileyTextTreeNode(aChar); |
|
434 iChildArray->InsertL(pos, node); |
|
435 return node; |
246 } |
436 } |
247 |
437 |
248 |
438 |
249 |
439 |
250 /////////////////////////////////////////////////////////////////////////////////////////////// |
440 /////////////////////////////////////////////////////////////////////////////////////////////// |
251 // CSmileyModel |
441 // CSmileyModel |
252 /////////////////////////////////////////////////////////////////////////////////////////////// |
442 /////////////////////////////////////////////////////////////////////////////////////////////// |
253 |
443 |
254 CSmileyModel::CSmileyModel(MSmileyIconObserver* aObserver) : iSmileyIconObserver(aObserver) |
444 const TUint16 KBaseCode = 0xf880; |
|
445 //const TUint16 KBaseCodeOff = 0x7FFF; |
|
446 _LIT(KPlaceHolder, "\xf880i"); |
|
447 |
|
448 CSmileyModel::CSmileyModel(MAknSmileyObserver* aObserver) : iSmileyIconObserver(aObserver) |
255 { |
449 { |
256 } |
450 } |
257 |
451 |
258 CSmileyModel::~CSmileyModel() |
452 CSmileyModel::~CSmileyModel() |
259 { |
453 { |
260 ReleaseResource(); |
454 ReleaseResource(); |
261 |
455 |
262 iSmileyIconArray.Close(); |
456 iSmileyIconArray.Close(); |
|
457 iSmileyCodeIndexArray.Close(); |
263 } |
458 } |
264 |
459 |
265 void CSmileyModel::LoadResourceL() |
460 void CSmileyModel::LoadResourceL() |
266 { |
461 { |
267 if(Count() > 0) return; |
462 if(Count() > 0) return; |
268 |
|
269 // append sct & smiley switch icon |
|
270 { |
|
271 TSmileyIconInfo info; |
|
272 info.iSkinItemID = KAknsIIDQgnIndiSwitchSmiley2; |
|
273 info.iDefaultThumbnailID = EMbmSmileyQgn_indi_switch_smiley2; |
|
274 iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); |
|
275 |
|
276 info.iSkinItemID = KAknsIIDQgnIndiSwitchSct2; |
|
277 info.iDefaultThumbnailID = EMbmSmileyQgn_indi_switch_sct2; |
|
278 iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); |
|
279 } |
|
280 |
463 |
281 // append image resourece |
464 // append image resourece |
282 TResourceReader reader; |
465 TResourceReader reader; |
283 TFileName smileyRscName; |
466 TFileName smileyRscName; |
284 SmileyUtils::GetCustomizableResPath(smileyRscName, KSmileyRsc); |
467 SmileyUtils::GetCustomizableResPath(smileyRscName, KSmileyRsc); |
285 TInt offset = CCoeEnv::Static()->AddResourceFileL(smileyRscName); |
468 TInt offset = CCoeEnv::Static()->AddResourceFileL(smileyRscName); |
286 CCoeEnv::Static()->CreateResourceReaderLC(reader, R_SMILEY_ICONS_INFO); |
469 CCoeEnv::Static()->CreateResourceReaderLC(reader, R_SMILEY_ICONS_INFO); |
287 |
470 |
|
471 TUint16 codeRef = KBaseCode; |
|
472 TInt index = 0; |
|
473 |
|
474 iTextSearchTree = new (ELeave) CSmileyTextTreeNode(0); |
|
475 |
288 TInt count(reader.ReadInt16()); |
476 TInt count(reader.ReadInt16()); |
289 for(TInt id(1); id<=count; id++) |
477 for(TInt i(0); i<count; i++) |
290 { |
478 { |
291 TSmileyIconInfo info; |
479 TSmileyIconInfo info; |
292 |
480 |
293 info.iId = id; // id |
|
294 |
|
295 TBool isAnimation = (reader.ReadInt16() == 1); |
481 TBool isAnimation = (reader.ReadInt16() == 1); |
296 TInt16 code = reader.ReadInt16(); |
482 TInt16 code = reader.ReadInt16(); |
297 TInt bmpId1 = reader.ReadInt32(); |
483 TInt bmpId1 = reader.ReadInt32(); |
298 TInt maskId1 = reader.ReadInt32(); |
484 TInt maskId1 = reader.ReadInt32(); |
299 TInt bmpId2 = reader.ReadInt32(); |
485 TInt bmpId2 = reader.ReadInt32(); |
300 TInt maskId2 = reader.ReadInt32(); |
486 TInt maskId2 = reader.ReadInt32(); |
301 |
487 |
|
488 |
|
489 info.iIndex = index++; |
|
490 |
302 if(bmpId2 > 0) |
491 if(bmpId2 > 0) |
303 { |
492 { |
304 info.iDefaultThumbnailID = bmpId2; |
493 info.iDefaultStillImageID = bmpId2; |
305 info.iDefaultAnimationID = bmpId1; |
494 info.iDefaultAnimationImageID = bmpId1; |
306 } |
495 } |
307 else |
496 else |
308 { |
497 { |
309 info.iDefaultThumbnailID = bmpId1; |
498 info.iDefaultStillImageID = bmpId1; |
310 info.iDefaultAnimationID = 0; |
499 info.iDefaultAnimationImageID = 0; |
311 } |
500 } |
312 |
501 |
313 TBuf<64> smileyName = reader.ReadTPtrC(); // strings |
502 TBuf<64> smileyName = reader.ReadTPtrC(); // strings |
314 TInt pos = smileyName.Find(_L(" ")); |
503 |
315 if(pos > 0) smileyName.SetLength(pos); |
504 CSmileyIcon* icon = CSmileyIcon::NewL(info, this); |
316 info.iName = smileyName; |
505 icon->AddVariant(smileyName, codeRef); |
317 |
506 iSmileyIconArray.Append(icon); |
318 iSmileyIconArray.Append(CSmileyIcon::NewL(info, this)); |
507 |
|
508 // build text search tree |
|
509 for(TInt j=0; j<icon->VariantCount(); j++) |
|
510 { |
|
511 iTextSearchTree->AddTreeL(icon->Text(j), codeRef++); |
|
512 iSmileyCodeIndexArray.Append(TSmileyCodeIndex(icon,j)); |
|
513 } |
319 } |
514 } |
320 |
515 |
321 CCoeEnv::Static()->DeleteResourceFile(offset); |
516 CCoeEnv::Static()->DeleteResourceFile(offset); |
322 CleanupStack::PopAndDestroy(); // reader |
517 CleanupStack::PopAndDestroy(); // reader |
|
518 |
|
519 // sct & smiley switch icon |
|
520 TSmileyIconInfo info; |
|
521 info.iIndex = index++; |
|
522 info.iSkinItemID = KAknsIIDQgnIndiSwitchSmiley2; |
|
523 info.iDefaultStillImageID = EMbmSmileyQgn_indi_switch_smiley2; |
|
524 CSmileyIcon* switchSmileyIcon = CSmileyIcon::NewL(info, this); |
|
525 iSmileyIconArray.Append(switchSmileyIcon); |
|
526 iSmileyCodeIndexArray.Append(TSmileyCodeIndex(switchSmileyIcon)); |
|
527 |
|
528 info.iIndex = index++; |
|
529 info.iSkinItemID = KAknsIIDQgnIndiSwitchSct2; |
|
530 info.iDefaultStillImageID = EMbmSmileyQgn_indi_switch_sct2; |
|
531 CSmileyIcon* switchSctIcon = CSmileyIcon::NewL(info,this); |
|
532 iSmileyIconArray.Append(switchSctIcon); |
|
533 iSmileyCodeIndexArray.Append(TSmileyCodeIndex(switchSctIcon)); |
323 |
534 |
324 } |
535 } |
325 |
536 |
326 void CSmileyModel::ReleaseResource() |
537 void CSmileyModel::ReleaseResource() |
327 { |
538 { |
|
539 if(Count() == 0) return; |
|
540 |
328 // reset array |
541 // reset array |
329 for(TInt i(0); i<Count(); i++) |
542 for(TInt i(0); i<ArrayCount(); i++) |
330 { |
543 { |
331 delete iSmileyIconArray[i]; |
544 delete iSmileyIconArray[i]; |
332 iSmileyIconArray[i] = NULL; |
545 iSmileyIconArray[i] = NULL; |
333 } |
546 } |
334 iSmileyIconArray.Reset(); |
547 iSmileyIconArray.Reset(); |
335 |
548 |
|
549 iSmileyCodeIndexArray.Reset(); |
336 // reset task loader |
550 // reset task loader |
337 iSmileyThumbnailLoader.DiscardAll(); |
551 iSmileyLoader.DiscardAll(); |
338 } |
552 |
339 |
553 delete iTextSearchTree; |
340 void CSmileyModel::LoadThumbnailAsyn(TInt aIndex) |
554 iTextSearchTree = NULL; |
341 { |
555 |
342 TRAP_IGNORE(iSmileyThumbnailLoader.AddTaskL((*this)[aIndex])); |
556 } |
|
557 |
|
558 TInt CSmileyModel::ConvertCodesToTextL(TDes& aText) |
|
559 { |
|
560 TInt converted = 0; |
|
561 iConvertBuffer.Zero(); |
|
562 |
|
563 // deal all |
|
564 TInt pos = 0; |
|
565 while(pos < aText.Length()) |
|
566 { |
|
567 TChar character = aText[pos++]; |
|
568 if(IsSmiley(character)) |
|
569 { |
|
570 converted++; |
|
571 pos++; // jump the 'i' |
|
572 iConvertBuffer.Append(Text(character)); |
|
573 } |
|
574 else |
|
575 { |
|
576 iConvertBuffer.Append(character); |
|
577 } |
|
578 } |
|
579 |
|
580 // replace |
|
581 if(converted) |
|
582 { |
|
583 aText.Copy(iConvertBuffer); |
|
584 } |
|
585 |
|
586 return converted; |
|
587 } |
|
588 |
|
589 TInt CSmileyModel::ConvertTextToCodesL(TDes& aText) |
|
590 { |
|
591 _AKNTRACE_FUNC_ENTER; |
|
592 TInt converted = 0; |
|
593 iConvertBuffer.Zero(); |
|
594 |
|
595 CSmileyTextTreeNode* node = iTextSearchTree; |
|
596 TInt matchedLength = 0; |
|
597 |
|
598 // deal all |
|
599 TInt pos = 0; |
|
600 while(pos < aText.Length()) |
|
601 { |
|
602 TChar character = aText[pos++]; |
|
603 iConvertBuffer.Append(character); |
|
604 |
|
605 CSmileyTextTreeNode* find = node->Child(character); |
|
606 if(find) |
|
607 { |
|
608 matchedLength++; // character is mathed |
|
609 |
|
610 CSmileyTextTreeNode* child = find->Child(0); |
|
611 TBool notFinished = (child && child->ChildCount()); |
|
612 if(notFinished) // not ended |
|
613 { |
|
614 node = find; // match next |
|
615 continue; |
|
616 } |
|
617 else if(child) // whole combination is matched and ended |
|
618 { |
|
619 TChar code = child->Char(); |
|
620 |
|
621 // replace with code |
|
622 iConvertBuffer.SetLength(iConvertBuffer.Length() - matchedLength); |
|
623 iConvertBuffer.Append(code); |
|
624 iConvertBuffer.Append('i'); |
|
625 converted++; // returned value added |
|
626 // load thumnail |
|
627 LoadStillImageL(code); |
|
628 |
|
629 // restart |
|
630 matchedLength = 0; |
|
631 node = iTextSearchTree; |
|
632 continue; |
|
633 } |
|
634 else // in this case matchedLength already increased by 1 |
|
635 { |
|
636 matchedLength--; |
|
637 } |
|
638 } |
|
639 |
|
640 // matching failed |
|
641 if(matchedLength) |
|
642 { |
|
643 // back to the 2nd char |
|
644 TInt rollBack = matchedLength; |
|
645 iConvertBuffer.SetLength(iConvertBuffer.Length() - rollBack); |
|
646 pos -= rollBack; |
|
647 |
|
648 // reset matching context |
|
649 matchedLength = 0; |
|
650 node = iTextSearchTree; |
|
651 } |
|
652 } |
|
653 |
|
654 // replace |
|
655 if(converted) |
|
656 { |
|
657 aText.Copy(iConvertBuffer); |
|
658 } |
|
659 |
|
660 _AKNTRACE_FUNC_EXIT; |
|
661 return converted; |
|
662 } |
|
663 |
|
664 TBool CSmileyModel::IsSmiley(TChar aCode) const |
|
665 { |
|
666 TInt smileyCodeIndex = (TUint16)aCode - KBaseCode; |
|
667 return (smileyCodeIndex>=0 && smileyCodeIndex<iSmileyCodeIndexArray.Count()); |
|
668 } |
|
669 |
|
670 const TDesC& CSmileyModel::Text(TChar aCode) const |
|
671 { |
|
672 if(IsSmiley(aCode)) |
|
673 { |
|
674 TInt smileyCodeIndex = (TUint16)aCode - KBaseCode; |
|
675 return iSmileyCodeIndexArray[smileyCodeIndex].Text(); |
|
676 } |
|
677 else |
|
678 { |
|
679 return KNullDesC; |
|
680 } |
343 } |
681 } |
344 |
682 |
345 void CSmileyModel::SetSize(const TSize& aSize) |
683 void CSmileyModel::SetSize(const TSize& aSize) |
346 { |
684 { |
347 for(TInt i(0); i<Count(); i++) |
685 if(ArrayCount() && iSmileyIconArray[0]->Size()!=aSize) |
348 { |
686 { |
349 iSmileyIconArray[i]->SetSize(aSize); |
687 for(TInt i(0); i<ArrayCount(); i++) |
350 } |
688 { |
351 } |
689 iSmileyIconArray[i]->SetSize(aSize); |
352 |
690 } |
353 CSmileyIcon* CSmileyModel::operator[](TInt aIndex) const |
691 } |
354 { |
692 } |
355 if(aIndex>=0 && aIndex<Count()) |
693 |
|
694 void CSmileyModel::SetSizeByFont(const CFont* aFont) |
|
695 { |
|
696 TSize size(aFont->TextWidthInPixels(KPlaceHolder),aFont->HeightInPixels()); |
|
697 SetSize(size); |
|
698 } |
|
699 |
|
700 void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TPoint& aPosition) const |
|
701 { |
|
702 TPtrC ptr = aText; |
|
703 TPoint pos = aPosition; |
|
704 |
|
705 aGc.UseFont(aFont); |
|
706 |
|
707 TBool metSmileyNotReady = EFalse; |
|
708 |
|
709 while(ptr.Length()) |
|
710 { |
|
711 TInt i = 0; |
|
712 for(; i<ptr.Length(); i++) // find next smiley code |
|
713 { |
|
714 if(IsSmiley(ptr[i])) |
|
715 { |
|
716 break; |
|
717 } |
|
718 } |
|
719 |
|
720 if(i > 0) // have text |
|
721 { |
|
722 TPtrC txt = ptr.Left(i); |
|
723 aGc.DrawText(txt, pos); |
|
724 pos += TPoint(aFont->TextWidthInPixels(txt),0); |
|
725 |
|
726 ptr.Set(ptr.Right(ptr.Length()-i)); |
|
727 i = 0; |
|
728 } |
|
729 |
|
730 if(ptr.Length()) // breaked by smiley code |
|
731 { |
|
732 CAknSmileyIcon* icon = Smiley(ptr[i]); |
|
733 if(icon) |
|
734 { |
|
735 TSize size = icon->Size(); |
|
736 TPoint tl = pos; |
|
737 tl.iY = tl.iY - (size.iHeight + aFont->HeightInPixels()) / 2; |
|
738 if(!metSmileyNotReady && icon->ReadyToDraw()) |
|
739 { |
|
740 aGc.BitBltMasked(tl, icon->Image(), TRect(size), icon->Mask(), EFalse); |
|
741 } |
|
742 else |
|
743 { |
|
744 metSmileyNotReady = ETrue; |
|
745 } |
|
746 pos += TPoint(aFont->TextWidthInPixels(ptr.Left(2)),0); |
|
747 } |
|
748 |
|
749 ptr.Set(ptr.Right(ptr.Length()-2)); |
|
750 } |
|
751 } |
|
752 } |
|
753 |
|
754 void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const TAknLayoutText& aLayout, TBool aUseLogicalToVisualConversion) const |
|
755 { |
|
756 _AKNTRACE_FUNC_ENTER; |
|
757 // adapter variables |
|
758 const CFont* font = aLayout.Font(); |
|
759 TRect textRect = aLayout.TextRect(); |
|
760 TInt offset = aLayout.BaselineOffset(); |
|
761 CGraphicsContext::TTextAlign align = aLayout.Align(); |
|
762 |
|
763 // belows are all from |
|
764 // void TAknLayoutText::DrawText(CGraphicsContext& aGc,const TDesC& aText,TBool aUseLogicalToVisualConversion, const TRgb &aColor) const |
|
765 |
|
766 __ASSERT_DEBUG(font, Panic(EAknPanicLayoutTextNotCalled)); |
|
767 |
|
768 //aGc.UseFont( font ); |
|
769 //aGc.SetPenColor( aColor ); |
|
770 if ( aText.Length() ) |
|
771 { |
|
772 HBufC* visualBuf = NULL; |
|
773 TPtrC text( aText ); |
|
774 |
|
775 if ( aUseLogicalToVisualConversion ) |
|
776 { |
|
777 visualBuf = HBufC::New( aText.Length() + KAknBidiExtraSpacePerLine ); |
|
778 |
|
779 // In OOM, logical to visual conversion is not performed... |
|
780 |
|
781 if ( visualBuf ) |
|
782 { |
|
783 *visualBuf = aText; // copy |
|
784 TPtr ptr = visualBuf->Des(); |
|
785 |
|
786 TInt maxWidth = textRect.Size().iWidth; |
|
787 // Logical to visual conversion. |
|
788 AknBidiTextUtils::ConvertToVisualAndClip( |
|
789 aText, |
|
790 ptr, |
|
791 *font, |
|
792 maxWidth, |
|
793 maxWidth ); |
|
794 // for smiley begin |
|
795 const TInt length = ptr.Length(); |
|
796 if(length>1 && IsSmiley(ptr[length-2])) |
|
797 { |
|
798 if(ptr[length-1] != 'i') |
|
799 { |
|
800 // smiley is clipped for visual, del this smiley |
|
801 ptr.Delete(length-2, 1); |
|
802 } |
|
803 } |
|
804 // for smiley end |
|
805 |
|
806 text.Set( ptr ); |
|
807 } |
|
808 } |
|
809 |
|
810 // Calculate x-offset based on the used alignment |
|
811 TInt margin = 0; |
|
812 if ( align != CGraphicsContext::ELeft ) |
|
813 { |
|
814 // Measure the full width of the text (ie. what DrawText needs) |
|
815 TInt textWidth = AknBidiTextUtils::MeasureTextBoundsWidth( *font, text,CFont::TMeasureTextInput::EFVisualOrder ); |
|
816 |
|
817 const TInt extraWidth = textRect.Width() - textWidth; |
|
818 if ( align == CGraphicsContext::ECenter ) |
|
819 { |
|
820 margin = extraWidth / 2; |
|
821 } |
|
822 else // right aligned |
|
823 { |
|
824 margin = extraWidth; |
|
825 } |
|
826 } |
|
827 |
|
828 // Need to make the drawing rectangle bigger to account for underlines |
|
829 TRect drawRect(textRect); |
|
830 TInt height = drawRect.Height(); |
|
831 // The underline position is not available from the GC. The following code imitates what Symbian CFbsBitGC implements. |
|
832 // (height-offset) is the part below the baseline. Check if it sufficient |
|
833 TInt extraHeightForUnderlining = 1 + Max(1, height/10)-(height-offset); |
|
834 if ( extraHeightForUnderlining > 0 ) |
|
835 drawRect.iBr.iY += extraHeightForUnderlining; |
|
836 |
|
837 // for smiley |
|
838 //aGc.DrawText( text, drawRect, offset, CGraphicsContext::ELeft, margin ); |
|
839 DrawText(aGc, text, font, drawRect, offset, CGraphicsContext::ELeft, margin); |
|
840 |
|
841 delete visualBuf; |
|
842 } |
|
843 |
|
844 //aGc.DiscardFont(); // Release the font cache |
|
845 _AKNTRACE_FUNC_EXIT; |
|
846 } |
|
847 |
|
848 void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TRect& aBox, TInt aBaselineOffset, |
|
849 CGraphicsContext::TTextAlign aAlignment, TInt aLeftMargin) const |
|
850 { |
|
851 TInt boxWidth = aBox.Width(); |
|
852 TInt textWidth = aFont->TextWidthInPixels(aText); |
|
853 |
|
854 TPoint offset; |
|
855 offset.iY = aBaselineOffset; |
|
856 |
|
857 switch(aAlignment) |
|
858 { |
|
859 case CGraphicsContext::ELeft: |
|
860 offset.iX = aLeftMargin; |
|
861 break; |
|
862 |
|
863 case CGraphicsContext::ERight: |
|
864 offset.iX = boxWidth - textWidth - aLeftMargin; |
|
865 break; |
|
866 |
|
867 case CGraphicsContext::ECenter: |
|
868 offset.iX = (boxWidth - textWidth) / 2; |
|
869 break; |
|
870 |
|
871 default: |
|
872 break; |
|
873 } |
|
874 |
|
875 DrawText(aGc, aText, aFont, aBox, offset); |
|
876 } |
|
877 |
|
878 void CSmileyModel::DrawText(CWindowGc& aGc, const TDesC& aText, const CFont* aFont, const TRect& aBox, const TPoint& aOffset) const |
|
879 { |
|
880 TPtrC ptr = aText; |
|
881 TPoint offset = aOffset; |
|
882 |
|
883 aGc.UseFont(aFont); |
|
884 |
|
885 TInt fontH = aFont->FontMaxHeight(); |
|
886 |
|
887 TBool metSmileyNotReady = EFalse; |
|
888 |
|
889 while(ptr.Length()) |
|
890 { |
|
891 TInt i = 0; |
|
892 for(; i<ptr.Length(); i++) // find next smiley code |
|
893 { |
|
894 if(IsSmiley(ptr[i])) |
|
895 { |
|
896 break; |
|
897 } |
|
898 } |
|
899 |
|
900 if(i > 0) // have text |
|
901 { |
|
902 TPtrC txt = ptr.Left(i); |
|
903 aGc.DrawText(txt, aBox, offset.iY, CGraphicsContext::ELeft, offset.iX); |
|
904 offset.iX += aFont->TextWidthInPixels(txt); |
|
905 |
|
906 ptr.Set(ptr.Right(ptr.Length()-i)); |
|
907 i = 0; |
|
908 } |
|
909 |
|
910 if(ptr.Length()) // breaked by smiley code |
|
911 { |
|
912 CAknSmileyIcon* icon = Smiley(ptr[i]); |
|
913 if(icon) |
|
914 { |
|
915 TSize size = icon->Size(); |
|
916 TPoint tl = aBox.iTl; |
|
917 tl.iX += offset.iX; |
|
918 //tl.iY = tl.iY - size.iHeight/*(size.iHeight + fontH) / 2*/; |
|
919 TRect imgWindow(tl, size); |
|
920 imgWindow.Intersection(aBox); |
|
921 if(!imgWindow.IsEmpty()) |
|
922 { |
|
923 TRect innerRect = TRect(imgWindow.iTl-tl,imgWindow.Size()); |
|
924 if(!metSmileyNotReady && icon->ReadyToDraw()) |
|
925 { |
|
926 aGc.BitBltMasked(imgWindow.iTl, icon->Image(), innerRect, icon->Mask(), EFalse); |
|
927 } |
|
928 else |
|
929 { |
|
930 metSmileyNotReady = ETrue; |
|
931 } |
|
932 } |
|
933 |
|
934 //offset += TPoint(aFont->TextWidthInPixels(ptr.Left(2)),0); |
|
935 offset.iX += size.iWidth; |
|
936 } |
|
937 |
|
938 ptr.Set(ptr.Right(ptr.Length()-2)); |
|
939 } |
|
940 } |
|
941 } |
|
942 |
|
943 CAknSmileyIcon* CSmileyModel::Smiley(TChar aCode) const |
|
944 { |
|
945 if(IsSmiley(aCode)) |
|
946 { |
|
947 TInt smileyCodeIndex = (TUint16)aCode - KBaseCode; |
|
948 return iSmileyCodeIndexArray[smileyCodeIndex].Smiley(); |
|
949 } |
|
950 else |
|
951 { |
|
952 return NULL; |
|
953 } |
|
954 } |
|
955 |
|
956 CAknSmileyIcon* CSmileyModel::operator[](TInt aIndex) const |
|
957 { |
|
958 if(aIndex>=0 && aIndex<ArrayCount()) |
356 { |
959 { |
357 return iSmileyIconArray[aIndex]; |
960 return iSmileyIconArray[aIndex]; |
358 } |
961 } |
359 else |
962 else |
360 { |
963 { |