diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknPhoneNumberEditor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/AknPhoneNumberEditor.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,1298 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "AknPhoneNumberEditor.h" +#include "AknPhedView.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static const TInt KPlainTextPos = 0; + +typedef CArrayFixFlat CFormatArray; + +NONSHARABLE_CLASS( CAknPhoneNumberEditorExtension ) : public CBase, + public MObjectProvider + { + public: + CAknPhoneNumberEditorExtension(); + ~CAknPhoneNumberEditorExtension(); + + protected: // from MObjectProvider + TTypeUid::Ptr MopSupplyObject( TTypeUid aId ); + + public: + CFormatArray* iFormats; + CAknExtendedInputCapabilities* iExtendedInputCapabilities; + TInt iPointPos; + CAknCcpuSupport* iCcpuSupport; + HBufC* iPasteText; + }; + +CAknPhoneNumberEditorExtension::CAknPhoneNumberEditorExtension() + { + iFormats = NULL; + iExtendedInputCapabilities = NULL; + } + + +CAknPhoneNumberEditorExtension::~CAknPhoneNumberEditorExtension() + { + delete iPasteText; + delete iFormats; + delete iExtendedInputCapabilities; + delete iCcpuSupport; + } + +// --------------------------------------------------------- +// CAknPhoneNumberEditorExtension::MopSupplyObject +// --------------------------------------------------------- +// +TTypeUid::Ptr CAknPhoneNumberEditorExtension::MopSupplyObject( TTypeUid aId ) + { + if ( aId.iUid == CAknExtendedInputCapabilities::ETypeId ) + { + return aId.MakePtr( iExtendedInputCapabilities ); + } + + return TTypeUid::Null(); + } + +enum TAknPhedFlags + { + ERedrawAll, + EInlineEditInProgress, + EFeaturePhoneNumberGrouping + }; + +enum TAknPhedControlPanic + { + ELeaveInStateChange, + EIncorrectInlineEditState + }; + +void PhedControlPanic( TAknPhedControlPanic aPanic ) + { + _LIT( KAknPhedControl,"AknPhedControl" ); + User::Panic( KAknPhedControl, aPanic ); + } + + +EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat() + { + Mem::FillZ( this, sizeof( *this ) ); + } + +EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat( TResourceReader& aReader ) + { + Mem::FillZ( this, sizeof( *this ) ); + + TInt top = aReader.ReadInt16(); + TInt left = aReader.ReadInt16(); + TInt bottom = aReader.ReadInt16(); + TInt right = aReader.ReadInt16(); + iOuterRect = TRect( TPoint( left, top ), TPoint( right, bottom ) ); + + iBorderType = aReader.ReadInt32(); + iNumLines = aReader.ReadInt16(); + iBottomBaselineOffset = aReader.ReadInt16(); + iBaselineSeparation = aReader.ReadInt16(); + iFont = AknLayoutUtils::FontFromId( aReader.ReadInt16() ); + } + +EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat( const TRect& aOuterRect, TInt aBorderType, + TInt aNumLines, TInt aBottomBaselineOffset, TInt aBaselineSeparation, const CFont* aFont ) + : iOuterRect( aOuterRect ), iBorderType( aBorderType ), iNumLines( aNumLines ), + iBottomBaselineOffset( aBottomBaselineOffset ), iBaselineSeparation( aBaselineSeparation ), + iFont( aFont ) + { + } + + + +EXPORT_C CAknPhoneNumberEditor::CAknPhoneNumberEditor() + { + iFlags.Set( ERedrawAll ); + AKNTASHOOK_ADD( this, "CAknPhoneNumberEditor" ); + } + +EXPORT_C CAknPhoneNumberEditor::~CAknPhoneNumberEditor() + { + AKNTASHOOK_REMOVE(); + delete iView; + delete iModel; + delete iExtension; + delete iFepState; + } + +EXPORT_C void CAknPhoneNumberEditor::ConstructFromResourceL( TResourceReader& aReader ) + { + TInt maxChars = aReader.ReadInt16(); + TInt maxLines = aReader.ReadInt16(); + HBufC* truncation = aReader.ReadHBufCL(); + CleanupStack::PushL( truncation ); + TInt formatCount = aReader.ReadInt16(); + ConstructL( maxChars, maxLines, formatCount, *truncation ); + CleanupStack::PopAndDestroy(); // truncation + + for ( TInt ii=0; iiiExtendedInputCapabilities->Capabilities(); + cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB; + iExtension->iExtendedInputCapabilities->SetCapabilities( cap ); + + } + +EXPORT_C void CAknPhoneNumberEditor::ConstructL( TInt aMaxChars, + TInt aMaxLines, + TInt aMaxFormats, + const TDesC& aTruncation ) + { + iExtension = new(ELeave) CAknPhoneNumberEditorExtension(); + iExtension->iFormats = new(ELeave) CFormatArray( 1 ); + iExtension->iFormats->ResizeL( aMaxFormats ); + iModel = CAknPhedModel::NewL( aMaxChars ); + iView = new(ELeave) CAknPhedView( iModel ); + iView->ConstructL( aMaxLines, aTruncation ); + iView->SetWindows( &iEikonEnv->RootWin(), DrawableWindow() ); + iView->SetChangeReceiver( this ); + CreateFepStateL(); + iExtension->iExtendedInputCapabilities = CAknExtendedInputCapabilities::NewL(); + + TUint cap = iExtension->iExtendedInputCapabilities->Capabilities(); + cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB; + iExtension->iExtendedInputCapabilities->SetCapabilities( cap ); + + EnableDragEvents(); + EnableCcpuSupportL( ETrue ); + } + +EXPORT_C void CAknPhoneNumberEditor::AddFormat( const TFormat& aFormat ) + { + iExtension->iFormats->At( iNumFormats++ ) = aFormat; + } + +EXPORT_C TInt CAknPhoneNumberEditor::CountFormats() const + { + return iNumFormats; + } + +EXPORT_C CAknPhoneNumberEditor::TFormat& CAknPhoneNumberEditor::Format( TInt aFormatIndex ) const + { + return iExtension->iFormats->At( aFormatIndex ); + } + +EXPORT_C TInt CAknPhoneNumberEditor::CurrentFormatIndex() const + { + return iCurrentFormatIndex; + } + +EXPORT_C TBool CAknPhoneNumberEditor::WouldTextFitInFormat( TInt aFormatIndex ) const + { + TFormat& format = Format( aFormatIndex ); + + // create a line and see how many times the text takes to fit it. + TAknPhedViewLine line; + line.SetModel( iModel ); + line.SetFormat( format.iFont, Border().InnerRect( format.iOuterRect ), + format.iBaselineSeparation ); + + TInt count = 1; + line.SetRightPos( 0 ); + if ( line.LeftPos() > 0 ) + { + while ( line.LeftPos() != iModel->Length() ) + { + line.SetRightPos( line.LeftPos() ); + line.SetRightLine( &line ); + count++; + } + } + return count <= format.iNumLines; + } + +EXPORT_C void CAknPhoneNumberEditor::SetFormat( TInt aFormatIndex ) + { + iCurrentFormatIndex = aFormatIndex; + TFormat& format = Format( aFormatIndex ); + SetBorder( format.iBorderType ); + SetRect( format.iOuterRect ); + } + +EXPORT_C TPtrC CAknPhoneNumberEditor::Text( TInt aFrom ) const + { + return iModel->UnFormattedText(aFrom); + } + +EXPORT_C void CAknPhoneNumberEditor::SetText( const TDesC& aText ) + { + iModel->SetText( aText ); + } + +void CAknPhoneNumberEditor::DrawChanges() + { + // DrawChanges actually draws everything. Flicker is not + // a problem now. + DrawDeferred(); + } + +EXPORT_C void CAknPhoneNumberEditor::SizeChanged() + { + TFormat& format = Format( CurrentFormatIndex() ); + TPoint pt = DrawableWindow()->Position(); + TSize size = DrawableWindow()->Size(); + TRect rect = Rect(); + TInt offset = rect.iBr.iX - ( pt.iX + size.iWidth ); + if ( offset > 0 ) + { + rect.iTl.iX -= offset; + rect.iBr.iX = pt.iX + size.iWidth; + SetRect( rect ); + } + iView->SetFormat( format.iNumLines, format.iFont, Border().InnerRect( Rect() ), + format.iBottomBaselineOffset, format.iBaselineSeparation); + } + +EXPORT_C TKeyResponse CAknPhoneNumberEditor::OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + if ( aType != EEventKey ) + return EKeyWasNotConsumed; + + TKeyResponse resp = EKeyWasConsumed; + + TInt cursorX = iView->CursorPosition().iX; + TBool targetPosUsed = EFalse; + + // when user inputs digit, the screen should be drawn, otherwise + // we need to check whether the screen will be drawn by view + TBool needDraw = EFalse; + + // record cursorline before cursor moves for preventing flicker + TInt cursorLinePre = iView->CursorLine(); + + // record leftpos of current line to help to decide how the + // cursor moves between different lines. + const CAknPhedViewLineArray* lineArray = iView->LineArray(); + TInt leftPosPre = lineArray->At( cursorLinePre ).LeftPos(); + + // phone number editor does not respond to shift key. + // The code is still here because it may need to be turned back on if + // the phone number editor needs to support selection, cut, copy and paste. + TBool shift = ( ( aKeyEvent.iModifiers & EModifierShift ) == EModifierShift ); + TBool cousorChanged = EFalse; + switch(aKeyEvent.iCode) + { + case EKeyLeftArrow: + if (shift) + iModel->SelectLeft(); + else + iModel->CursorLeft(); + cousorChanged = ETrue; + break; + + case EKeyRightArrow: + if (shift) + iModel->SelectRight(); + else + iModel->CursorRight(); + cousorChanged = ETrue; + break; + + case EKeyUpArrow: + if ( shift ) + targetPosUsed = iView->SelectUp( TargetCursorPos( cursorX ) ); + else + targetPosUsed = iView->CursorUp( TargetCursorPos( cursorX ) ); + cousorChanged = ETrue; + break; + + case EKeyDownArrow: + if ( shift ) + targetPosUsed = iView->SelectDown( TargetCursorPos( cursorX ) ); + else + targetPosUsed = iView->CursorDown( TargetCursorPos( cursorX ) ); + cousorChanged = ETrue; + break; + + case EKeyBackspace: + iModel->DeleteLeft(); + needDraw = ETrue; + break; + + default: + if ( aKeyEvent.iCode < ENonCharacterKeyBase ) + { + iModel->Insert( TText( aKeyEvent.iCode ) ); + needDraw = ETrue; + } + else + resp = EKeyWasNotConsumed; + break; + } + + if ( iExtension->iExtendedInputCapabilities ) + { + iExtension->iExtendedInputCapabilities->ReportEventL( + CAknExtendedInputCapabilities:: + MAknEventObserver::EControlContentUpdatedInternally, + NULL ); + } + + if ( shift && iExtension->iCcpuSupport ) + { + iExtension->iCcpuSupport->HandleSelectionChangeL(); + } + if ( cousorChanged ) + { + ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ); + } + // see if we want to remember the old cursor X position + if ( targetPosUsed ) + { + if ( iTargetCursorPos == CAknPhedView::KNoPos ) + iTargetCursorPos = cursorX; + } + else + iTargetCursorPos = CAknPhedView::KNoPos; + + // To prevent flicker by avoiding drawing screen multi-times in short + // time. When cursor moves between two lines that are both shown at + // the same time, the screen will be drawn by CAknPhedView, and the + // DrawNow need not be called, otherwise the screen should be drawn here. + TInt leftPosPost = lineArray->At( iView->CursorLine() ).LeftPos(); + if ( needDraw || + Abs( leftPosPost - leftPosPre ) != lineArray->At( 0 ).LineWidth() ) + { + DrawNow(); + } + ReportEventL( MCoeControlObserver::EEventStateChanged ); + return resp; + } + +EXPORT_C TSize CAknPhoneNumberEditor::MinimumSize() + { + return iView->Rect().Size(); + } + +EXPORT_C void CAknPhoneNumberEditor::FocusChanged( TDrawNow aDrawNow ) + { + if ( iView ) + { + if ( IsFocused() ) + iView->EnableCursor(); + else + iView->DisableCursor(); + } + + if ( iExtension->iCcpuSupport ) + { + TRAP_IGNORE( iExtension->iCcpuSupport->HandleFocusChangeL() ); + } + if ( ! IsFocused() ) + { + TRAP_IGNORE( ReportAknEdStateEventL( MAknEdStateObserver::EAknSyncEdwinState ) ); + } + if ( aDrawNow ) + DrawNow(); + } + +EXPORT_C void CAknPhoneNumberEditor::Draw( const TRect& aRect ) const + { + CEikBorderedControl::Draw( aRect ); + iView->Draw( SystemGc(), iFlags[ERedrawAll], this ); + } + +EXPORT_C TCoeInputCapabilities CAknPhoneNumberEditor::InputCapabilities() const + { + if ( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) ) + { + TCoeInputCapabilities inputCaps( + TCoeInputCapabilities::EWesternAlphabetic | + TCoeInputCapabilities::ENavigation, + const_cast( this ), NULL ); + + // Voip-enabled phone editor wants to use edit-key style hash key mode selection. + iExtension->iExtendedInputCapabilities->SetEditorType( + CAknExtendedInputCapabilities::EPhoneNumberEditor ); + iExtension->iExtendedInputCapabilities->SetCapabilities( + CAknExtendedInputCapabilities::EForceHashKeySelectionStatusFlagOff | + CAknExtendedInputCapabilities::EForceEditSubmenuStatusFlagOff ); + inputCaps.SetObjectProvider( + const_cast( iExtension ) ); + + return inputCaps; + } + else if ( FeatureManager::FeatureSupported( KFeatureIdCsVideoTelephony ) ) + { + TCoeInputCapabilities inputCaps( + TCoeInputCapabilities::EDialableCharacters | + TCoeInputCapabilities::ENavigation, + const_cast(this), NULL); + + iExtension->iExtendedInputCapabilities->SetEditorType( + CAknExtendedInputCapabilities::EPhoneNumberEditor ); + inputCaps.SetObjectProvider( + const_cast( iExtension ) ); + + return inputCaps; + } + return TCoeInputCapabilities( 0, const_cast(this), NULL ); + } + +EXPORT_C TInt CAknPhoneNumberEditor::TextLength() const + { + return iModel->Length(); + } + +EXPORT_C TInt CAknPhoneNumberEditor::CursorPos() const + { + return iModel->CursorPosition(); + } + +EXPORT_C TInt CAknPhoneNumberEditor::SelectionLength() const + { + return iModel->SelectionWidth(); + } + +EXPORT_C TCursorSelection CAknPhoneNumberEditor::Selection() const + { + return TCursorSelection( iModel->CursorPosition(), iModel->AnchorPosition() ); + } + +EXPORT_C void CAknPhoneNumberEditor::ClearSelectionL() + { + if ( iModel->SelectionExists() ) + iModel->DeleteLeft(); + } + +EXPORT_C void CAknPhoneNumberEditor::SetSelectionL( TInt aCursorPos,TInt aAnchorPos ) + { + iModel->SetRealCursorPosition(aCursorPos); + iModel->SetAnchorPosition( aAnchorPos ); + ReportAknEdStateEventL( + MAknEdStateObserver::EAknCursorPositionChanged ); + } + +EXPORT_C void CAknPhoneNumberEditor::SetCursorPosL( TInt aCursorPos,TBool aSelect ) + { + TInt anchor = iModel->AnchorPosition(); + iModel->SetRealCursorPosition( aCursorPos ); + if ( aSelect ) + iModel->SetAnchorPosition( anchor ); + ReportAknEdStateEventL( + MAknEdStateObserver::EAknCursorPositionChanged ); + } + +EXPORT_C void CAknPhoneNumberEditor::SelectAllL() + { + iModel->SetRealCursorPosition(iModel->Length()); + iModel->SetAnchorPosition( 0 ); + } + +EXPORT_C void CAknPhoneNumberEditor::GetText( TDes& aDes ) const + { + if ( Text().Length() <= aDes.MaxLength() ) + { + aDes = Text(); + } + else + { + aDes = Text().Left( aDes.MaxLength() ); + } + } + +EXPORT_C HBufC* CAknPhoneNumberEditor::GetTextInHBufL() const + { + return Text().AllocL(); + } + +EXPORT_C void CAknPhoneNumberEditor::SetTextL( const TDesC* aDes ) + { + if ( aDes ) + iModel->SetText( *aDes ); + else + iModel->SetText( KNullDesC() ); + } + +EXPORT_C void CAknPhoneNumberEditor::CancelFepTransaction() + { + CCoeFep* fep = iCoeEnv->Fep(); + if ( fep ) + { + fep->CancelTransaction(); + } + } + +EXPORT_C void CAknPhoneNumberEditor::UpdateScrollBarsL() + { + } + +EXPORT_C CEikScrollBarFrame* CAknPhoneNumberEditor::CreateScrollBarFrameL() + { + return NULL; + } + +EXPORT_C TInt CAknPhoneNumberEditor::LineCursorWidth() const + { + return 0; + } + +EXPORT_C TMargins8 CAknPhoneNumberEditor::Margins() const + { + return TMargins8(); + } + +void CAknPhoneNumberEditor::StartFepInlineEditL( + const TDesC& aInitialInlineText, + TInt /*aPositionOfInsertionPointInInlineText*/, + TBool /*aCursorVisibility*/, + const MFormCustomDraw* /*aCustomDraw*/, + MFepInlineTextFormatRetriever& /*aInlineTextFormatRetriever*/, + MFepPointerEventHandlerDuringInlineEdit& /*aPointerEventHandlerDuringInlineEdit*/) + { + if ( aInitialInlineText.Length() == 0 ) + { + // This method used to ignore aInitialInlineText. For improved + // backwards compatibility just do what it did before. + // That is, do not admit a new state of "in inline edit", but with no text. + iFlags.Clear( EInlineEditInProgress ); + } + else + { + // flag is set by a StartFepInlineEdit with text + // or by UpdateFepInlineTextL. Should not get a 2nd start. + __ASSERT_DEBUG( !iFlags[EInlineEditInProgress], + PhedControlPanic(EIncorrectInlineEditState) ); + iModel->Insert( aInitialInlineText[0] ); + iFlags.Set( EInlineEditInProgress ); + DrawChanges(); + } + } + +void CAknPhoneNumberEditor::UpdateFepInlineTextL(const TDesC& aNewInlineText, + TInt /*aPositionOfInsertionPointInInlineText*/ ) + { + if ( iFlags[EInlineEditInProgress] ) + iModel->DeleteLeft(); + + if ( aNewInlineText != KNullDesC ) + { + iModel->Insert( aNewInlineText[0] ); + } + else + { + iModel->DeleteLeft(); + } + + iFlags.Set( EInlineEditInProgress ); + DrawChanges(); + } + +void CAknPhoneNumberEditor::SetInlineEditingCursorVisibilityL(TBool /*aCursorVisibility*/) + { + } + +void CAknPhoneNumberEditor::CancelFepInlineEdit() + { + iFlags.Clear( EInlineEditInProgress ); + } + +TInt CAknPhoneNumberEditor::DocumentLengthForFep() const + { + return iModel->UnFormattedText( 0 ).Length(); + } + +TInt CAknPhoneNumberEditor::DocumentMaximumLengthForFep() const + { + // Lie to FEP about the maximum length, because we handle our own overflow. + return iModel->MaxDisplayLength() + 1; + } + +void CAknPhoneNumberEditor::SetCursorSelectionForFepL( const TCursorSelection& aCursorSelection ) + { + iModel->SetRealCursorPosition( iModel->Uncompensate( aCursorSelection.iCursorPos ) ); + iModel->SetAnchorPosition( iModel->Uncompensate( aCursorSelection.iAnchorPos ) ); + + ReportAknEdStateEventL( + MAknEdStateObserver::EAknCursorPositionChanged ); + DrawNow(); + } + +void CAknPhoneNumberEditor::GetCursorSelectionForFep( TCursorSelection& aCursorSelection ) const + { + aCursorSelection.iCursorPos = iModel->CursorPosition(); + aCursorSelection.iAnchorPos = iModel->AnchorPosition(); + } + +void CAknPhoneNumberEditor::GetEditorContentForFep( TDes& aEditorContent, + TInt aDocumentPosition, + TInt aLengthToRetrieve ) const + { + TInt realLength = Min( iModel->Length() - aDocumentPosition, aLengthToRetrieve ); + if ( iModel->Length() > 0 ) + { + if ( iModel->UnFormattedText( 0 ).Length() >= aDocumentPosition + realLength ) + { + aEditorContent.Copy( + iModel->UnFormattedText( 0 ).Mid( aDocumentPosition, realLength ) ); + } + } + } +void CAknPhoneNumberEditor::GetFormatForFep( TCharFormat& /*aFormat*/, + TInt /*aDocumentPosition*/ ) const + { + } + +void CAknPhoneNumberEditor::GetScreenCoordinatesForFepL( TPoint& /*aLeftSideOfBaseLine*/, + TInt& /*aHeight*/, + TInt& /*aAscent*/, + TInt /*aDocumentPosition*/) const + { + } + +void CAknPhoneNumberEditor::DoCommitFepInlineEditL() + { + iFlags.Clear( EInlineEditInProgress ); + } + +MCoeFepAwareTextEditor_Extension1* CAknPhoneNumberEditor::Extension1(TBool& aSetToTrue) + { + aSetToTrue=ETrue; + return STATIC_CAST( MCoeFepAwareTextEditor_Extension1*, this ); + } + +TInt CAknPhoneNumberEditor::TargetCursorPos( TInt aCurrentPos ) + { + if ( iTargetCursorPos == CAknPhedView::KNoPos ) + return aCurrentPos; + else + return iTargetCursorPos; + } + +void CAknPhoneNumberEditor::StateChanged() + { +#ifdef _DEBUG + TRAPD(err, ReportEventL( MCoeControlObserver::EEventStateChanged ) ); + // phone number editor should never leave. + TRAP_IGNORE(__ASSERT_DEBUG( err == KErrNone, PhedControlPanic( ELeaveInStateChange ) ) ); +#else + TRAP_IGNORE( ReportEventL( MCoeControlObserver::EEventStateChanged ) ); +#endif // _DEBUG + } + +CEikScrollBarFrame* CAknPhoneNumberEditor::CreateScrollBarFrameL(TBool /*aPreAlloc*/) + { + return NULL; + } + +void CAknPhoneNumberEditor::SetStateTransferingOwnershipL( CState* aState, + TUid /*aTypeSafetyUid*/) + { + if ( iFepState ) + delete iFepState; + iFepState=aState; + } + +MCoeFepAwareTextEditor_Extension1::CState* CAknPhoneNumberEditor::State( TUid /*aTypeSafetyUid*/ ) + { + return iFepState; + } + +void CAknPhoneNumberEditor::CreateFepStateL() + { + CAknEdwinState* fepState = new(ELeave) CAknEdwinState(); + iFepState = fepState; + + fepState->SetObjectProvider( this ); + fepState->SetFlags( EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | + EAknEditorFlagNoEditIndicators | EAknEditorFlagSelectionVisible ); + fepState->SetDefaultInputMode( EAknEditorNumericInputMode ); + fepState->SetCurrentInputMode( EAknEditorNumericInputMode ); + fepState->SetPermittedInputModes( EAknEditorNumericInputMode ); + fepState->SetDefaultCase( EAknEditorLowerCase ); + fepState->SetCurrentCase( EAknEditorLowerCase ); + fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase ); + fepState->SetSpecialCharacterTableResourceId( 0 ); + fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap ); + } + +EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Reserved_2() + { + } + +EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_2() + { + } + +EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_3() + { + } + +EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_4() + { + } + + +// --------------------------------------------------------- +// CAknPhoneNumberEditor::ChangeEditorMode +// --------------------------------------------------------- +// +EXPORT_C TInt CAknPhoneNumberEditor::ChangeEditorMode( TBool aDefaultMode ) + { + TInt value( EAknEditorNumericInputMode ); // Return value. + + if ( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) ) + { + CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; + + // Get current input mode. + TInt currentInputMode = fepState->CurrentInputMode(); + + // Set default values. + if ( aDefaultMode ) + { + fepState->SetCurrentInputMode( EAknEditorNumericInputMode ); + value = EAknEditorNumericInputMode; + } + // Set next input mode. 123 -> abc -> 123... + else + { + if ( currentInputMode == EAknEditorNumericInputMode ) + { + fepState->SetCurrentInputMode( EAknEditorTextInputMode ); + fepState->SetSpecialCharacterTableResourceId( + R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG ); + value = EAknEditorTextInputMode; + } + else if ( currentInputMode == EAknEditorTextInputMode ) + { + fepState->SetCurrentInputMode(EAknEditorNumericInputMode); + fepState->SetSpecialCharacterTableResourceId( 0 ); + value = EAknEditorNumericInputMode; + } + } + + fepState->SetCurrentCase(EAknEditorLowerCase); + // Set some other VoIP specific editor settings. + if ( FeatureManager::FeatureSupported( KFeatureIdOnScreenDialer ) ) + { + fepState->SetFlags( EAknEditorFlagNoT9 + | EAknEditorFlagLatinInputModesOnly | EAknEditorFlagNoEditIndicators ); + } + else + { + fepState->SetFlags( EAknEditorFlagNoT9 + | EAknEditorFlagLatinInputModesOnly ); + } + + fepState->SetPermittedInputModes( + EAknEditorNumericInputMode|EAknEditorTextInputMode ); + fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap); + + // Report FEP from new settings. + TRAP_IGNORE( fepState->ReportAknEdStateEventL( + MAknEdStateObserver::EAknEdwinStateEventStateUpdate ) ); + + fepState->SetMenu(); + } + DrawChanges(); + return value; + } + +// --------------------------------------------------------- +// CAknPhoneNumberEditor::GetEditorMode +// --------------------------------------------------------- +// +EXPORT_C TInt CAknPhoneNumberEditor::GetEditorMode() const + { + CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; + + TInt currentInputMode = fepState->CurrentInputMode(); + + fepState->SetCurrentCase(EAknEditorLowerCase); + if ( currentInputMode == EAknEditorNumericInputMode ) + { + fepState->SetSpecialCharacterTableResourceId( 0 ); + } + else if ( currentInputMode == EAknEditorTextInputMode ) + { + + fepState->SetSpecialCharacterTableResourceId( + R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG ); + } + + fepState->SetMenu(); + return currentInputMode; + } + +// --------------------------------------------------------- +// CAknPhoneNumberEditor::ResetEditorToDefaultValues +// --------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::ResetEditorToDefaultValues() + { + CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; + CloseVKB(); + // Set FEP-state to default values. + fepState->SetFlags( EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | + EAknEditorFlagNoEditIndicators ); + fepState->SetDefaultInputMode( EAknEditorNumericInputMode ); + fepState->SetCurrentInputMode( EAknEditorNumericInputMode ); + fepState->SetPermittedInputModes( EAknEditorNumericInputMode ); + fepState->SetDefaultCase( EAknEditorLowerCase ); + fepState->SetCurrentCase( EAknEditorLowerCase ); + fepState->SetPermittedCases( EAknEditorLowerCase | EAknEditorUpperCase ); + fepState->SetSpecialCharacterTableResourceId( 0 ); + fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap ); + + DrawChanges(); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::HandlePointerEventL +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::HandlePointerEventL( + const TPointerEvent& aPointerEvent) + { + TCursorSelection selectionBefore = Selection(); + TInt cursor = iView->GetCursorPosByPoint( aPointerEvent.iPosition ); + // if cursro is not in accepted range. cancel current selection + + if ( cursor < 0 ) + { + cursor = CursorPos(); + DrawNow(); + return; + } + + const CAknPhedViewLineArray* lineArray = iView->LineArray(); + TInt cursorLinePre = iView->CursorLine(); + TInt leftPosPre = lineArray->At( cursorLinePre ).LeftPos(); + switch( aPointerEvent.iType ) + { + case TPointerEvent::EButton1Down: + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + + if ( feedback ) + { + feedback->InstantFeedback( this, ETouchFeedbackEdit ); + } + } + //cancel previous selection + if ( iExtension->iPointPos != cursor ) + { + SetCursorPosL( iModel->Uncompensate( cursor ), EFalse ); + iExtension->iPointPos = cursor; + } + break; + case TPointerEvent::EButton1Up: + if ( iExtension->iPointPos == cursor ) + { + SetCursorPosL( iModel->Uncompensate( cursor ), EFalse ); + } + else + { + SetSelectionL( iModel->Uncompensate( cursor ), + iModel->Uncompensate( iExtension->iPointPos ) ); + } + break; + case TPointerEvent::EButtonRepeat: + case TPointerEvent::EDrag: + { + SetSelectionL( iModel->Uncompensate( cursor ), + iModel->Uncompensate( iExtension->iPointPos ) ); + TCursorSelection selectionAfter = Selection(); + TBool selectionChanged = + ( ( selectionAfter.iCursorPos != selectionBefore.iCursorPos ) + || ( selectionAfter.iAnchorPos != selectionBefore.iAnchorPos ) ); + if ( selectionChanged ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->InstantFeedback( this, ETouchFeedbackTextSelection ); + } + } + } + break; + default: + break; + } + + // same handling as OfferKeyEvent to prevent flicker. + TInt leftPosPost = lineArray->At( iView->CursorLine() ).LeftPos(); + if ( Abs( leftPosPost - leftPosPre ) != lineArray->At( 0 ).LineWidth() ) + { + DrawNow(); + } + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::MopSupplyObject +// -------------------------------------------------------------------------- +// +EXPORT_C TTypeUid::Ptr CAknPhoneNumberEditor::MopSupplyObject( TTypeUid aId ) + { + if ( aId.iUid == CEikMenuBar::ETypeId ) + { + return aId.MakePtr( iEikonEnv->AppUiFactory()->MenuBar() ); + } + return TTypeUid::Null(); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuIsFocused +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CAknPhoneNumberEditor::CcpuIsFocused() const + { + return IsFocused(); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCanCut +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanCut() const + { + return ( iExtension->iCcpuSupport && SelectionLength() != 0 ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCutL +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::CcpuCutL() + { + ClipboardL( EFalse ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCanCopy +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanCopy() const + { + return ( iExtension->iCcpuSupport && SelectionLength() != 0 ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCopyL +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::CcpuCopyL() + { + ClipboardL( ETrue ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCanPaste +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanPaste() const + { + if ( !iExtension->iCcpuSupport ) + return EFalse; + + if ( iExtension->iPasteText ) + { + delete iExtension->iPasteText; + iExtension->iPasteText = NULL; + } + TRAPD( err, DoCanPasteL() ); + return ( err == KErrNone ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::DoCanPasteL +// Check if there are data in clipboard and if the format of the data is +// accepted by phone number editor +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::DoCanPasteL() const + { + CClipboard* cb = NULL; + cb = CClipboard::NewForReadingL( iCoeEnv->FsSession() ); + CleanupStack::PushL( cb ); + CStreamStore& store = cb->Store(); + CStreamDictionary& dict = cb->StreamDictionary(); + + // get plain text data from clipboard + CPlainText* text = CPlainText::NewL(); + CleanupStack::PushL( text ); + TInt dataLength = text->PasteFromStoreL( store, dict, KPlainTextPos); + if ( dataLength == 0 ) + { + User::Leave( KErrNotFound ); + } + HBufC* hBuf = HBufC::NewL( dataLength ); + TPtr buf = hBuf->Des(); + text->Extract( buf, KPlainTextPos, dataLength ); + CleanupStack::PopAndDestroy( text ); + CleanupStack::PushL( hBuf ); + + // get the list of allowed characters in phone number editor + CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; + HBufC* specTable = NULL; + if ( fepState->NumericKeymap() == + EAknEditorAlphanumericNumberModeKeymap ) + { + TInt resId = fepState->SpecialCharacterTableResourceId(); + if ( resId > 0 ) + { + specTable = iEikonEnv->AllocReadResourceLC( resId ); + } + } + HBufC* allowChars = iEikonEnv->AllocReadResourceLC( + R_EIK_ALLOWED_STANDARDNUMBERMODEKEYMAP ); + + // check if the characters are allowed, if one character is not allowed, + // it will not be pasted into phone number editor + if ( fepState->CurrentInputMode() != EAknEditorTextInputMode ) + { + TInt pos = 0; + TInt index = 0; + while ( index < buf.Length() ) + { + pos = allowChars->Locate( buf[index] ); + if ( pos == KErrNotFound && specTable && specTable->Length() > 0 ) + { + pos = specTable->Locate( buf[index] ); + } + if ( pos == KErrNotFound ) + { + buf.Delete( index, 1 ); + } + else + { + index++; + } + } + if ( buf.Length() == 0 ) + { + User::Leave( KErrNotFound ); + } + } + iExtension->iPasteText = HBufC::NewL( buf.Length() ); + TPtr pasteBuf = iExtension->iPasteText->Des(); + pasteBuf.Copy( buf ); + CleanupStack::PopAndDestroy( allowChars ); + if ( specTable ) + { + CleanupStack::PopAndDestroy( specTable ); + } + CleanupStack::PopAndDestroy( hBuf ); + CleanupStack::PopAndDestroy( cb ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuPasteL +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::CcpuPasteL() + { + if ( iExtension->iPasteText ) + { + iModel->Paste( iExtension->iPasteText->Des() ); + DrawNow(); + } + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuCanUndo +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanUndo() const + { + return EFalse; + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CcpuUndoL +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::CcpuUndoL() + { + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::EnableCcpuSupportL +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::EnableCcpuSupportL( TBool aSupport ) + { + CAknCcpuSupport* ccpu = NULL; + CAknEdwinState* edwinState = ( CAknEdwinState* )iFepState; + + if ( aSupport ) + { + ccpu = new( ELeave ) CAknCcpuSupport( this ); + ccpu->SetMopParent( this ); + CleanupStack::PushL( ccpu ); + ccpu->ConstructL(); + CleanupStack::Pop( ccpu ); + if ( edwinState ) + { + edwinState->SetCcpuState( this ); + } + } + else + { + if ( edwinState ) + { + edwinState->SetCcpuState( NULL ); + } + } + delete iExtension->iCcpuSupport; + iExtension->iCcpuSupport = ccpu; + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::ClipboardL +// implementate copy and cut +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::ClipboardL( TBool aIsCopy ) + { + CancelFepTransaction(); + TInt selectLength = SelectionLength(); + if ( selectLength == 0 ) + { + iEikonEnv->InfoMsg( aIsCopy ? + R_EIK_TBUF_NOTHING_TO_COPY : R_EIK_TBUF_NOTHING_TO_CUT ); + } + else + { + HBufC* buf = HBufC::NewLC( selectLength ); + TPtr text = buf->Des(); + if ( aIsCopy ) + { + iModel->Copy( text ); + } + else + { + iModel->Cut( text ); + DrawNow(); + } + PlaceDataOnClipboardL( text ); + CleanupStack::PopAndDestroy( buf ); + iEikonEnv->InfoMsg( R_EIK_TBUF_COPIED ); + if ( iExtension->iCcpuSupport ) + { + iExtension->iCcpuSupport->HandleSelectionChangeL(); + } + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog(); + dlg->SetTimeout( CAknNoteDialog::EShortTimeout ); + dlg->SetTone( CAknNoteDialog::ENoTone ); + dlg->ExecuteLD( R_AVKON_NOTE_CONF_COPIED ); + } + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::PlaceDataOnClipboardL +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::PlaceDataOnClipboardL( const TDesC& aText ) + { + CClipboard* cb = CClipboard::NewForWritingLC( iCoeEnv->FsSession() ); + + CStreamStore& store = cb->Store(); + CStreamDictionary& dict = cb->StreamDictionary(); + + CPlainText* text = CPlainText::NewL(); + CleanupStack::PushL( text ); + text->InsertL( KPlainTextPos, aText ); + text->CopyToStoreL( store, dict, KPlainTextPos, aText.Length() ); + CleanupStack::PopAndDestroy( text ); + cb->CommitL(); + + CleanupStack::PopAndDestroy( cb ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::OpenVKB +// -------------------------------------------------------------------------- +// +EXPORT_C void CAknPhoneNumberEditor::OpenVKB( ) + { + TUint cap = iExtension->iExtendedInputCapabilities->Capabilities(); + cap &= ~CAknExtendedInputCapabilities::EInputEditorDisableVKB; + iExtension->iExtendedInputCapabilities->SetCapabilities( cap ); + TRAP_IGNORE( ReportAknEdStateEventL( + MAknEdStateObserver::EAknActivatePenInputRequest ) ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::CloseVKB +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::CloseVKB( ) + { + TUint cap = iExtension->iExtendedInputCapabilities->Capabilities(); + cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB; + iExtension->iExtendedInputCapabilities->SetCapabilities( cap ); + ReportAknEdStateEventL( MAknEdStateObserver::EAknClosePenInputRequest ); + } + +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::ReportAknEdStateEventL +// -------------------------------------------------------------------------- +// +void CAknPhoneNumberEditor::ReportAknEdStateEventL( + MAknEdStateObserver::EAknEdwinStateEvent aStateEvent ) + { + CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*,State(KNullUid) ); + if ( edwinState ) + { + TRAP_IGNORE( edwinState->ReportAknEdStateEventL( aStateEvent ) ); + } + } +// -------------------------------------------------------------------------- +// CAknPhoneNumberEditor::AknEditorFlags +// -------------------------------------------------------------------------- +// +EXPORT_C TInt CAknPhoneNumberEditor::AknEditorFlags() + { + CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*,State(KNullUid) ); + if ( !edwinState ) + { + return 0; + } + return edwinState->Flags(); + } + + +// End of file