222 TInt aStartRow, |
208 TInt aStartRow, |
223 TInt aEndRow ) |
209 TInt aEndRow ) |
224 { |
210 { |
225 FUNC_LOG; |
211 FUNC_LOG; |
226 |
212 |
227 |
213 if ( iLinkList.Count() > aIndex) |
228 if(iLinkList.Count() > aIndex) |
|
229 { |
214 { |
230 TInt pos = iLinkList[aIndex]->StartPos(); |
215 TInt currPos( KErrNotFound ); |
|
216 const CESMRRichTextLink* currentLink = GetSelectedLink(); |
|
217 if ( currentLink ) |
|
218 { |
|
219 currPos = currentLink->StartPos(); |
|
220 } |
|
221 |
|
222 TInt pos = iLinkList[ aIndex ]->StartPos(); |
231 |
223 |
232 TInt checkRow = TextLayout()->GetLineNumber( pos ); |
224 TInt checkRow = TextLayout()->GetLineNumber( pos ); |
233 |
225 |
234 if ( checkRow >= aStartRow && checkRow <= ( aEndRow ) ) |
226 if ( checkRow >= aStartRow && checkRow <= aEndRow ) |
235 { |
227 { |
236 if ( aDirection == TCursorPosition::EFLineDown && |
228 if ( aDirection == TCursorPosition::EFLineDown && |
237 aIndex > iCurrentLinkIndex || |
229 pos > currPos || |
238 aDirection == TCursorPosition::EFLineUp && |
230 aDirection == TCursorPosition::EFLineUp && |
239 ( aIndex < iCurrentLinkIndex || |
231 ( pos < currPos || currPos == KErrNotFound ) ) |
240 iCurrentLinkIndex == KErrNotFound )) |
|
241 { |
232 { |
242 iCurrentLinkIndex = aIndex; |
|
243 |
|
244 // link found between next scroll area. |
233 // link found between next scroll area. |
245 return checkRow; |
234 return checkRow; |
246 } |
235 } |
247 } |
236 } |
248 } |
237 } |
249 return KErrNotFound; |
238 return KErrNotFound; |
250 } |
239 } |
251 |
240 |
252 // ----------------------------------------------------------------------------- |
241 // ----------------------------------------------------------------------------- |
253 // CESMRRichTextViewer::SetHighLightToNextLinkL |
|
254 // ----------------------------------------------------------------------------- |
|
255 // |
|
256 TBool CESMRRichTextViewer::SetHighLightToNextLinkL( |
|
257 TCursorPosition::TMovementType aDirection, |
|
258 TInt aStartRow, |
|
259 TInt aEndRow ) |
|
260 { |
|
261 FUNC_LOG; |
|
262 TBool ret( EFalse ); |
|
263 |
|
264 TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() ); |
|
265 |
|
266 // check is there a link before next scroll point: |
|
267 TInt linkRow = FindTextLinkBetweenNextScrollArea( |
|
268 aStartRow , aEndRow, aDirection); |
|
269 |
|
270 if ( linkRow != KErrNotFound && iCurrentLinkIndex != KErrNotFound ) |
|
271 { |
|
272 const CESMRRichTextLink* link = GetSelectedLink ( ); |
|
273 if (link ) |
|
274 { |
|
275 HighlightLink (*link ); |
|
276 |
|
277 if ( iObserver && linkRow != currentLineNumber ) |
|
278 { |
|
279 TInt endOfLink = link->StartPos()+link->Length(); |
|
280 TInt line = TextLayout()->GetLineNumber( endOfLink ); |
|
281 if ( aDirection == TCursorPosition::EFLineUp ) // moving up: |
|
282 { |
|
283 iObserver->MoveListAreaDownL( |
|
284 RowHeight() * ( currentLineNumber - line )); |
|
285 } |
|
286 else |
|
287 { |
|
288 iObserver->MoveListAreaUpL( |
|
289 RowHeight() * ( line - currentLineNumber )); |
|
290 } |
|
291 } |
|
292 |
|
293 DrawDeferred ( ); |
|
294 ret = ETrue; |
|
295 } |
|
296 } |
|
297 else |
|
298 { |
|
299 // no link are focused, do reset work to refresh the option menu. |
|
300 ResetActionMenuL(); |
|
301 } |
|
302 |
|
303 return ret; |
|
304 } |
|
305 |
|
306 // ----------------------------------------------------------------------------- |
|
307 // CESMRRichTextViewer::OfferKeyEventL |
242 // CESMRRichTextViewer::OfferKeyEventL |
308 // ----------------------------------------------------------------------------- |
243 // ----------------------------------------------------------------------------- |
309 // |
244 // |
310 EXPORT_C TKeyResponse CESMRRichTextViewer::OfferKeyEventL( |
245 EXPORT_C TKeyResponse CESMRRichTextViewer::OfferKeyEventL( |
311 const TKeyEvent &aKeyEvent, |
246 const TKeyEvent &aKeyEvent, |
312 TEventCode aType ) |
247 TEventCode aType ) |
313 { |
248 { |
314 FUNC_LOG; |
249 FUNC_LOG; |
315 // Handle only event keys |
250 TKeyResponse response( EKeyWasNotConsumed ); |
316 if ( aType == EEventKey ) |
251 |
317 { |
252 // Handle only event keys. |
318 if ( iObserver ) // only description field has observer set. |
253 if( aType != EEventKey ) |
319 { |
254 { |
320 // fetch the current line number: |
255 return response; |
321 TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() ); |
256 } |
322 |
257 |
323 if ( aKeyEvent.iCode == EKeyDownArrow && aType == EEventKey ) |
258 /* |
324 { |
259 * Handles scrolling between rich text links. |
325 if ( !iObserver->IsFieldBottomVisible() && |
260 */ |
326 SetHighLightToNextLinkL( |
261 const CESMRRichTextLink* selectedLink = GetSelectedLink(); |
327 TCursorPosition::EFLineDown, |
262 TInt linkCount = iLinkList.Count(); |
328 currentLineNumber, |
263 |
329 currentLineNumber + KMaxAddressFieldLines) ) |
264 // If a link is selected, it means that we are operating within |
|
265 // the field and can move focus between the links. |
|
266 if( linkCount && selectedLink ) |
|
267 { |
|
268 TInt selectedLinkIndex = iLinkList.Find( selectedLink ); |
|
269 |
|
270 switch ( aKeyEvent.iCode ) |
|
271 { |
|
272 case EKeyLeftArrow: |
|
273 case EKeyUpArrow: |
|
274 { |
|
275 // If possible and exists ... |
|
276 if( selectedLinkIndex > 0 && |
|
277 selectedLinkIndex < linkCount ) |
330 { |
278 { |
331 return EKeyWasConsumed; |
279 // ...Highlight previous link. |
|
280 HighlightLinkL( *( iLinkList[ selectedLinkIndex - 1 ] ) ); |
|
281 response = EKeyWasConsumed; |
|
282 |
|
283 // View update required, for example if link is out of |
|
284 // viewable area. |
|
285 UpdateViewL( aKeyEvent ); |
332 } |
286 } |
333 else if ( iObserver->IsFieldBottomVisible() ) |
287 |
|
288 break; |
|
289 } |
|
290 case EKeyRightArrow: |
|
291 case EKeyDownArrow: |
|
292 { |
|
293 // If possible and exists ... |
|
294 if( selectedLinkIndex + 1 < linkCount && |
|
295 selectedLinkIndex >= 0 ) |
334 { |
296 { |
335 if ( SetHighLightToNextLinkL(TCursorPosition::EFLineDown, |
297 // ...Highlight next link. |
336 currentLineNumber, |
298 HighlightLinkL( *( iLinkList[ selectedLinkIndex + 1 ] ) ); |
337 iNumberOfLines) ) |
299 response = EKeyWasConsumed; |
|
300 |
|
301 // View update required, for example if link is out of |
|
302 // viewable area. |
|
303 UpdateViewL( aKeyEvent ); |
|
304 } |
|
305 |
|
306 break; |
|
307 } |
|
308 case EKeyDevice3: // Selection key |
|
309 { |
|
310 // No implementation. Non-MSK devices might require this. |
|
311 break; |
|
312 } |
|
313 default: |
|
314 break; |
|
315 } |
|
316 } |
|
317 |
|
318 return response; |
|
319 } |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // CESMRRichTextViewer::HandlePointerEventL |
|
323 // ----------------------------------------------------------------------------- |
|
324 // |
|
325 void CESMRRichTextViewer::HandlePointerEventL( const TPointerEvent& aPointerEvent ) |
|
326 { |
|
327 if ( Rect().Contains( aPointerEvent.iPosition) ) |
|
328 { |
|
329 TBool linkFound( EFalse ); |
|
330 |
|
331 switch ( aPointerEvent.iType ) |
|
332 { |
|
333 case TPointerEvent::EButton1Down: |
|
334 case TPointerEvent::EDrag: |
|
335 { |
|
336 RRegion linkArea; |
|
337 CleanupClosePushL( linkArea ); |
|
338 |
|
339 // Find matching link |
|
340 TInt count = iLinkList.Count(); |
|
341 |
|
342 for ( TInt i = 0; i < count; ++i ) |
|
343 { |
|
344 CESMRRichTextLink* link = iLinkList[ i ]; |
|
345 GetLinkAreaL( linkArea, *link ); |
|
346 |
|
347 if ( linkArea.Contains( aPointerEvent.iPosition ) ) |
338 { |
348 { |
339 return EKeyWasConsumed; |
349 if ( link != GetSelectedLink() ) |
|
350 { |
|
351 iCntMenuHdlr->SetContactMenuObserver( this ); |
|
352 HighlightLinkL( *link ); |
|
353 DrawDeferred(); |
|
354 } |
|
355 |
|
356 linkFound = ETrue; |
|
357 break; |
340 } |
358 } |
341 // means that the whole control is visible: |
|
342 // and we can skip to next field |
|
343 return EKeyWasNotConsumed; |
|
344 } |
359 } |
345 |
360 |
346 if ( currentLineNumber == iNumberOfLines ) |
361 CleanupStack::PopAndDestroy( &linkArea ); |
|
362 |
|
363 break; |
|
364 } |
|
365 |
|
366 case TPointerEvent::EButton1Up: |
|
367 { |
|
368 const CESMRRichTextLink* link = GetSelectedLink(); |
|
369 |
|
370 TBool menuAvailable = iCntMenuHdlr->OptionsMenuAvailable(); |
|
371 |
|
372 if ( link |
|
373 && ( menuAvailable |
|
374 || link->Type() == CESMRRichTextLink::ETypeLocationUrl |
|
375 || link->Type() == CESMRRichTextLink::ETypeAttachment ) ) |
347 { |
376 { |
348 // the end of text has been reached |
377 linkFound = ETrue; |
349 return EKeyWasConsumed; |
378 |
|
379 LinkSelectedL(); |
350 } |
380 } |
351 |
381 else if ( link && !menuAvailable ) |
352 // move three lines... |
|
353 ScrollViewL( KMaxAddressFieldLines, |
|
354 TCursorPosition::EFLineDown); |
|
355 |
|
356 |
|
357 SetSelectionL( CursorPos(), CursorPos() ); |
|
358 iCurrentLinkIndex = KErrNotFound; |
|
359 if ( iObserver ) |
|
360 { |
382 { |
361 iObserver->MoveListAreaUpL( |
383 linkFound = ETrue; |
362 RowHeight() * KMaxAddressFieldLines ); |
384 iOpenActionMenu = ETrue; |
363 } |
385 } |
364 |
386 break; |
365 return EKeyWasConsumed; |
387 } |
366 } |
388 default: |
367 else if ( aKeyEvent.iCode == EKeyUpArrow && aType == EEventKey ) |
389 { |
368 { |
390 break; |
369 if (iPosition.iY < 0 && |
391 } |
370 SetHighLightToNextLinkL( |
392 } |
371 TCursorPosition::EFLineUp, |
393 |
372 currentLineNumber - KMaxAddressFieldLines, |
394 if ( !linkFound ) |
373 currentLineNumber)) |
395 { |
374 { |
396 // Tap on plain text |
375 return EKeyWasConsumed; |
397 TextView()->ClearSelectionL(); |
376 } |
398 ResetActionMenuL(); |
377 if ( iPosition.iY > 0 ) |
399 DrawDeferred(); |
378 { |
400 } |
379 // before changing the focus the field above, |
401 |
380 // check is there any links in rest of text |
402 } |
381 if (SetHighLightToNextLinkL(TCursorPosition::EFLineUp, |
403 |
382 0, |
|
383 currentLineNumber)) |
|
384 { |
|
385 return EKeyWasConsumed; |
|
386 } |
|
387 |
|
388 // means that the whole control is visible: |
|
389 // and we can skip to next field |
|
390 return EKeyWasNotConsumed; |
|
391 } |
|
392 else |
|
393 { |
|
394 TInt currentLineNumber = |
|
395 TextLayout()->GetLineNumber( CursorPos() ); |
|
396 // move three lines... |
|
397 ScrollViewL( KMaxAddressFieldLines, |
|
398 TCursorPosition::EFLineUp); |
|
399 |
|
400 SetSelectionL( CursorPos(), CursorPos()); |
|
401 iCurrentLinkIndex = KErrNotFound; |
|
402 |
|
403 if ( iObserver ) |
|
404 { |
|
405 iObserver->MoveListAreaDownL( |
|
406 RowHeight() * KMaxAddressFieldLines ); |
|
407 } |
|
408 |
|
409 currentLineNumber = |
|
410 TextLayout()->GetLineNumber( CursorPos() ); |
|
411 return EKeyWasConsumed; |
|
412 } |
|
413 } |
|
414 } |
|
415 if ( aKeyEvent.iCode == EKeyRightArrow || |
|
416 aKeyEvent.iCode == EKeyDevice3 || |
|
417 aKeyEvent.iCode == EKeyDevice4 || |
|
418 aKeyEvent.iCode == EKeyEnter ) |
|
419 { |
|
420 // Show right click menu (action menu) |
|
421 const CESMRRichTextLink* link = GetSelectedLink(); |
|
422 if (link && |
|
423 link->TriggerKey ( )== CESMRRichTextLink::ETriggerKeyRight ) |
|
424 { |
|
425 if ( !iLinkObserver || |
|
426 !iLinkObserver->HandleRichTextLinkSelection(link) ) |
|
427 { |
|
428 iCntMenuHdlr->ShowActionMenuL(); |
|
429 } |
|
430 return EKeyWasConsumed; |
|
431 } |
|
432 } |
|
433 if ( aKeyEvent.iCode == EKeyLeftArrow ) |
|
434 { |
|
435 const CESMRRichTextLink* link = GetSelectedLink(); |
|
436 if ( link ) |
|
437 { |
|
438 return EKeyWasConsumed; |
|
439 } |
|
440 } |
|
441 if ( aKeyEvent.iCode == EKeyDevice3 || |
|
442 aKeyEvent.iCode == EKeyDevice4 || |
|
443 aKeyEvent.iCode == EKeyEnter ) |
|
444 { |
|
445 // Select link |
|
446 const CESMRRichTextLink* link = GetSelectedLink ( ); |
|
447 if (link && |
|
448 link->TriggerKey ( )== CESMRRichTextLink::ETriggerKeyOk ) |
|
449 { |
|
450 if (iLinkObserver && |
|
451 iLinkObserver->HandleRichTextLinkSelection (link ) ) |
|
452 { |
|
453 return EKeyWasConsumed; |
|
454 } |
|
455 } |
|
456 } |
|
457 } |
|
458 |
|
459 return EKeyWasNotConsumed; |
|
460 } |
|
461 |
|
462 |
|
463 // ----------------------------------------------------------------------------- |
|
464 // CESMRRichTextViewer::ScrollViewL |
|
465 // ----------------------------------------------------------------------------- |
|
466 // |
|
467 void CESMRRichTextViewer::ScrollViewL( |
|
468 TInt aNumberOfRows, |
|
469 TCursorPosition::TMovementType aDirection) |
|
470 { |
|
471 FUNC_LOG; |
|
472 for( TInt i=0; i < aNumberOfRows; i++ ) |
|
473 { |
|
474 MoveCursorL( aDirection, EFalse); |
|
475 } |
|
476 } |
404 } |
477 |
405 |
478 // ----------------------------------------------------------------------------- |
406 // ----------------------------------------------------------------------------- |
479 // CESMRRichTextViewer::SetMargins |
407 // CESMRRichTextViewer::SetMargins |
480 // ----------------------------------------------------------------------------- |
408 // ----------------------------------------------------------------------------- |
481 // |
409 // |
482 EXPORT_C void CESMRRichTextViewer::SetMargins( TInt sMargin ) |
410 EXPORT_C void CESMRRichTextViewer::SetMargins( TInt sMargin ) |
483 { |
411 { |
484 // Set new value for left and right margins |
412 // Set new value for left and right margins |
485 if ( TextView() ) |
413 TextView()->SetMarginWidths( sMargin ,0); |
486 { |
|
487 TextView()->SetMarginWidths( sMargin ,0); |
|
488 } |
|
489 } |
414 } |
490 |
415 |
491 // ----------------------------------------------------------------------------- |
416 // ----------------------------------------------------------------------------- |
|
417 // CESMRRichTextViewer::SetTextL |
|
418 // ----------------------------------------------------------------------------- |
|
419 // |
|
420 EXPORT_C void CESMRRichTextViewer::SetTextL( |
|
421 const TDesC* aText, |
|
422 TBool aSearchLinks ) |
|
423 { |
|
424 FUNC_LOG; |
|
425 |
|
426 iLinkList.ResetAndDestroy(); |
|
427 |
|
428 TextView()->SetMarginWidths( KDefaultTextSideMargin ,0); |
|
429 |
|
430 // Clear edwin text |
|
431 CEikEdwin::SetCursorPosL( 0, EFalse ); |
|
432 CEikRichTextEditor::SetTextL( &KNullDesC ); |
|
433 RichText()->Reset(); |
|
434 |
|
435 // text lenght plus one to ensure the formatting |
|
436 // used is full, not band formatting. |
|
437 SetUpperFullFormattingLength( aText->Length() + 1 ); |
|
438 |
|
439 // Set new edwin text |
|
440 CEikEdwin::SetTextLimit( aText->Length ( ) ); |
|
441 CEikRichTextEditor::SetTextL( aText ); |
|
442 |
|
443 //Make sure cursor is invisible and selection visible |
|
444 TextView()->SetCursorVisibilityL( |
|
445 TCursor::EFCursorInvisible, |
|
446 TCursor::EFCursorInvisible ); |
|
447 TextView()->SetSelectionVisibilityL( ETrue ); |
|
448 |
|
449 // Search text for links (highlights) |
|
450 if ( aSearchLinks ) |
|
451 { |
|
452 SearchLinksL( *aText ); |
|
453 // find first link. |
|
454 FindTextLinkBetweenNextScrollArea(0, KMaxAddressFieldLines, TCursorPosition::EFLineDown); |
|
455 } |
|
456 } |
|
457 |
|
458 // ----------------------------------------------------------------------------- |
|
459 // CESMRRichTextViewer::SetLinkObserver |
|
460 // ----------------------------------------------------------------------------- |
|
461 // |
|
462 EXPORT_C void CESMRRichTextViewer::SetLinkObserver( |
|
463 MESMRRichTextObserver* aLinkObserver ) |
|
464 { |
|
465 FUNC_LOG; |
|
466 iLinkObserver = aLinkObserver; |
|
467 } |
|
468 |
|
469 // ----------------------------------------------------------------------------- |
|
470 // CESMRRichTextViewer::AddLinkL |
|
471 // ----------------------------------------------------------------------------- |
|
472 // |
|
473 EXPORT_C void CESMRRichTextViewer::AddLinkL( CESMRRichTextLink* aLink ) |
|
474 { |
|
475 FUNC_LOG; |
|
476 // If this is first link, set it highlighted |
|
477 TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 ); |
|
478 |
|
479 // Reserve space for new link |
|
480 iLinkList.ReserveL( iLinkList.Count() + 1 ); |
|
481 |
|
482 RichText()->ApplyCharFormatL( iRichTextLinkFormat, |
|
483 iRichTextLinkFormatMask, |
|
484 aLink->StartPos(), |
|
485 aLink->Length() ); |
|
486 |
|
487 // Append aLink to link list. Space has been reserved, so this cannot fail. |
|
488 iLinkList.AppendL( aLink ); |
|
489 |
|
490 if ( highlight ) |
|
491 { |
|
492 HighlightLinkL( *aLink ); |
|
493 } |
|
494 } |
|
495 |
|
496 // ----------------------------------------------------------------------------- |
|
497 // CESMRRichTextViewer::InsertLinkL |
|
498 // ----------------------------------------------------------------------------- |
|
499 // |
|
500 EXPORT_C void CESMRRichTextViewer::InsertLinkL( CESMRRichTextLink* aLink, |
|
501 TInt aPosition ) |
|
502 { |
|
503 FUNC_LOG; |
|
504 // If this is first link, set it highlighted |
|
505 TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 ); |
|
506 |
|
507 // Reserve space for new link |
|
508 iLinkList.ReserveL( iLinkList.Count() + 1 ); |
|
509 |
|
510 RichText()->ApplyCharFormatL( iRichTextLinkFormat, |
|
511 iRichTextLinkFormatMask, |
|
512 aLink->StartPos(), |
|
513 aLink->Length() ); |
|
514 |
|
515 // Insert aLink to link list. Space has been reserved, so this cannot fail. |
|
516 // InsertL panics if aPosition is illegal. |
|
517 iLinkList.InsertL( aLink, aPosition ); |
|
518 |
|
519 if ( highlight ) |
|
520 { |
|
521 HighlightLinkL( *aLink ); |
|
522 } |
|
523 } |
|
524 |
|
525 // ----------------------------------------------------------------------------- |
|
526 // CESMRRichTextViewer::GetSelectedLink |
|
527 // ----------------------------------------------------------------------------- |
|
528 // |
|
529 EXPORT_C const CESMRRichTextLink* CESMRRichTextViewer::GetSelectedLink( ) const |
|
530 { |
|
531 FUNC_LOG; |
|
532 CESMRRichTextLink* link( NULL ); |
|
533 |
|
534 TCursorSelection currentSelection = Selection(); |
|
535 |
|
536 for ( TInt i = 0; i < iLinkList.Count(); ++i ) |
|
537 { |
|
538 CESMRRichTextLink* tempLink = iLinkList[i]; |
|
539 TInt startPos = tempLink->StartPos(); |
|
540 TInt length = tempLink->Length(); |
|
541 |
|
542 TCursorSelection linkSelection( startPos, startPos + length ); |
|
543 |
|
544 if( currentSelection.iCursorPos == linkSelection.iCursorPos && |
|
545 currentSelection.iAnchorPos == linkSelection.iAnchorPos ) |
|
546 { |
|
547 link = tempLink; |
|
548 break; |
|
549 } |
|
550 } |
|
551 |
|
552 return link; |
|
553 } |
|
554 |
|
555 // ----------------------------------------------------------------------------- |
|
556 // CESMRRichTextViewer::GetLinkTextL |
|
557 // ----------------------------------------------------------------------------- |
|
558 // |
|
559 EXPORT_C HBufC* CESMRRichTextViewer::GetLinkTextLC( |
|
560 const CESMRRichTextLink& aLink ) const |
|
561 { |
|
562 FUNC_LOG; |
|
563 return RichText()->Read( aLink.StartPos(), aLink.Length() ).AllocLC(); |
|
564 } |
|
565 |
|
566 // ----------------------------------------------------------------------------- |
|
567 // CESMRRichTextViewer::CESMRRichTextViewer |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 EXPORT_C void CESMRRichTextViewer::SetListObserver( |
|
571 MESMRListObserver* aObserver ) |
|
572 { |
|
573 FUNC_LOG; |
|
574 iObserver = aObserver; |
|
575 } |
|
576 |
|
577 // ----------------------------------------------------------------------------- |
|
578 // CESMRRichTextViewer::RowHeight |
|
579 // ----------------------------------------------------------------------------- |
|
580 // |
|
581 EXPORT_C TInt CESMRRichTextViewer::RowHeight() |
|
582 { |
|
583 FUNC_LOG; |
|
584 TInt bandHeight = TextLayout()->BandHeight(); |
|
585 // Starts from zero, so let's increase the count by one. |
|
586 TInt lineNumberCount = TextLayout()->GetLineNumber( TextLength() ) + 1; |
|
587 |
|
588 return ( bandHeight / lineNumberCount ); |
|
589 } |
|
590 |
|
591 // ----------------------------------------------------------------------------- |
|
592 // CESMRRichTextViewer::LineCount |
|
593 // ----------------------------------------------------------------------------- |
|
594 // |
|
595 EXPORT_C TInt CESMRRichTextViewer::LineCount() |
|
596 { |
|
597 FUNC_LOG; |
|
598 |
|
599 // First row is 0, so let's add one... |
|
600 return ( TextLayout()->GetLineNumber( TextLength() ) + 1 ); |
|
601 } |
|
602 // ----------------------------------------------------------------------------- |
|
603 // CESMRRichTextViewer::CurrentLineNumber |
|
604 // ----------------------------------------------------------------------------- |
|
605 // |
|
606 EXPORT_C TInt CESMRRichTextViewer::CurrentLineNumber() |
|
607 { |
|
608 FUNC_LOG; |
|
609 // first line is zero, let's increase it by one |
|
610 return TextLayout()->GetLineNumber( CursorPos() ) + 1; |
|
611 } |
|
612 |
|
613 // ----------------------------------------------------------------------------- |
492 // CESMRRichTextViewer::SetFontL |
614 // CESMRRichTextViewer::SetFontL |
493 // ----------------------------------------------------------------------------- |
615 // ----------------------------------------------------------------------------- |
494 // |
616 // |
495 EXPORT_C void CESMRRichTextViewer::SetFontL( const CFont* aFont, |
617 EXPORT_C void CESMRRichTextViewer::SetFontL( const CFont* aFont ) |
496 CESMRLayoutManager* aLayout ) |
618 { |
497 { |
619 FUNC_LOG; |
498 FUNC_LOG; |
620 // iFont is stored for changing font color when losing or |
499 // These pointers are stored to able font color changing when losing or |
|
500 // gaining focus |
621 // gaining focus |
501 iLayout = aLayout; |
|
502 iFont = aFont; |
622 iFont = aFont; |
503 |
623 if ( !iParaFormat ) |
504 SetFontColorL( IsFocused() ); |
624 { |
505 |
625 iParaFormat = new ( ELeave ) CParaFormat(); |
|
626 } |
|
627 |
|
628 // All this required, otherwise the font loses its |
|
629 // antialiasing drawing. |
|
630 iParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingExactlyInPixels; |
|
631 |
|
632 iParaFormatMask.SetAttrib( EAttLineSpacing ); |
|
633 iParaFormat->iHorizontalAlignment = CParaFormat::ELeftAlign; |
|
634 iParaFormat->iVerticalAlignment = CParaFormat::ECenterAlign; |
|
635 iParaFormatMask.SetAttrib( EAttAlignment ); |
|
636 iParaFormatMask.SetAttrib( EAttVerticalAlignment ); |
|
637 |
|
638 iCharFormat.iFontSpec = iFont->FontSpecInTwips(); |
|
639 |
|
640 iCharFormatMask.SetAttrib( EAttFontTypeface ); |
|
641 iCharFormatMask.SetAttrib( EAttFontHeight ); |
|
642 iCharFormatMask.SetAttrib( EAttFontPosture ); |
|
643 iCharFormatMask.SetAttrib( EAttFontStrokeWeight ); |
|
644 |
|
645 iCharFormat.iFontPresentation.iTextColor = |
|
646 NMRColorManager::Color( NMRColorManager::EMRMainAreaTextColor ); |
|
647 |
|
648 iCharFormatMask.SetAttrib( EAttColor ); |
|
649 } |
|
650 |
|
651 // ----------------------------------------------------------------------------- |
|
652 // CESMRRichTextViewer::SetLineSpacingL |
|
653 // ----------------------------------------------------------------------------- |
|
654 // |
|
655 EXPORT_C void CESMRRichTextViewer::SetLineSpacingL( TInt aLineSpacingInTwips ) |
|
656 { |
|
657 __ASSERT_DEBUG( iParaFormat, Panic( EParaFormatNotInitialised ) ); |
|
658 iParaFormatMask.SetAttrib( EAttLineSpacing ); |
|
659 iParaFormatMask.SetAttrib( EAttLineSpacingControl ); |
|
660 iParaFormat->iLineSpacingControl = |
|
661 CParaFormat::ELineSpacingExactlyInPixels; |
|
662 |
|
663 iParaFormat->iLineSpacingInTwips = aLineSpacingInTwips; |
|
664 } |
|
665 |
|
666 // ----------------------------------------------------------------------------- |
|
667 // CESMRRichTextViewer::ApplyLayoutChanges |
|
668 // ----------------------------------------------------------------------------- |
|
669 // |
|
670 EXPORT_C void CESMRRichTextViewer::ApplyLayoutChangesL() |
|
671 { |
|
672 __ASSERT_DEBUG( iParaFormat, Panic( EParaFormatNotInitialised ) ); |
|
673 CRichText* richtext = RichText(); |
|
674 TInt paraCount( richtext->ParagraphCount() ); |
|
675 // Go through each paragraph and apply the same format |
|
676 for( TInt i = 0; i < paraCount; ++i ) |
|
677 { |
|
678 TInt paraLen( 0 ); // Length of paragraph |
|
679 TInt fiChPos( 0 ); // First character position of paragraph |
|
680 // Get the length of the paragraph |
|
681 fiChPos = richtext->CharPosOfParagraph( paraLen, i ); |
|
682 richtext->ApplyParaFormatL( |
|
683 iParaFormat, iParaFormatMask, fiChPos, paraLen ); |
|
684 richtext->ApplyCharFormatL( |
|
685 iCharFormat, iCharFormatMask, fiChPos, paraLen ); |
|
686 } |
506 // This forces CEikEdwin::OnReformatL to notify observer |
687 // This forces CEikEdwin::OnReformatL to notify observer |
507 // through HandleEdwinSizeEventL about changed size. |
688 // through HandleEdwinSizeEventL about changed size. |
508 // It is notified only if linecount changes. |
689 // It is notified only if linecount changes. |
509 CEikEdwin::iNumberOfLines = 0; |
690 CEikEdwin::iNumberOfLines = 0; |
510 CEikEdwin::FormatTextL(); |
691 CEikEdwin::FormatTextL(); |
511 } |
692 } |
512 |
693 |
513 // ----------------------------------------------------------------------------- |
694 |
514 // CESMRRichTextViewer::SetFontColor |
695 // ----------------------------------------------------------------------------- |
515 // ----------------------------------------------------------------------------- |
696 // CESMRRichTextViewer::SetSelectedLink |
516 // |
697 // ----------------------------------------------------------------------------- |
517 void CESMRRichTextViewer::SetFontColorL( TBool aFocused ) |
698 // |
518 { |
699 EXPORT_C void CESMRRichTextViewer::SetFocusLink( TInt aLinkIndex ) |
519 FUNC_LOG; |
700 { |
520 // all this stuff is needed to be set, otherwise the |
701 if ( ( aLinkIndex >= 0 ) && ( aLinkIndex < iLinkList.Count() ) ) |
521 // font loses its antialiasing drawing |
702 { |
522 |
703 TRAP_IGNORE( HighlightLinkL( *( iLinkList[aLinkIndex] ) ) ); |
523 TFontSpec fontSpec = iFont->FontSpecInTwips(); |
704 DrawDeferred(); |
524 |
|
525 CParaFormat paraFormat; |
|
526 TParaFormatMask paraFormatMask; |
|
527 paraFormat.iLineSpacingControl = CParaFormat::ELineSpacingExactlyInPixels; |
|
528 |
|
529 paraFormatMask.SetAttrib( EAttLineSpacing ); |
|
530 paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign; |
|
531 paraFormatMask.SetAttrib( EAttAlignment ); |
|
532 |
|
533 TCharFormat charFormat; |
|
534 TCharFormatMask formatMask; |
|
535 charFormat.iFontSpec = fontSpec; |
|
536 |
|
537 formatMask.SetAttrib( EAttFontTypeface ); |
|
538 formatMask.SetAttrib( EAttFontHeight ); |
|
539 formatMask.SetAttrib( EAttFontPosture ); |
|
540 formatMask.SetAttrib( EAttFontStrokeWeight ); |
|
541 |
|
542 if( aFocused ) |
|
543 { |
|
544 charFormat.iFontPresentation.iTextColor = |
|
545 iLayout->ViewerListAreaHighlightedTextColor(); |
|
546 } |
|
547 else |
|
548 { |
|
549 charFormat.iFontPresentation.iTextColor = KRgbBlack; |
|
550 } |
|
551 formatMask.SetAttrib( EAttColor ); |
|
552 |
|
553 CParaFormatLayer* paraFormatLayer = |
|
554 CParaFormatLayer::NewL( ¶Format, paraFormatMask ); |
|
555 CleanupStack::PushL( paraFormatLayer ); |
|
556 |
|
557 CCharFormatLayer* charFormatLayer = |
|
558 CCharFormatLayer::NewL( charFormat, formatMask ); |
|
559 |
|
560 SetParaFormatLayer( paraFormatLayer ); |
|
561 SetCharFormatLayer( charFormatLayer ); |
|
562 |
|
563 CleanupStack::Pop( paraFormatLayer ); |
|
564 } |
|
565 |
|
566 // ----------------------------------------------------------------------------- |
|
567 // CESMRRichTextViewer::SetTextL |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 EXPORT_C void CESMRRichTextViewer::SetTextL( |
|
571 const TDesC* aText, |
|
572 TBool aSearchLinks ) |
|
573 { |
|
574 FUNC_LOG; |
|
575 iCurrentLinkIndex = KErrNotFound; |
|
576 iLinkList.ResetAndDestroy ( ); |
|
577 |
|
578 // Clear edwin text |
|
579 CEikEdwin::SetCursorPosL( 0, EFalse ); |
|
580 |
|
581 // text lenght plus one to ensure the formatting |
|
582 // used is full, not band formatting. |
|
583 SetUpperFullFormattingLength( aText->Length() + 1 ); |
|
584 |
|
585 // Set new edwin text |
|
586 CEikRichTextEditor::SetTextL( aText ); |
|
587 |
|
588 //Make sure cursor is invisible and selection visible |
|
589 TextView()->SetCursorVisibilityL (TCursor::EFCursorInvisible, |
|
590 TCursor::EFCursorInvisible ); |
|
591 TextView()->SetSelectionVisibilityL (ETrue ); |
|
592 |
|
593 // Search text for links (highlights) |
|
594 if (aSearchLinks ) |
|
595 { |
|
596 SearchLinksL( *aText ); |
|
597 // find first link. |
|
598 FindTextLinkBetweenNextScrollArea(0, KMaxAddressFieldLines, TCursorPosition::EFLineDown); |
|
599 } |
|
600 |
|
601 // first row is 0, so let's add one... |
|
602 iNumberOfLines = TextLayout()->GetLineNumber( TextLength() ) + 1; |
|
603 } |
|
604 |
|
605 // ----------------------------------------------------------------------------- |
|
606 // CESMRRichTextViewer::SetLinkObserver |
|
607 // ----------------------------------------------------------------------------- |
|
608 // |
|
609 EXPORT_C void CESMRRichTextViewer::SetLinkObserver( |
|
610 MESMRRichTextObserver* aLinkObserver ) |
|
611 { |
|
612 FUNC_LOG; |
|
613 iLinkObserver = aLinkObserver; |
|
614 } |
|
615 |
|
616 // ----------------------------------------------------------------------------- |
|
617 // CESMRRichTextViewer::AddLinkL |
|
618 // ----------------------------------------------------------------------------- |
|
619 // |
|
620 EXPORT_C void CESMRRichTextViewer::AddLinkL( CESMRRichTextLink* aLink ) |
|
621 { |
|
622 FUNC_LOG; |
|
623 // If this is first link, set it highlighted |
|
624 TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 ); |
|
625 |
|
626 // Reserve space for new link |
|
627 iLinkList.ReserveL( iLinkList.Count() + 1 ); |
|
628 |
|
629 RichText()->ApplyCharFormatL( iFormat, |
|
630 iFormatMask, |
|
631 aLink->StartPos(), |
|
632 aLink->Length() ); |
|
633 |
|
634 // Append aLink to link list. Space has been reserved, so this cannot fail. |
|
635 iLinkList.AppendL( aLink ); |
|
636 |
|
637 if ( highlight ) |
|
638 { |
|
639 HighlightLink( *aLink ); |
|
640 } |
|
641 } |
|
642 |
|
643 // ----------------------------------------------------------------------------- |
|
644 // CESMRRichTextViewer::InsertLinkL |
|
645 // ----------------------------------------------------------------------------- |
|
646 // |
|
647 EXPORT_C void CESMRRichTextViewer::InsertLinkL( CESMRRichTextLink* aLink, |
|
648 TInt aPosition ) |
|
649 { |
|
650 FUNC_LOG; |
|
651 // If this is first link, set it highlighted |
|
652 TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 ); |
|
653 |
|
654 // Reserve space for new link |
|
655 iLinkList.ReserveL( iLinkList.Count() + 1 ); |
|
656 |
|
657 RichText()->ApplyCharFormatL( iFormat, |
|
658 iFormatMask, |
|
659 aLink->StartPos(), |
|
660 aLink->Length() ); |
|
661 |
|
662 // Insert aLink to link list. Space has been reserved, so this cannot fail. |
|
663 // InsertL panics if aPosition is illegal. |
|
664 iLinkList.InsertL( aLink, aPosition ); |
|
665 |
|
666 if ( highlight ) |
|
667 { |
|
668 HighlightLink( *aLink ); |
|
669 } |
705 } |
670 } |
706 } |
671 |
707 |
672 // ----------------------------------------------------------------------------- |
708 // ----------------------------------------------------------------------------- |
673 // CESMRRichTextViewer::GetSelectedLink |
709 // CESMRRichTextViewer::GetSelectedLink |
674 // ----------------------------------------------------------------------------- |
710 // ----------------------------------------------------------------------------- |
675 // |
711 // |
676 EXPORT_C const CESMRRichTextLink* CESMRRichTextViewer::GetSelectedLink( ) const |
712 EXPORT_C TInt CESMRRichTextViewer::GetFocusLink( ) const |
677 { |
713 { |
678 FUNC_LOG; |
714 FUNC_LOG; |
679 if (iCurrentLinkIndex >= 0 && iCurrentLinkIndex < iLinkList.Count ( ) ) |
715 // "-1" stand for no link be selected now. |
680 { |
716 TInt linkIndex( KErrNotFound ); |
681 return iLinkList[iCurrentLinkIndex]; |
717 if ( 0 == iLinkList.Count() ) |
682 } |
718 { |
683 else |
719 return linkIndex; |
684 { |
720 } |
685 return NULL; |
721 |
686 } |
722 TCursorSelection currentSelection = Selection(); |
687 } |
723 |
688 |
724 for ( TInt i = 0; i < iLinkList.Count(); ++i ) |
689 // ----------------------------------------------------------------------------- |
725 { |
690 // CESMRRichTextViewer::GetLinkTextL |
726 CESMRRichTextLink* tempLink = iLinkList[i]; |
691 // ----------------------------------------------------------------------------- |
727 TInt startPos = tempLink->StartPos(); |
692 // |
728 TInt length = tempLink->Length(); |
693 EXPORT_C HBufC* CESMRRichTextViewer::GetLinkTextL( |
729 |
694 const CESMRRichTextLink& aLink ) const |
730 TCursorSelection linkSelection( startPos, startPos + length ); |
695 { |
731 |
696 FUNC_LOG; |
732 if( currentSelection.iCursorPos == linkSelection.iCursorPos && |
697 return RichText()->Read( aLink.StartPos ( ), aLink.Length ( ) ).AllocL(); |
733 currentSelection.iAnchorPos == linkSelection.iAnchorPos ) |
|
734 { |
|
735 linkIndex = i; |
|
736 break; |
|
737 } |
|
738 } |
|
739 |
|
740 return linkIndex; |
698 } |
741 } |
699 |
742 |
700 // ----------------------------------------------------------------------------- |
743 // ----------------------------------------------------------------------------- |
701 // CESMRRichTextViewer::CESMRRichTextViewer |
744 // CESMRRichTextViewer::CESMRRichTextViewer |
702 // ----------------------------------------------------------------------------- |
745 // ----------------------------------------------------------------------------- |
703 // |
746 // |
704 EXPORT_C void CESMRRichTextViewer::SetListObserver( |
|
705 MESMRListObserver* aObserver ) |
|
706 { |
|
707 FUNC_LOG; |
|
708 iObserver = aObserver; |
|
709 } |
|
710 |
|
711 // ----------------------------------------------------------------------------- |
|
712 // CESMRRichTextViewer::RowHeight |
|
713 // ----------------------------------------------------------------------------- |
|
714 // |
|
715 EXPORT_C TInt CESMRRichTextViewer::RowHeight() |
|
716 { |
|
717 FUNC_LOG; |
|
718 TInt bandHeight = TextLayout()->BandHeight(); |
|
719 // Starts from zero, so let's increase the count by one. |
|
720 TInt lineNumberCount = TextLayout()->GetLineNumber( TextLength() ) + 1; |
|
721 |
|
722 return ( bandHeight / lineNumberCount ); |
|
723 } |
|
724 |
|
725 // ----------------------------------------------------------------------------- |
|
726 // CESMRRichTextViewer::LineCount |
|
727 // ----------------------------------------------------------------------------- |
|
728 // |
|
729 EXPORT_C TInt CESMRRichTextViewer::LineCount() |
|
730 { |
|
731 FUNC_LOG; |
|
732 return iNumberOfLines; |
|
733 } |
|
734 // ----------------------------------------------------------------------------- |
|
735 // CESMRRichTextViewer::CurrentLineNumber |
|
736 // ----------------------------------------------------------------------------- |
|
737 // |
|
738 EXPORT_C TInt CESMRRichTextViewer::CurrentLineNumber() |
|
739 { |
|
740 FUNC_LOG; |
|
741 // first line is zero, let's increase it by one |
|
742 return TextLayout()->GetLineNumber( CursorPos() ) + 1; |
|
743 } |
|
744 |
|
745 // ----------------------------------------------------------------------------- |
|
746 // CESMRRichTextViewer::CESMRRichTextViewer |
|
747 // ----------------------------------------------------------------------------- |
|
748 // |
|
749 EXPORT_C void CESMRRichTextViewer::SetActionMenuStatus( TBool aStatus ) |
|
750 { |
|
751 FUNC_LOG; |
|
752 iActionMenuStatus = aStatus; |
|
753 } |
|
754 |
|
755 // ----------------------------------------------------------------------------- |
|
756 // CESMRRichTextViewer::CESMRRichTextViewer |
|
757 // ----------------------------------------------------------------------------- |
|
758 // |
|
759 CESMRRichTextViewer::CESMRRichTextViewer( ) |
747 CESMRRichTextViewer::CESMRRichTextViewer( ) |
760 : iActionMenuStatus( ETrue ), iActionMenuOpen( EFalse ) |
|
761 { |
748 { |
762 FUNC_LOG; |
749 FUNC_LOG; |
763 } |
750 } |
764 |
751 |
765 // ----------------------------------------------------------------------------- |
752 // ----------------------------------------------------------------------------- |
1155 void CESMRRichTextViewer::ActivateL() |
1042 void CESMRRichTextViewer::ActivateL() |
1156 { |
1043 { |
1157 FUNC_LOG; |
1044 FUNC_LOG; |
1158 CEikRichTextEditor::ActivateL(); |
1045 CEikRichTextEditor::ActivateL(); |
1159 |
1046 |
1160 // Make sure correct font color is in use. |
|
1161 SetFontColorL( IsFocused() ); |
|
1162 |
|
1163 // CEikEdwin::ActivateL removes selection, re-set highlight |
1047 // CEikEdwin::ActivateL removes selection, re-set highlight |
1164 // if focused and there's a selected link. |
1048 // if focused and there's a selected link. |
1165 if ( IsFocused() && GetSelectedLink() ) |
1049 const CESMRRichTextLink* link = GetSelectedLink(); |
1166 { |
1050 if ( link && IsFocused() ) |
1167 HighlightLink( *GetSelectedLink() ); |
1051 { |
|
1052 HighlightLinkL( *link ); |
1168 DrawDeferred(); |
1053 DrawDeferred(); |
1169 } |
1054 } |
1170 } |
1055 } |
1171 |
1056 |
1172 // ----------------------------------------------------------------------------- |
1057 // ----------------------------------------------------------------------------- |
1173 // CESMRRichTextViewer::HandlePointerEventL |
1058 // CESMRRichTextViewer::ContactActionQueryComplete |
1174 // ----------------------------------------------------------------------------- |
1059 // ----------------------------------------------------------------------------- |
1175 // |
1060 // |
1176 void CESMRRichTextViewer::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
1061 void CESMRRichTextViewer::ContactActionQueryComplete() |
1177 { |
1062 { |
1178 TBool linkTapped( EFalse ); |
1063 FUNC_LOG; |
1179 CESMRRichTextLink* link = NULL; |
1064 if ( iOpenActionMenu ) |
1180 // fetch the current line number: |
1065 { |
1181 TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() ); |
1066 // Activate link as actions have been discovered |
1182 // find out tapped position |
1067 TRAP_IGNORE( LinkSelectedL() ); |
1183 TPoint touchPoint = aPointerEvent.iPosition; |
1068 } |
1184 |
1069 |
1185 TInt tappedPos = TextView()->XyPosToDocPosL( touchPoint ); |
1070 // Reset menu observer |
1186 for (TInt i = 0; i<iLinkList.Count(); i++) |
1071 iCntMenuHdlr->SetContactMenuObserver( NULL ); |
1187 { |
1072 iOpenActionMenu = EFalse; |
1188 link = iLinkList[ i ]; |
1073 } |
1189 TInt linkStart = link->StartPos(); |
1074 |
1190 TInt linkEnd = link->StartPos() + link->Length() - 1; |
1075 // ----------------------------------------------------------------------------- |
1191 if ( tappedPos >= linkStart && tappedPos <= linkEnd ) |
1076 // CESMRRichTextViewer::ShowContextMenuL |
1192 { |
1077 // ----------------------------------------------------------------------------- |
1193 // link tapped |
1078 // |
1194 linkTapped = ETrue; |
1079 void CESMRRichTextViewer::ShowContextMenuL() |
1195 iCurrentLinkIndex = i; |
1080 { |
|
1081 FUNC_LOG; |
|
1082 iOpenActionMenu = EFalse; |
|
1083 ProcessCommandL( EAknSoftkeyContextOptions ); |
|
1084 } |
|
1085 |
|
1086 // ----------------------------------------------------------------------------- |
|
1087 // CESMRRichTextViewer::GetLinkAreaL |
|
1088 // ----------------------------------------------------------------------------- |
|
1089 // |
|
1090 void CESMRRichTextViewer::GetLinkAreaL( |
|
1091 TRegion& aRegion, |
|
1092 const CESMRRichTextLink& aLink ) const |
|
1093 { |
|
1094 FUNC_LOG; |
|
1095 TTmDocPosSpec posSpec; |
|
1096 TTmPosInfo2 posInfo; |
|
1097 |
|
1098 posSpec.iPos = aLink.StartPos(); |
|
1099 posSpec.iType = TTmDocPosSpec::ELeading; |
|
1100 |
|
1101 aRegion.Clear(); |
|
1102 |
|
1103 if ( TextView()->FindDocPosL( posSpec, posInfo ) ) |
|
1104 { |
|
1105 TRect linkRect( 0, 0, 0, 0 ); |
|
1106 |
|
1107 // Create link surrounding rectangle |
|
1108 HBufC* text = GetLinkTextLC( aLink ); |
|
1109 TInt textWidth = AknBidiTextUtils::MeasureTextBoundsWidth( |
|
1110 *iFont, |
|
1111 *text, |
|
1112 CFont::TMeasureTextInput::EFVisualOrder ); |
|
1113 |
|
1114 TPoint tl( posInfo.iEdge ); |
|
1115 |
|
1116 if ( AknLayoutUtils::LayoutMirrored() ) |
|
1117 { |
|
1118 // move top left x to end of text |
|
1119 tl.iX -= textWidth; |
|
1120 } |
|
1121 |
|
1122 tl.iY -= iFont->FontMaxAscent(); |
|
1123 TPoint br( tl.iX + textWidth, tl.iY + iFont->FontMaxHeight() ); |
|
1124 |
|
1125 TRect rect( Rect() ); |
|
1126 |
|
1127 while ( ( tl.iX < rect.iTl.iX || br.iX > rect.iBr.iX ) |
|
1128 && !aRegion.CheckError() ) |
|
1129 { |
|
1130 // Link on multiple lines |
|
1131 |
|
1132 tl.iX = Max( rect.iTl.iX, tl.iX ); |
|
1133 br.iX = Min( br.iX, rect.iBr.iX ); |
|
1134 linkRect.SetRect( tl, br ); |
|
1135 aRegion.AddRect( linkRect ); |
|
1136 |
|
1137 TPtrC remainder( text->Mid( posSpec.iPos - aLink.StartPos() ) ); |
|
1138 TInt numChars = iFont->TextCount( remainder, |
|
1139 linkRect.Width() ); |
|
1140 posSpec.iPos += numChars; |
|
1141 remainder.Set( remainder.Mid( numChars) ); |
|
1142 |
|
1143 if ( TextView()->FindDocPosL( posSpec, posInfo ) ) |
|
1144 { |
|
1145 textWidth = AknBidiTextUtils::MeasureTextBoundsWidth( |
|
1146 *iFont, |
|
1147 remainder, |
|
1148 CFont::TMeasureTextInput::EFVisualOrder ); |
|
1149 |
|
1150 tl = posInfo.iEdge; |
|
1151 |
|
1152 if ( AknLayoutUtils::LayoutMirrored() ) |
|
1153 { |
|
1154 // move top left x to end of text |
|
1155 tl.iX -= textWidth; |
|
1156 } |
|
1157 |
|
1158 tl.iY -= iFont->FontMaxAscent(); |
|
1159 br.SetXY( tl.iX + textWidth, tl.iY + iFont->FontMaxHeight() ); |
|
1160 } |
|
1161 } |
|
1162 |
|
1163 linkRect.SetRect( tl, br ); |
|
1164 aRegion.AddRect( linkRect ); |
|
1165 |
|
1166 CleanupStack::PopAndDestroy( text ); |
|
1167 } |
|
1168 } |
|
1169 |
|
1170 // ----------------------------------------------------------------------------- |
|
1171 // CESMRRichTextViewer::ChangeMiddleSoftkeyL |
|
1172 // ----------------------------------------------------------------------------- |
|
1173 // |
|
1174 void CESMRRichTextViewer::ChangeMiddleSoftkeyL( const CESMRRichTextLink& aLink ) |
|
1175 { |
|
1176 FUNC_LOG; |
|
1177 CESMRField* field = static_cast< CESMRField* >( Parent() ); |
|
1178 |
|
1179 if ( field ) |
|
1180 { |
|
1181 field->ChangeMiddleSoftKeyL( aLink.MSKCommand(), aLink.MSKText() ); |
|
1182 } |
|
1183 } |
|
1184 |
|
1185 // ----------------------------------------------------------------------------- |
|
1186 // CESMRRichTextViewer::UpdateViewL |
|
1187 // ----------------------------------------------------------------------------- |
|
1188 // |
|
1189 void CESMRRichTextViewer::UpdateViewL( const TKeyEvent &aKeyEvent ) |
|
1190 { |
|
1191 FUNC_LOG; |
|
1192 const CESMRRichTextLink* selectedLink = GetSelectedLink(); |
|
1193 |
|
1194 if( !selectedLink ) |
|
1195 { |
|
1196 return; |
|
1197 } |
|
1198 |
|
1199 RRegion linkRegion; |
|
1200 CleanupClosePushL( linkRegion ); |
|
1201 |
|
1202 GetLinkAreaL( linkRegion, *selectedLink ); |
|
1203 TRect linkRect = linkRegion.BoundingRect(); |
|
1204 |
|
1205 CleanupStack::PopAndDestroy( &linkRegion ); |
|
1206 |
|
1207 TRect viewableAreaRect = iObserver->ViewableAreaRect(); |
|
1208 |
|
1209 |
|
1210 switch ( aKeyEvent.iCode ) |
|
1211 { |
|
1212 case EKeyLeftArrow: |
|
1213 case EKeyUpArrow: |
|
1214 { |
|
1215 if( linkRect.iTl.iY < viewableAreaRect.iTl.iY ) |
|
1216 { |
|
1217 // Move fields down |
|
1218 iObserver->RePositionFields( |
|
1219 -( linkRect.iTl.iY - viewableAreaRect.iTl.iY ) ); |
|
1220 } |
|
1221 |
1196 break; |
1222 break; |
1197 } |
1223 } |
1198 } |
1224 case EKeyRightArrow: |
1199 |
1225 case EKeyDownArrow: |
1200 if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) |
1226 { |
1201 { |
1227 if( linkRect.iBr.iY > viewableAreaRect.iBr.iY ) |
1202 if ( linkTapped ) |
1228 { |
1203 { |
1229 // Move fields up |
1204 // tactile feedback |
1230 iObserver->RePositionFields( |
1205 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
1231 -( linkRect.iBr.iY - viewableAreaRect.iBr.iY ) ); |
1206 if ( feedback ) |
1232 } |
1207 { |
1233 break; |
1208 feedback->InstantFeedback( this, ETouchFeedbackBasic ); |
1234 } |
1209 } |
1235 default: |
1210 |
1236 break; |
1211 TPointerEvent pointerEvent = aPointerEvent; |
1237 } |
1212 pointerEvent.iParentPosition = pointerEvent.iPosition |
1238 } |
1213 + DrawableWindow()->AbsPosition(); |
1239 |
1214 iLongTapDetector->PointerEventL( pointerEvent ); |
|
1215 HighlightLink( *link ); |
|
1216 if ( Parent() ) |
|
1217 { |
|
1218 Parent()->DrawDeferred(); |
|
1219 } |
|
1220 else |
|
1221 { |
|
1222 DrawDeferred(); |
|
1223 } |
|
1224 } |
|
1225 } |
|
1226 else |
|
1227 { |
|
1228 TPointerEvent pointerEvent = aPointerEvent; |
|
1229 pointerEvent.iParentPosition = pointerEvent.iPosition |
|
1230 + DrawableWindow()->AbsPosition(); |
|
1231 iLongTapDetector->PointerEventL( pointerEvent ); |
|
1232 |
|
1233 if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) |
|
1234 { |
|
1235 if ( linkTapped && !iActionMenuOpen ) |
|
1236 { |
|
1237 // tapped highlighted field, execute action |
|
1238 LinkSelectedL(); |
|
1239 } |
|
1240 } |
|
1241 } |
|
1242 } |
|
1243 |
|
1244 // ----------------------------------------------------------------------------- |
|
1245 // CESMRRichTextViewer::HandleLongTapEventL |
|
1246 // ----------------------------------------------------------------------------- |
|
1247 // |
|
1248 void CESMRRichTextViewer::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/, |
|
1249 const TPoint& /*aPenEventScreenLocation*/ ) |
|
1250 { |
|
1251 if ( !iActionMenuOpen ) |
|
1252 { |
|
1253 LinkSelectedL(); |
|
1254 } |
|
1255 } |
|
1256 // EOF |
1240 // EOF |
1257 |
1241 |