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