diff -r e8e63152f320 -r 2a9601315dfc javauis/lcdui_akn/lcdui/src/CMIDTextBoxControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/lcdui/src/CMIDTextBoxControl.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,464 @@ +/* +* Copyright (c) 2003 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: ?Description +* +*/ + + +// ========== INCLUDE FILES ================================ + +#include +#include +#include +// using Layout_Meta_Data::IsLandscapeOrientation for retrieving info about orientation +#include +// LAF +#include + +#include +#include + +#include "CMIDTextBoxControl.h" +// used when creating a new text box +#include "CMIDTextBoxEdwin.h" +#include "CMIDTextBoxEdwinCustomDraw.h" +#include "CMIDCommand.h" + + +// ========== MEMBER FUNCTIONS ============================= + +CMIDTextBoxControl* CMIDTextBoxControl::NewL(TInt aConstraints, + const TDesC& aText, TInt aMaxSize,MMIDDisplayable* aDisplayable) +{ + CMIDTextBoxControl* self=new(ELeave) CMIDTextBoxControl(); + CleanupStack::PushL(self); + self->ConstructL(aConstraints, aText, aMaxSize, aDisplayable); + CleanupStack::Pop(self); + + return self; +} + +CMIDTextBoxControl::CMIDTextBoxControl() +{ +} + +void CMIDTextBoxControl::ConstructL(TInt aConstraints, const TDesC& aText, + TInt aMaxSize, MMIDDisplayable* aDisplayable) +{ + iDisplayable = static_cast(aDisplayable); + + SetContainerWindowL(*iDisplayable); + + iTextBox = CreateTextBoxL(aText, aMaxSize, aConstraints); + iConstraints=aConstraints; + iCursorPos = iTextBox->CursorPos(); + + SetRect(iDisplayable->Rect()); + aDisplayable->SetComponentL(*this); //will call ActivateL() on us +} + +CMIDTextBoxControl::~CMIDTextBoxControl() +{ + delete iTextBox; + + // Displayable is notified about content control deletion + if (iDisplayable) + { + iDisplayable->NotifyContentDestroyed(); + } + +} + +// +// methods from MMIDTextBox +// + +void CMIDTextBoxControl::DeleteTextL(TInt aOffset,TInt aLength) +{ + iTextBox->DeleteTextL(aOffset, aLength); +} + +void CMIDTextBoxControl::SetTextL(const TDesC& aText) +{ + iTextBox->SetTextL(aText); +} + +void CMIDTextBoxControl::InsertTextL(const TDesC& aText,TInt aPosition) +{ + iTextBox->InsertTextL(aText, aPosition); +} + +void CMIDTextBoxControl::SetConstraintsL(TUint aConstraints) +{ + iConstraints=aConstraints; + TBool convNeededOld = iTextBox->IsNumberConversionNeeded(); + RecreateTextBoxL(aConstraints); + TBool convNeededNew = iTextBox->IsNumberConversionNeeded(); + if (convNeededNew != convNeededOld) + { + HBufC* text = iTextBox->GetTextL(); + TPtr ptr = text->Des(); + AknTextUtils::LanguageSpecificNumberConversion(ptr); + CleanupStack::PushL(text); + iTextBox->SetTextL(ptr); + CleanupStack::PopAndDestroy(text); + } +} + +TInt CMIDTextBoxControl::SetMaxSizeL(TInt aSize) +{ + return iTextBox->SetMaxSizeL(aSize); +} + +TInt CMIDTextBoxControl::GetMaxSize() +{ + return iTextBox->GetMaxSize(); +} + +TInt CMIDTextBoxControl::Size() +{ + return iTextBox->Size(); +} + +TInt CMIDTextBoxControl::GetCaretPosition() +{ + return iTextBox->GetCaretPosition(); +} + +HBufC* CMIDTextBoxControl::GetTextL() +{ + return iTextBox->GetTextL(); +} + +void CMIDTextBoxControl::SetInitialInputModeL(const TDesC& aCharacterSubset) +{ + iTextBox->SetInitialInputModeL(aCharacterSubset); +} + +// +// methods from CCoeControl +// + +TInt CMIDTextBoxControl::CountComponentControls() const +{ + return 1; // iTextBox +} + +CCoeControl* CMIDTextBoxControl::ComponentControl(TInt aIndex) const +{ + if (aIndex == 0) + { + return iTextBox; + } + return NULL; +} + +TKeyResponse CMIDTextBoxControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) +{ + // + // Enter Key + // + + if (aType == EEventKey) + { + iUsedKeyEvent = &aKeyEvent; + } + + // If TextBox have constraints below params + // Any and Password + // Numeric or Numeric and Password or + // Decimal or Decimal and Password or + // PhoneNumber or PhoneNumber and Password or + // MailAddr or MailAddr and Password or + // PhoneNumber Uneditable or MailAddr Uneditable or + // Url or Url and Password + // then show menu or activate one command. + if (((aType == EEventKey && aKeyEvent.iCode == EKeyEnter) || + (aType == EEventKeyUp && aKeyEvent.iScanCode == EStdKeyEnter && + aKeyEvent.iCode == EKeyEnter && iUsedKeyEvent!=&aKeyEvent))) + { + + if ((iConstraints == MMIDTextField::EAny + MMIDTextField::EPassword) || + + (iConstraints == MMIDTextField::ENumeric || + (iConstraints == MMIDTextField::ENumeric + MMIDTextField::EPassword) || + iConstraints == MMIDTextField::EDecimal || + (iConstraints == MMIDTextField::EDecimal + MMIDTextField::EPassword)) || + + (iConstraints == MMIDTextField::EPhoneNumber || + (iConstraints == MMIDTextField::EPhoneNumber + MMIDTextField::EPassword) || + iConstraints == MMIDTextField::EMailAddr || + (iConstraints == MMIDTextField::EMailAddr + MMIDTextField::EPassword)) || + + ((iConstraints == MMIDTextField::EPhoneNumber + MMIDTextField::EUneditable) || + (iConstraints == MMIDTextField::EMailAddr + MMIDTextField::EUneditable)) || + + (iConstraints == MMIDTextField::EUrl || + (iConstraints == MMIDTextField::EUrl + MMIDTextField::EPassword))) + { + + // counter OK and Item elements from options menu + TInt numOpt = iDisplayable->NumCommandsForOkOptionsMenu(); + + //open menu + if (numOpt > 1) + { + iDisplayable->MenuHandler()->ShowMenuL(CMIDMenuHandler::EOkMenu); + } + else + { + CMIDCommand* cmdTmp = NULL; + + // counter of all elements from options menu + TInt numItemCommands = iDisplayable->MainCommandList()->Count(); + + for (TInt i = 0; i < numItemCommands; i++) + { + // for each command from menu + // count offset index only for commands + // without FetchPhoneNumber, EmailAddress, PhoneCall + cmdTmp = iDisplayable->MainCommandList()->At(i).iCommand; + + if (cmdTmp) + { + if ((cmdTmp->Id() != CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) && + (cmdTmp->Id() != CMIDEdwinUtils::EMenuCommandFetchEmailAddress) && + (cmdTmp->Id() != CMIDEdwinUtils::EMenuCommandCreatePhoneCall)) + { + break; + } + } + } + + // execute command + if (cmdTmp) + { + if ((cmdTmp->CommandType() == MMIDCommand::EOk || + cmdTmp->CommandType() == MMIDCommand::EItem || + cmdTmp->CommandType() == MMIDCommand::EScreen)) + { + // get command index from option menu + TInt offsetIdx = iDisplayable->MainCommandList()->FindCommandIndex(cmdTmp); + + if (offsetIdx != KErrNotFound && + iDisplayable->MainCommandList()->At(offsetIdx).iCommand == cmdTmp) + { + iDisplayable->ProcessCommandL(iDisplayable->MainCommandList()->CommandOffset() + offsetIdx); + } + + } + } + } + return EKeyWasConsumed; + } + } + + // + // End Enter Key + // + + // msk: this should be obsolete, but is needed if MSK is not enabled on the device + if ((aType == EEventKey) && (aKeyEvent.iScanCode == EStdKeyDevice3)) + { + iDisplayable->ShowOkOptionsMenuL(); + return EKeyWasConsumed; + } + // end msk + else + { + return iTextBox->OfferKeyEventL(aKeyEvent, aType); + } +} + +void CMIDTextBoxControl::FocusChanged(TDrawNow /*aDrawNow*/) +{ + if (iTextBox) + { + if (IsFocused()) + { + iTextBox->SetFocus(ETrue); + } + else + { + iTextBox->SetFocus(EFalse); + } + } +} + +void CMIDTextBoxControl::HandleCurrentL(TBool aActivate) +{ + iTextBox->HandleCurrentL(aActivate); + if (!aActivate) + { + iCursorPos = iTextBox->CursorPos(); + } +} + +void CMIDTextBoxControl::ActivateL() +{ + CCoeControl::ActivateL(); + // This is needed because CEikEdwin doesn't leave the cursor + // at its current position when the CEikEdwin is re-activated. + iTextBox->SetCursorPosL(iCursorPos, EFalse); + SizeChanged(); // needed to be called explicitly to layout controls as ActivateL() will not call it if size has not changed +} + +/** + * @note SizeChanged() won't be called so often for CMIDTextBoxControl + * (i.e. called when resolution changes) + * No need to set the layout info as members of this class. + * The control rect is without the left and right margins from + * list_scroll_midp_pane. + */ +void CMIDTextBoxControl::SizeChanged() +{ + TAknWindowLineLayout listScrollPaneLayout = + AknLayoutScalable_Avkon::listscroll_midp_pane(0).LayoutLine(); + + TRect listScrollPaneRect = Rect(); + listScrollPaneRect.iTl.iX += listScrollPaneLayout.il; + listScrollPaneRect.iBr.iX -= listScrollPaneLayout.ir; + + // the pane for displaying the actual Edwin, without scrollbar + TAknLayoutRect edwinPane; + edwinPane.LayoutRect( + listScrollPaneRect, + AknLayoutScalable_Avkon::list_midp_pane(0).LayoutLine()); + + if (iTextBox) + { + // layout the scroll bar + LayoutScrollBar(listScrollPaneRect); + + // layout the Edwin control + iTextBox->DoLayout(edwinPane.Rect()); + } +} + + +void CMIDTextBoxControl::HandleResourceChange(TInt aType) +{ + CCoeControl::HandleResourceChange(aType); + + // Skin Changed + if (aType == KEikColorResourceChange || aType == KAknsMessageSkinChange || + aType == KUidValueCoeColorSchemeChangeEvent) + { + CMIDTextBoxEdwinCustomDraw* customDraw = NULL; + CMIDTextBoxEdwin* textBoxEdwin = reinterpret_cast(iTextBox); + if (textBoxEdwin) + { + // Getting of CMIDTextBoxCustomDraw, which will be updated. + customDraw = textBoxEdwin->GetCustomDraw(); + } + + if (customDraw) + { + // Updating of line icon in CMIDTextBoxCustomDraw. + TRAPD(ignoreErr, customDraw->UpdateIconL()); + if (ignoreErr != KErrNone) + { + DEBUG_INT("CMIDTextBoxControl::HandleResourceChange - UpdateIconL leaved. Error = %d", ignoreErr); + } + // Calculating of layout, it is necessary for correct set of size + // of line icon in CMIDTextBoxCustomDraw. + SizeChanged(); + } + } + + if (aType == KEikDynamicLayoutVariantSwitch) + { + // relayout the control + SizeChanged(); + // Changing system fonts height could also affect layouting of textbox. + // Because this change doesn't affect rectangle, displayable is not + // redrawn (see CMIDDisplayable::Layout()). So that redrawing has to be + // initiated here. + if (IsVisible()) + { + DrawDeferred(); + } + } +} + + +/** Create a new text box. This is called by ConstrctL() and by RecreateTextBoxL() */ +CMIDEdwin* CMIDTextBoxControl::CreateTextBoxL(const TDesC& aText, + TInt aMaxSize, TUint aConstraints) +{ + return CMIDTextBoxEdwin::NewL(aConstraints, aText, aMaxSize, iDisplayable); +} + +/** Deletes the existing text box and recreates a new one. This is called by SetConstraints(). +If we fail creating the new text box we make sure the old one is still +there. Makes sure the focus position is preserved. */ +void CMIDTextBoxControl::RecreateTextBoxL(TUint aConstraints) +{ + ASSERT(iTextBox); + + HBufC* text = iTextBox->GetTextL(); + CleanupStack::PushL(text); + + TInt maxSize = iTextBox->GetMaxSize(); + iCursorPos = iTextBox->CursorPos(); + + // TextBox's focus state is stored because after recreating + // TextBox the focus information is lost. + TBool hasFocus = IsFocused(); + + CMIDEdwin* textBox = CreateTextBoxL(KNullDesC, maxSize, aConstraints); + + delete iTextBox; + iTextBox = textBox; + + iTextBox->SetTextWithNewConstraintsL(text); + CleanupStack::PopAndDestroy(text); + + iTextBox->HandleCurrentL(iDisplayable->IsActive()); + + // Check if the text size has changed and reposition cursor if needed + if (iCursorPos > iTextBox->TextLength()) + { + iCursorPos = iTextBox->TextLength(); + } + iTextBox->SetCursorPosL(iCursorPos, EFalse); + + // Activate new iTextBox with CoeControl + ActivateL(); + + // If TextBox had focus before recreation, the focus is restored. + if (hasFocus) + { + iTextBox->SetFocus(ETrue); + } + +} + +void CMIDTextBoxControl::LayoutScrollBar(const TRect& aRect) +{ + // get the Edwin's scrollbar + CEikScrollBarFrame* sbFrame = iTextBox->ScrollBarFrame(); + + TAknWindowLineLayout scrollPane = + AknLayoutScalable_Avkon::scroll_pane_cp16(0).LayoutLine(); + + if (sbFrame && + sbFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan) + { + AknLayoutUtils::LayoutVerticalScrollBar(sbFrame, aRect, scrollPane); + } +} + + +// End of File