226 |
226 |
227 NONSHARABLE_CLASS(CEikEdwinFepSupport) : public CBase, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, public TCoeInputCapabilities::MCoeFepSpecificExtensions |
227 NONSHARABLE_CLASS(CEikEdwinFepSupport) : public CBase, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, public TCoeInputCapabilities::MCoeFepSpecificExtensions |
228 { |
228 { |
229 friend class CEikEdwin; |
229 friend class CEikEdwin; |
230 public: |
230 public: |
|
231 // The length of text window |
|
232 const static TInt KMaxSegmentLength = 10000; |
|
233 // The threshold for text window position change |
|
234 const static TInt KSegmentUpdateTrigger = 100; |
|
235 |
231 static CEikEdwinFepSupport* New(CEikEdwin& aEdwin); |
236 static CEikEdwinFepSupport* New(CEikEdwin& aEdwin); |
232 virtual ~CEikEdwinFepSupport(); |
237 virtual ~CEikEdwinFepSupport(); |
233 TBool IsHandledByFepL(TPointerEvent::TType aType, TUint aModifiers, TInt aDocumentPosition); |
238 TBool IsHandledByFepL(TPointerEvent::TType aType, TUint aModifiers, TInt aDocumentPosition); |
234 /** |
239 /** |
235 * Set the input capabilities in the edwin fep support object. A copy of the input capabilities |
240 * Set the input capabilities in the edwin fep support object. A copy of the input capabilities |
241 const TCoeInputCapabilities* InputCapabilities() const; |
246 const TCoeInputCapabilities* InputCapabilities() const; |
242 void ConstructStateHolder(); |
247 void ConstructStateHolder(); |
243 // from MCoeFepAwareTextEditor_Extension1 |
248 // from MCoeFepAwareTextEditor_Extension1 |
244 void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid); |
249 void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid); |
245 CState* State(TUid aTypeSafetyUid); // this function does *not* transfer ownership |
250 CState* State(TUid aTypeSafetyUid); // this function does *not* transfer ownership |
246 |
251 |
|
252 // New functions for Touch Input sync performance improvement. A sliding window method is used |
|
253 // here to show only part of text of editor to Touch Input, so the text sync between Touch input and |
|
254 // editor can be faster. |
|
255 /** |
|
256 * To update start position of text window according to cursor position. The cursor position has to |
|
257 * be in the visible text window. |
|
258 */ |
|
259 void UpdateDocPosOffsetL( TInt aCursorPos ); |
|
260 |
|
261 /** |
|
262 * To check if FEP wants to get information of whole text, not the text window. |
|
263 */ |
|
264 TBool FepRequireWholeTextData() const; |
|
265 |
247 private: |
266 private: |
248 enum TPointerState |
267 enum TPointerState |
249 { |
268 { |
250 EPointerIsUp, |
269 EPointerIsUp, |
251 EPointerIsDownStartingInsideInlineText, |
270 EPointerIsDownStartingInsideInlineText, |
635 #endif |
654 #endif |
636 } |
655 } |
637 |
656 |
638 TInt CEikEdwinFepSupport::DocumentLengthForFep() const |
657 TInt CEikEdwinFepSupport::DocumentLengthForFep() const |
639 { |
658 { |
|
659 // If the length between text window start position and text end is shorter |
|
660 // than length of text window, return the short length, otherwise return |
|
661 // text window length. |
|
662 if ( !FepRequireWholeTextData() && iEdwin.TextLength() > KMaxSegmentLength ) |
|
663 { |
|
664 TInt lengthToEnd( iEdwin.TextLength() - iDocPosOffset ); |
|
665 if ( lengthToEnd < KMaxSegmentLength ) |
|
666 { |
|
667 return lengthToEnd; |
|
668 } |
|
669 return KMaxSegmentLength; |
|
670 } |
640 return iEdwin.TextLength(); |
671 return iEdwin.TextLength(); |
641 } |
672 } |
642 |
673 |
643 TInt CEikEdwinFepSupport::DocumentMaximumLengthForFep() const |
674 TInt CEikEdwinFepSupport::DocumentMaximumLengthForFep() const |
644 { |
675 { |
|
676 // return the length between textlimit and text window start position |
|
677 if ( !FepRequireWholeTextData() && KMaxSegmentLength < iEdwin.iTextLimit ) |
|
678 { |
|
679 return iEdwin.iTextLimit - iDocPosOffset; |
|
680 } |
645 return iEdwin.iTextLimit; |
681 return iEdwin.iTextLimit; |
646 } |
682 } |
647 |
683 |
648 void CEikEdwinFepSupport::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection) |
684 void CEikEdwinFepSupport::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection) |
649 { |
685 { |
650 TCursorSelection select( aCursorSelection.iCursorPos, aCursorSelection.iAnchorPos ); |
686 // if text window is enabled, the pos of parameter selection are relative to |
651 iEdwin.HandleSelectionForSmiley( select ); |
687 // text window start position, so convert them back to actual doc pos. |
652 iEdwin.iTextView->SetSelectionL( select ); |
688 TInt cursorPos( aCursorSelection.iCursorPos ); |
653 iEdwin.UpdateVertScrollBarThumbL(); |
689 TInt anchorPos( aCursorSelection.iAnchorPos ); |
654 iEdwin.UpdateHorizScrollBarThumb(); |
690 TInt textLength( iEdwin.TextLength() ); |
655 iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventNavigation ); |
691 if ( !FepRequireWholeTextData() ) |
|
692 { |
|
693 cursorPos += iDocPosOffset; |
|
694 anchorPos += iDocPosOffset; |
|
695 cursorPos = cursorPos > textLength ? textLength : cursorPos; |
|
696 anchorPos = anchorPos > textLength ? textLength : anchorPos; |
|
697 if ( cursorPos != anchorPos ) |
|
698 { |
|
699 TCursorSelection select( iEdwin.Selection() ); |
|
700 if ( ( anchorPos == iDocPosOffset || anchorPos == iDocPosOffset + |
|
701 KMaxSegmentLength ) && anchorPos >= select.LowerPos() && |
|
702 anchorPos <= select.HigherPos() ) |
|
703 { |
|
704 anchorPos = cursorPos > anchorPos ? select.LowerPos() : |
|
705 select.HigherPos(); |
|
706 } |
|
707 } |
|
708 } |
|
709 // Selection position can not be in smiley code string, so check if |
|
710 // the position needs to be changed. |
|
711 if ( iEdwin.IsSmileyEnabled() ) |
|
712 { |
|
713 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
|
714 TInt oldPos = ( cursorPos == anchorPos ) ? iEdwin.CursorPos() : anchorPos; |
|
715 smiley->HandleSetCursor( oldPos, cursorPos ); |
|
716 if ( aCursorSelection.iCursorPos == aCursorSelection.iAnchorPos ) |
|
717 { |
|
718 anchorPos = cursorPos; |
|
719 } |
|
720 else |
|
721 { |
|
722 smiley->HandleSetCursor( cursorPos, anchorPos ); |
|
723 } |
|
724 } |
|
725 iEdwin.SetSelectionL( cursorPos, anchorPos ); |
|
726 // Cursor pos is changed, so update text window position. |
|
727 UpdateDocPosOffsetL( cursorPos ); |
|
728 iEdwin.ReportEdwinEventL(MEikEdwinObserver::EEventNavigation); |
656 } |
729 } |
657 |
730 |
658 void CEikEdwinFepSupport::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const |
731 void CEikEdwinFepSupport::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const |
659 { |
732 { |
660 aCursorSelection=iEdwin.Selection(); |
733 aCursorSelection=iEdwin.Selection(); |
|
734 // To use text window, FEP can not access text view of editor directly but |
|
735 // FEP needs to know some information which can not be provided by current |
|
736 // interface. So use below method to transfer the information to FEP. |
|
737 CAknEdwinState* state( iEdwin.EditorState() ); |
|
738 if ( state ) |
|
739 { |
|
740 TInt flag( state->Flags() ); |
|
741 TTmDocPos docPos; |
|
742 iEdwin.TextView()->GetCursorPos( docPos ); |
|
743 if ( docPos.iLeadingEdge ) |
|
744 { |
|
745 flag |= EAknEditorFlagCursorLedingEdge; |
|
746 } |
|
747 else |
|
748 { |
|
749 flag &= ~EAknEditorFlagCursorLedingEdge; |
|
750 } |
|
751 state->SetFlags( flag ); |
|
752 } |
|
753 // If text window is enabled, convert the actual doc pos to relative doc pos. |
|
754 if ( !FepRequireWholeTextData() ) |
|
755 { |
|
756 if ( aCursorSelection.iAnchorPos < iDocPosOffset ) |
|
757 { |
|
758 aCursorSelection.iAnchorPos = iDocPosOffset; |
|
759 } |
|
760 else if ( aCursorSelection.iAnchorPos > iDocPosOffset + KMaxSegmentLength ) |
|
761 { |
|
762 aCursorSelection.iAnchorPos = iDocPosOffset + KMaxSegmentLength; |
|
763 } |
|
764 aCursorSelection.iCursorPos -= iDocPosOffset; |
|
765 aCursorSelection.iAnchorPos -= iDocPosOffset; |
|
766 } |
661 } |
767 } |
662 |
768 |
663 void CEikEdwinFepSupport::GetEditorContentForFep(TDes& aEditorContent,TInt aDocumentPosition,TInt aLengthToRetrieve) const |
769 void CEikEdwinFepSupport::GetEditorContentForFep(TDes& aEditorContent,TInt aDocumentPosition,TInt aLengthToRetrieve) const |
664 { |
770 { |
|
771 // If text window is enabled, convert relative doc pos to actual doc pos. |
|
772 if ( !FepRequireWholeTextData() ) |
|
773 { |
|
774 aDocumentPosition += iDocPosOffset; |
|
775 } |
665 TInt length( Min( aLengthToRetrieve, iEdwin.TextLength() - aDocumentPosition ) ); |
776 TInt length( Min( aLengthToRetrieve, iEdwin.TextLength() - aDocumentPosition ) ); |
|
777 if ( !FepRequireWholeTextData() ) |
|
778 { |
|
779 length = Min( length, KMaxSegmentLength ); |
|
780 } |
666 iEdwin.iText->Extract( aEditorContent, aDocumentPosition, length ); |
781 iEdwin.iText->Extract( aEditorContent, aDocumentPosition, length ); |
667 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
782 CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley ); |
668 if ( smiley && smiley->HasSmileyIconsInText() ) |
783 if ( smiley && smiley->HasSmileyIconsInText() ) |
669 { |
784 { |
670 CAknEdwinState* state( iEdwin.EditorState() ); |
785 CAknEdwinState* state( iEdwin.EditorState() ); |
708 STATIC_CAST(CGlobalText*,iEdwin.iText)->GetCharFormat(aFormat,notUsed,aDocumentPosition,(aDocumentPosition==iEdwin.TextLength())? 0: 1); |
823 STATIC_CAST(CGlobalText*,iEdwin.iText)->GetCharFormat(aFormat,notUsed,aDocumentPosition,(aDocumentPosition==iEdwin.TextLength())? 0: 1); |
709 } |
824 } |
710 |
825 |
711 void CEikEdwinFepSupport::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine,TInt& aHeight,TInt& aAscent,TInt aDocumentPosition) const |
826 void CEikEdwinFepSupport::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine,TInt& aHeight,TInt& aAscent,TInt aDocumentPosition) const |
712 { |
827 { |
|
828 // If text window is enabled, convert relative doc pos to actual doc pos. |
|
829 aDocumentPosition += iDocPosOffset; |
713 aDocumentPosition %= ( iEdwin.iText->DocumentLength() + 1 ); |
830 aDocumentPosition %= ( iEdwin.iText->DocumentLength() + 1 ); |
714 iEdwin.iTextView->DocPosToXyPosL(aDocumentPosition,aLeftSideOfBaseLine); |
831 iEdwin.iTextView->DocPosToXyPosL(aDocumentPosition,aLeftSideOfBaseLine); |
715 aLeftSideOfBaseLine+=iEdwin.DrawableWindow()->InquireOffset(iEdwin.iCoeEnv->RootWin()); // make position "absolute" (i.e. not relative to the window that iEdwin is using) - note that *any* group window can be passed into InquireOffset to return the desired result, it doesn't have to be an ancestor of the window being used by iEdwin (i.e. this line of code does *not* make the assumption that iEdwin is (even indirectly) attached to iCoeEnv->RootWin()) |
832 aLeftSideOfBaseLine+=iEdwin.DrawableWindow()->InquireOffset(iEdwin.iCoeEnv->RootWin()); // make position "absolute" (i.e. not relative to the window that iEdwin is using) - note that *any* group window can be passed into InquireOffset to return the desired result, it doesn't have to be an ancestor of the window being used by iEdwin (i.e. this line of code does *not* make the assumption that iEdwin is (even indirectly) attached to iCoeEnv->RootWin()) |
716 iEdwin.iLayout->GetCharacterHeightAndAscentL(aDocumentPosition,aHeight,aAscent); |
833 iEdwin.iLayout->GetCharacterHeightAndAscentL(aDocumentPosition,aHeight,aAscent); |
717 } |
834 } |
876 |
993 |
877 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_2() |
994 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_2() |
878 { |
995 { |
879 } |
996 } |
880 |
997 |
|
998 // Update start position of text window, when cursor pos is out of current |
|
999 // text window or it is in trigger range, the text window position needs to |
|
1000 // be changed and notify FEP the text change. |
|
1001 void CEikEdwinFepSupport::UpdateDocPosOffsetL( TInt aCursorPos ) |
|
1002 { |
|
1003 if ( FepRequireWholeTextData() ) |
|
1004 { |
|
1005 return; |
|
1006 } |
|
1007 if ( iEdwin.TextLength() > KMaxSegmentLength ) |
|
1008 { |
|
1009 TInt halfSegment( KMaxSegmentLength / 2 ); |
|
1010 TBool validDocPosOffset( iDocPosOffset >= 0 && aCursorPos > iDocPosOffset && |
|
1011 aCursorPos - iDocPosOffset < KMaxSegmentLength ); |
|
1012 TBool cursorInHead( validDocPosOffset && |
|
1013 aCursorPos - iDocPosOffset < KSegmentUpdateTrigger ); |
|
1014 TBool cursorInTail( validDocPosOffset && |
|
1015 iDocPosOffset + KMaxSegmentLength - aCursorPos < KSegmentUpdateTrigger && |
|
1016 iDocPosOffset + KMaxSegmentLength < iEdwin.TextLength() ); |
|
1017 if ( !validDocPosOffset || cursorInHead || cursorInTail ) |
|
1018 { |
|
1019 if ( iEdwin.TextLength() - aCursorPos < halfSegment ) |
|
1020 { |
|
1021 iDocPosOffset = iEdwin.TextLength() - KMaxSegmentLength; |
|
1022 } |
|
1023 else |
|
1024 { |
|
1025 iDocPosOffset = aCursorPos - halfSegment; |
|
1026 iDocPosOffset = iDocPosOffset >= 0 ? iDocPosOffset : 0; |
|
1027 } |
|
1028 static_cast<CAknEdwinState*>( State( KNullUid ) )->ReportAknEdStateEventL( |
|
1029 MAknEdStateObserver::EAknCursorPositionChanged ); |
|
1030 } |
|
1031 } |
|
1032 } |
|
1033 |
|
1034 // Check if FEP set the flag to indicate it wants to get information of whole |
|
1035 // text, not the text window. |
|
1036 TBool CEikEdwinFepSupport::FepRequireWholeTextData() const |
|
1037 { |
|
1038 CAknEdwinState* state( static_cast<CAknEdwinState*>( |
|
1039 const_cast<CEikEdwinFepSupport*>( this )->State(KNullUid) ) ); |
|
1040 return ( state->Flags() & EAknEditorFlagNeedWholeTextData ); |
|
1041 } |
881 |
1042 |
882 // |
1043 // |
883 // CEikEdwinExtension |
1044 // CEikEdwinExtension |
884 // |
1045 // |
885 CEikEdwin::CEikEdwinExtension* CEikEdwin::CEikEdwinExtension::NewL(CEikEdwin* aEdwin) |
1046 CEikEdwin::CEikEdwinExtension* CEikEdwin::CEikEdwinExtension::NewL(CEikEdwin* aEdwin) |