diff -r 000000000000 -r 2f259fa3e83a uifw/EikStd/coctlsrc/EIKLBED.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/EikStd/coctlsrc/EIKLBED.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,423 @@ +/* +* Copyright (c) 1997-1999 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 +#include // CDesArray +#include // class CEikListBoxTextEditor header file +#include +#include +#include +#include +#include +#include // CGlobalText +#include // CParaFormatLayer, CCharFormatLayer +#include +#include +#include "LAFLBED.H" +#include "akntrace.h" +enum TTUiklbedPanic + { + ETUiklbedPanicEndMarkMissing, + ETUiklbedPanicEmptyField, + ETUiklbedPanicLongInput, + }; + +LOCAL_C void Panic(TTUiklbedPanic aPanic) + { + _LIT(KTUiklbed,"TUiklbed"); + User::Panic(KTUiklbed, aPanic); + } + +// +// MEikListBoxEditor +// + +EXPORT_C void MEikListBoxEditor::MEikListBoxEditor_Reserved_1() + { + } + +// +// CEikListBoxTextEditor +// + +EXPORT_C CEikListBoxTextEditor::CEikListBoxTextEditor( MListBoxModel* aModel ) + : iModel(aModel), iEditor(NULL), iFont(NULL), iItemPos(0), iItemLen(0) + { + _AKNTRACE_FUNC_ENTER; + iFont = CONST_CAST(CFont*,CCoeEnv::Static()->NormalFont()); + AKNTASHOOK_ADD( this, "CEikListBoxTextEditor" ); + _AKNTRACE_FUNC_EXIT; + } + +EXPORT_C CEikListBoxTextEditor::~CEikListBoxTextEditor() + { // need to remove from stack incase listbox was destroyed without calling StopEditingL() + // safe to call RemoveFromStack even if we're not stacked + // code here is same as in StopEditingL(), but we can't call + // a L function from ~ even if it can't leave + _AKNTRACE_FUNC_ENTER; + AKNTASHOOK_REMOVE(); + iEikonEnv->EikAppUi()->RemoveFromStack(this); + if(iEditor) + iEditor->SetFocus(EFalse); // BUG? - cursor remains on screen without this + delete iEditor; + delete iParaFormatLayer; + delete iCharFormatLayer; + _AKNTRACE_FUNC_EXIT; + } + +EXPORT_C void CEikListBoxTextEditor::Release() + { + delete this; + } + +EXPORT_C void CEikListBoxTextEditor::SetFont(const CFont* aFont) + { + if (aFont!=NULL) + iFont = CONST_CAST(CFont*,aFont); + } + +void CEikListBoxTextEditor::UseFontL( CEikEdwin& aEditor, const CFont& aFont ) + { + _AKNTRACE_FUNC_ENTER; + CGlobalText* globalText; + + TCharFormatMask defaultCharFormatMask; + defaultCharFormatMask.SetAttrib(EAttFontTypeface); + defaultCharFormatMask.SetAttrib(EAttFontHeight); + TFontSpec fontspec = aFont.FontSpecInTwips(); + TCharFormat defaultCharFormat( fontspec.iTypeface.iName, fontspec.iHeight ); + + iParaFormatLayer=CParaFormatLayer::NewL(); + iCharFormatLayer=CCharFormatLayer::NewL(defaultCharFormat,defaultCharFormatMask); + globalText=CGlobalText::NewL(iParaFormatLayer,iCharFormatLayer,CEditableText::ESegmentedStorage,5); + CleanupStack::PushL(globalText); + + TCharFormat charFormat; + TCharFormatMask charMask; + iCharFormatLayer->Sense(charFormat,charMask); + if ( fontspec.iFontStyle.Posture()==EPostureItalic ) + { + charMask.SetAttrib(EAttFontPosture); + charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); + } + if ( fontspec.iFontStyle.StrokeWeight()==EStrokeWeightBold ) + { + charMask.SetAttrib(EAttFontStrokeWeight ); + charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); + } + iCharFormatLayer->SetL(charFormat,charMask); + + CPlainText* old=aEditor.Text(); + CleanupStack::Pop(); // globalText + CleanupStack::PushL(old); // old is pushed because we're using EUseText in the subsequent call + aEditor.SetDocumentContentL(*globalText,CEikEdwin::EUseText); + CleanupStack::PopAndDestroy(); // old + _AKNTRACE_FUNC_EXIT; + } + +EXPORT_C CEikEdwin* CEikListBoxTextEditor::Editor() + { + return iEditor; + } + +EXPORT_C MListBoxModel* CEikListBoxTextEditor::ListBoxModel() + { + return iModel; + } + +EXPORT_C void CEikListBoxTextEditor::StartEditingL(const CCoeControl& aContainer, const TRect& aRect, TInt aItemIndex, TInt aMaxLength ) + { + _AKNTRACE_FUNC_ENTER; + if (Editor()) + { + _AKNTRACE_FUNC_EXIT; + return; // quit if editing is currently on + } + + iItemIndex=aItemIndex; + TRect rect=aRect; + TPtrC itemtext=EditableItemText(&rect); // get text (also partly editable) + + // create edwin (make it into own window, no wrapping) + TGulBorder border; + LafListBoxTextEditor::GetDefaultBorder(border); + CEikEdwin* editor=new(ELeave) CEikEdwin(border); + CleanupStack::PushL(editor); + TInt edwinFlags=EEikEdwinOwnsWindow | EEikEdwinNoWrap | EEikEdwinNoLineOrParaBreaks | EEikEdwinNoCustomDraw; + editor->CEikEdwin::ConstructL(edwinFlags,0,(iItemLen?iItemLen:aMaxLength),1); + editor->SetContainerWindowL(aContainer); + editor->SetRect(rect); + UseFontL(*editor,*iFont); // need this to change CEikEdwin font... + editor->SetTextL(&itemtext); + editor->SetCursorPosL(editor->TextLength(),ETrue); + editor->SetFocus(ETrue); + editor->ActivateL(); + iEikonEnv->EikAppUi()->AddToStackL(this,ECoeStackPriorityDialog,ECoeStackFlagRefusesFocus); + CleanupStack::Pop(); // editor + iEditor=editor; + iCoeEnv->InputCapabilitiesChanged(); + _AKNTRACE_FUNC_EXIT; + } + +/** + * Writes the internal state of the control and its components to aStream. + * Does nothing in release mode. + * Designed to be overidden and base called by subclasses. + * + * @internal + * @since App-Framework_6.1 + */ +#ifndef _DEBUG +EXPORT_C void CEikListBoxTextEditor::WriteInternalStateL(RWriteStream&) const + {} +#else +EXPORT_C void CEikListBoxTextEditor::WriteInternalStateL(RWriteStream& aWriteStream) const + { + _LIT(KEikLitLbxEdCtlStart,""); + _LIT(KEikLitLbxEdCtlEnd,"<\\CEikListBoxTextEditor>"); + _LIT(KEikLitLbxEdObs,""); + _LIT(KEikLitLbxEdObsEnd,"<\\iEditorObserver>"); + _LIT(KEikLitLbxEdMdl,""); + _LIT(KEikLitLbxEdMdlEnd,"<\\iModel>"); + _LIT(KEikLitLbxEdEdr,""); + _LIT(KEikLitLbxEdEdrEnd,"<\\iEditor>"); + _LIT(KEikLitLbxEdIndx,""); + _LIT(KEikLitLbxEdIndxEnd,"<\\iItemIndex>"); + _LIT(KEikLitLbxEdFont,""); + _LIT(KEikLitLbxEdFontEnd,"<\\iFont>"); + _LIT(KEikLitLbxEdItemPos,""); + _LIT(KEikLitLbxEdItemPosEnd,"<\\iItemPos>"); + _LIT(KEikLitLbxEdItemLen,""); + _LIT(KEikLitLbxEdItemLenEnd,"<\\iItemLen>"); + _LIT(KEikLitLbxEdParaLay,""); + _LIT(KEikLitLbxEdParaLayEnd,"<\\iParaFormatLayer>"); + _LIT(KEikLitLbxEdCharLay,""); + _LIT(KEikLitLbxEdCharLayEnd,"<\\iCharFormatLayer>"); + + aWriteStream << KEikLitLbxEdCtlStart; + aWriteStream << KEikLitLbxEdObs; + aWriteStream.WriteInt32L((TInt)iEditorObserver); + aWriteStream << KEikLitLbxEdObsEnd; + aWriteStream << KEikLitLbxEdMdl; + aWriteStream.WriteInt32L((TInt)iModel); + aWriteStream << KEikLitLbxEdMdlEnd; + aWriteStream << KEikLitLbxEdEdr; + iEditor->WriteInternalStateL(aWriteStream); // won't be done as a component + aWriteStream << KEikLitLbxEdEdrEnd; + aWriteStream << KEikLitLbxEdIndx; + aWriteStream.WriteInt32L(iItemIndex); + aWriteStream << KEikLitLbxEdIndxEnd; + aWriteStream << KEikLitLbxEdFont; + const TFontSpec& spec=iFont->FontSpecInTwips(); + aWriteStream << spec; + aWriteStream << KEikLitLbxEdFontEnd; + aWriteStream << KEikLitLbxEdItemPos; + aWriteStream.WriteInt32L(iItemPos); + aWriteStream << KEikLitLbxEdItemPosEnd; + aWriteStream << KEikLitLbxEdItemLen; + aWriteStream.WriteInt32L(iItemLen); + aWriteStream << KEikLitLbxEdItemLenEnd; + aWriteStream << KEikLitLbxEdParaLay; + aWriteStream << *iParaFormatLayer; + aWriteStream << KEikLitLbxEdParaLayEnd; + aWriteStream << KEikLitLbxEdCharLay; + aWriteStream << *iCharFormatLayer; + aWriteStream << KEikLitLbxEdCharLayEnd; + CCoeControl::WriteInternalStateL(aWriteStream); + aWriteStream << KEikLitLbxEdCtlEnd; + } +#endif + +EXPORT_C TPtrC CEikListBoxTextEditor::ItemText() + { + return static_cast(ListBoxModel())->ItemText(ItemIndex()); + } + +TPtrC CEikListBoxTextEditor::EditableItemText(TRect* aRect) + { + _AKNTRACE_FUNC_ENTER; + TPtrC itemtext = ItemText(); + if (iItemPos==0) // not yet set (and even if set, cannot be zero) + { + iItemPos = itemtext.Locate('\n'); // loacte partly editable item start + if (iItemPos != KErrNotFound) + { + iItemPos++; // jump over mark character + iItemLen = itemtext.Mid( iItemPos ).Locate('\n'); // locate string end + if ( iItemLen == KErrNotFound ) + Panic( ETUiklbedPanicEndMarkMissing ); + if ( iItemLen==0 ) + Panic( ETUiklbedPanicEmptyField ); + TPtrC head = itemtext.Left( iItemPos ); + TPtrC body = itemtext.Mid( iItemPos, iItemLen ); + if ( aRect ) // adjust the rect if it is given + { + aRect->iTl.iX += iFont->TextWidthInPixels( head ); + aRect->iBr.iX = aRect->iTl.iX + iFont->TextWidthInPixels( body ) + 4; + } + _AKNTRACE_FUNC_EXIT; + return body; + } + iItemPos = 0; // partly editable text not found + } + _AKNTRACE_FUNC_EXIT; + return itemtext; + } + +EXPORT_C void CEikListBoxTextEditor::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + CAknControl::HandlePointerEventL(aPointerEvent); + } + +EXPORT_C void* CEikListBoxTextEditor::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +/** + * Stops editing the current item, if editing was taking place. Does not Leave. + * + * @since Uikon1.2 + */ +EXPORT_C void CEikListBoxTextEditor::StopEditingL() + { + iEikonEnv->EikAppUi()->RemoveFromStack(this); + if ( Editor() == NULL ) return; // quit if editing is not currently on + iEditor->SetFocus(EFalse); // BUG? - cursor remains on screen without this + delete iEditor; + iEditor=NULL; + iCoeEnv->InputCapabilitiesChanged(); + } + +EXPORT_C TBool CEikListBoxTextEditor::UpdateModelL() + // virtual - needs to be rewritten if editing other than single column text list + { + _AKNTRACE_FUNC_ENTER; + if (!Editor()) + { + _AKNTRACE_FUNC_EXIT; + return EFalse; // quit if editing is not currently on + } + const MDesCArray* matchableTextArray=ListBoxModel()->MatchableTextArray(); + CDesCArray* textArray=(CDesCArray*)matchableTextArray; + + TPtrC itemtext = ItemText(); + if ( iItemPos ) // partly editable item? + { + HBufC* itemBuffer= HBufC::New(itemtext.Length()); + CleanupStack::PushL( itemBuffer ); + TPtr itemPointer = itemBuffer->Des(); + + itemPointer.Append( itemtext.Left( iItemPos ) ); + + HBufC* ptr=iEditor->GetTextInHBufL(); + TPtrC newText; + if (ptr) + { + newText.Set(ptr->Des()); + } + TInt addSpaces = iItemLen - newText.Length(); + for (TInt index=0; ((addSpaces>0) && (indexInsertL( ItemIndex(), *itemBuffer ); + CleanupStack::PopAndDestroy(); // itemBuffer + + textArray->Delete( ItemIndex()+1 ); + } + else // replace the whole list item + { + HBufC* newText = iEditor->GetTextInHBufL(); + if (!newText) return ETrue; // if user tries to insert an empty text... + + CleanupStack::PushL(newText); + textArray->InsertL(ItemIndex(),*newText); + CleanupStack::PopAndDestroy(); // newText + + textArray->Delete( ItemIndex() + 1 ); + } + _AKNTRACE_FUNC_EXIT; + return ETrue; + } + +EXPORT_C TInt CEikListBoxTextEditor::ItemIndex() const + { + return iItemIndex; + } + +EXPORT_C TKeyResponse CEikListBoxTextEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + _AKNTRACE_FUNC_ENTER; + _AKNTRACE( "aKeyEvent.iCode is %d", aKeyEvent.iCode ); + _AKNTRACE( "aKeyEvent.iScanCode is %d", aKeyEvent.iScanCode ); + _AKNTRACE( "aType is %d", aType ); + if (!Editor() || aType!=EEventKey) + { + _AKNTRACE_FUNC_EXIT; + return EKeyWasNotConsumed; + } + + if(iEditorObserver && iEditorObserver->HandleListBoxEditorEventL(this,aKeyEvent)==EKeyWasConsumed) + { // gives owning dialogs or listboxes a chance to intecept keys prior to or instead of passing to editor + // eg the CCknFileSaveAsDialog needs to check if a file exists when the enter key is pressed + // and prevent the Enter key being passed on to the editor, or intecept the up/down keys to + // allow scrolling out of the editor + _AKNTRACE_FUNC_EXIT; + return EKeyWasConsumed; + } + const TInt code=aKeyEvent.iCode; + if (aKeyEvent.iModifiers&(EModifierCtrl|EModifierShift)==(EModifierCtrl|EModifierShift)) + { + TBuf<24> buf; + iCoeEnv->ReadResource(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS); + const TInt pos=buf.Locate(TChar(code+'a'-1)); + if (pos==CEikEdwin::EHotKeyInsertChar) + { + _AKNTRACE_FUNC_EXIT; + return EKeyWasConsumed; + } + } + switch (code) + { + case EKeyEnter: // stop editing and update data + case EKeyOK: + UpdateModelL(); + StopEditingL(); + break; + case EKeyEscape: // stop editing and don't update data + StopEditingL(); + break; + default: + Editor()->OfferKeyEventL(aKeyEvent,aType); + } + _AKNTRACE_FUNC_EXIT; + return EKeyWasConsumed; + } + +EXPORT_C void CEikListBoxTextEditor::SetListBoxEditorObserver(MListBoxEditorObserver* aObserver) + { + iEditorObserver=aObserver; + } + +EXPORT_C void CEikListBoxTextEditor::MEikListBoxEditor_Reserved_1() + { + }