diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknMultilineQueryControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/AknMultilineQueryControl.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,2080 @@ +/* +* Copyright (c) 2002 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 FILES +#include //This class +#include //For TResourceReader +#include //For CEikEnv +#include //For layout definitions +#include //For layout macros +#include + +#include +#include + +#include "akntextcontrol.h" +#include "aknqueryeditorindicator.h" +#include "AknQueryExtension.h" +#include +#include "aknappui.h" +#include "AknQueryExtension.h" + +#include +#include +#include + +#if defined( RD_SCALABLE_UI_V2) +//class CAknButton is available from week 20 version 5.0 onwards +#include +// For MAknMfneCommandObserver +#include +#endif //if defined( RD_SCALABLE_UI_V2) + +#include +#include + +#include + +#include // for testability hooks + + +EXPORT_C CAknMultilineQueryControl::CAknMultilineQueryControl() + : CAknQueryControl(), iLinePos(EFirstLine) + { + AKNTASHOOK_ADD( this, "CAknMultilineQueryControl" ); + } + +// +//Destructor +// +EXPORT_C CAknMultilineQueryControl::~CAknMultilineQueryControl() + + { + AKNTASHOOK_REMOVE(); + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->RemoveFeedbackForControl( this ); + } + } + +/** + *Initializes the member data from resource + */ +void CAknMultilineQueryControl::ConstructQueryL(TResourceReader& aRes) + { + SetLinePosition(); + + switch(iQueryType) + { + case EMultiDataFirstEdwin: + case EMultiDataSecondEdwin: + { + iEdwin = new(ELeave)CEikEdwin; + iEdwin->SetContainerWindowL(*this); + iEdwin->ConstructFromResourceL(aRes); + iEdwin->SetObserver(this); + iEdwin->AddFlagToUserFlags(EEikEdwinNoWrap); + } + break; + case EMultiDataFirstEdwinAllowEmpty: + { + iEdwin = new(ELeave)CEikEdwin; + iEdwin->SetContainerWindowL(*this); + iEdwin->ConstructFromResourceL(aRes); + iEdwin->SetObserver(this); + iEdwin->AddFlagToUserFlags(EEikEdwinNoWrap); + + CAknQueryExtension* extension = QueryExtension(); + if( extension ) + { + extension->iAllowEmptyInput = ETrue; + } + iQueryType = EMultiDataFirstEdwin; + } + break; + case EMultiDataSecondEdwinAllowEmpty: + { + iEdwin = new(ELeave)CEikEdwin; + iEdwin->SetContainerWindowL(*this); + iEdwin->ConstructFromResourceL(aRes); + iEdwin->SetObserver(this); + iEdwin->AddFlagToUserFlags(EEikEdwinNoWrap); + + CAknQueryExtension* extension = QueryExtension(); + if( extension ) + { + extension->iAllowEmptyInput = ETrue; + } + iQueryType = EMultiDataSecondEdwin; + } + break; + case EMultiDataFirstSecEd: + case EMultiDataSecondSecEd: + { + iSecretEd = new(ELeave)CEikSecretEditor; + iSecretEd->SetContainerWindowL(*this); + iSecretEd->ConstructFromResourceL(aRes); + iSecretEd->SetObserver(this); + iSecretEd->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); + } + break; + case EMultiDataFirstTimeEd: + case EMultiDataSecondTimeEd: + { + iTimeEdwin = new(ELeave)CEikTimeEditor; + iTimeEdwin->SetContainerWindowL(*this); + iTimeEdwin->ConstructFromResourceL(aRes); + iTimeEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); +#if defined( RD_SCALABLE_UI_V2) + + if ( AknLayoutUtils::PenEnabled() ) + { + iTimeEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight ); + } + +#endif //if defined( RD_SCALABLE_UI_V2) + } + break; + case EMultiDataFirstDateEd: + case EMultiDataSecondDateEd: + { + iDateEdwin = new(ELeave)CEikDateEditor; + iDateEdwin->SetContainerWindowL(*this); + iDateEdwin->ConstructFromResourceL(aRes); + iDateEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); +#if defined( RD_SCALABLE_UI_V2) + + if ( AknLayoutUtils::PenEnabled() ) + { + iDateEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight ); + //SizeChanged(); + } + +#endif //if defined( RD_SCALABLE_UI_V2) + } + break; + case EMultiDataFirstDurEd: + case EMultiDataSecondDurEd: + { + iDurationEdwin = new(ELeave)CEikDurationEditor; + iDurationEdwin->SetContainerWindowL(*this); + iDurationEdwin->ConstructFromResourceL(aRes); + iDurationEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); + if ( AknLayoutUtils::PenEnabled() ) + { + iDurationEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight ); + } + } + break; + case EMultiDataFirstPhoneEd: + case EMultiDataSecondPhoneEd: + { + iEdwin = new(ELeave)CEikEdwin; + iEdwin->AddFlagToUserFlags(EEikEdwinAlternativeWrapping | EEikEdwinNoWrap); + iEdwin->SetContainerWindowL(*this); + iEdwin->SetEdwinObserver(this); + iEdwin->ConstructFromResourceL(aRes); + iEdwin->SetObserver(this); + iEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode); + iEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); + } + break; + case EMultiDataFirstNumEd: + case EMultiDataSecondNumEd: + { + iNumberEdwin = new(ELeave)CAknIntegerEdwin; + iNumberEdwin->SetContainerWindowL(*this); + iNumberEdwin->ConstructFromResourceL(aRes); + iNumberEdwin->SetObserver(this); + iNumberEdwin->AddFlagToUserFlags(EEikEdwinNoWrap); + } + break; + case EMultiDataFirstPinEd: + case EMultiDataSecondPinEd: + { + iPinEdwin = new(ELeave)CAknNumericSecretEditor; + iPinEdwin->SetContainerWindowL(*this); + iPinEdwin->ConstructFromResourceL(aRes); + iPinEdwin->SetObserver(this); + iPinEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); + } + break; + case EMultiDataFirstLocationEd: + case EMultiDataSecondLocationEd: + { + LocationEd() = new(ELeave)CAknLocationEditor; + LocationEd()->SetContainerWindowL(*this); + LocationEd()->ConstructFromResourceL(aRes); + LocationEd()->SetObserver(this); + LocationEd()->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); + if ( AknLayoutUtils::PenEnabled() ) + { + LocationEd()->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight ); + } + } + default: + break; + } + + // Construct editor context + CAknQueryExtension* extension = QueryExtension(); + if( extension ) + { + extension->CreateEditorContextL(); + } + + MTouchFeedback* feedback = MTouchFeedback::Instance(); + CFeedbackSpec* spec = CFeedbackSpec::New(); + if ( feedback && spec ) + { + spec->AddFeedback( ETouchEventStylusDown, + ETouchFeedbackSensitiveList ); + feedback->SetFeedbackArea( this, 0, Rect(), spec ); + delete spec; + } + } + +/** + * Layout rectangle (shift up and left by margins) + */ +TRect CAknMultilineQueryControl::LayoutRect() + { + TPoint topLeft(0,0); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + TAknLayoutRect layout; + layout.LayoutRect(DialogRect(), AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(DialogRect(), LAFIndex.CDCPQWindowGraphicsLine5())); + + TRect rect(layout.Rect()); + topLeft.iX -= rect.iTl.iX; + topLeft.iY -= rect.iTl.iY; + + TPoint bottomRight (topLeft); + TSize size (MinimumSize()); + bottomRight.iY += size.iHeight; + bottomRight.iX += size.iWidth; + + return TRect(topLeft,bottomRight); + } + + +/** + * Depending on layout type determine control position in the dialog + */ +void CAknMultilineQueryControl::SetLinePosition() + { + if ( iQueryType == EMultiDataSecondEdwin || iQueryType == EMultiDataSecondSecEd + || iQueryType == EMultiDataSecondTimeEd || iQueryType == EMultiDataSecondDateEd + || iQueryType == EMultiDataSecondDurEd || iQueryType == EMultiDataSecondPhoneEd + || iQueryType == EMultiDataSecondNumEd || iQueryType == EMultiDataSecondPinEd + || iQueryType == EMultiDataSecondLocationEd + ) + { + iLinePos = ESecondLine; + } + } + +/** + * Set the line width for the prompt lines + * + * This is a virtual method called by CAknQueryControl::DoSetPromptL() + * + * Depending on LAF information and on weather we are the first or the second + * query line, we can work out the line widths by indexing the LAF tables. + * + */ +void CAknMultilineQueryControl::SetLineWidthsL() + { + if (!iLineWidths) + return; + + iLineWidths->Reset(); + + TAknLayoutRect parentLayoutRect; + if (Layout_Meta_Data::IsLandscapeOrientation()) + parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_window(0)); + else + parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_code_window(0)); + + //parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_code_window(0)); + TAknLayoutText textRect; + + for (TInt i = 0; i < 2; i++) + { + if (iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_1(0)); + iLineWidths->AppendL(textRect.TextRect().Width()); + } + else if (iLinePos == ESecondLine) + { + textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_3(0)); + iLineWidths->AppendL(textRect.TextRect().Width()); + } + } + } + +/** + * Set the number of prompt lines. + * + * The query dialog calls this method in order to communicate the number of prompt lines + * in the other query line. Indexing into LAF tables depends on this. + * + */ +EXPORT_C void CAknMultilineQueryControl::SetNbrOfPromptLines( + TInt aNbrOfPromptLinesFirstLine, + TInt aNbrOfPromptLinesSecondLine) + { + iFirstQueryPromptLines = aNbrOfPromptLinesFirstLine; + iSecondQueryPromptLines = aNbrOfPromptLinesSecondLine; + } + + +EXPORT_C CCoeControl* CAknMultilineQueryControl::ControlByLayoutOrNull(TInt aLayout) + { + CCoeControl* ctrl=NULL; + switch ( aLayout ) + { + case EMultiDataFirstEdwin: + case EMultiDataSecondEdwin: + case EMultiDataFirstPhoneEd: + case EMultiDataSecondPhoneEd: + ctrl=iEdwin; + break; + case EMultiDataFirstSecEd: + case EMultiDataSecondSecEd: + ctrl=iSecretEd; + break; + case EMultiDataFirstDateEd: + case EMultiDataSecondDateEd: + ctrl=iDateEdwin; + break; + case EMultiDataFirstTimeEd: + case EMultiDataSecondTimeEd: + ctrl=iTimeEdwin; + break; + case EMultiDataFirstDurEd: + case EMultiDataSecondDurEd: + ctrl=iDurationEdwin; + break; + case EMultiDataFirstNumEd: + case EMultiDataSecondNumEd: + ctrl=iNumberEdwin; + break; + case EMultiDataFirstPinEd: + case EMultiDataSecondPinEd: + ctrl=iPinEdwin; + break; + case EMultiDataFirstLocationEd: + case EMultiDataSecondLocationEd: + ctrl=LocationEd(); + break; + default: + break; + } + return ctrl; + } + +EXPORT_C TBool CAknMultilineQueryControl::IsFirst() const + { + return iLinePos == EFirstLine; + } + +EXPORT_C TBool CAknMultilineQueryControl::IsSecond() const + { + return !IsFirst(); + } + +/** + * Return control minimum size + * + * Size is calculated by using LAF tables. Index in this table depends on the + * total number of prompt lines in both queries + */ +EXPORT_C TSize CAknMultilineQueryControl::MinimumSize() + { + TAknLayoutRect layout; + TAknWindowLineLayout window; + WindowLayout( window ); + + TRect mainPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, mainPane ); + layout.LayoutRect( mainPane, window ); + TRect rect2(layout.Rect()); + TSize size = rect2.Size(); + + if (IsFirst()) + { + size.iHeight = FirstLineHeight(); + } + else if (Layout_Meta_Data::IsLandscapeOrientation() && IsSecond()) + { + size.iHeight = SecondLineHeight(); + } + else if (IsSecond()) + { + TAknWindowLineLayout layoutLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(rect2/*DialogRect()*/,0); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect(rect2/*DialogRect()*/, layoutLine); + TRect rect(layoutRect.Rect()); + size.iHeight = rect.Height() - FirstLineHeight(); + } + + else + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + + return size; + } + +/** + * Return height of first line control, use separator to determine this. + */ +TInt16 CAknMultilineQueryControl::FirstLineHeight() const + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + TAknWindowLineLayout separator; + if(!AknLayoutUtils::PenEnabled()) + { + separator = + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3()); + } + else + { + separator = AknLayoutScalable_Avkon::popup_query_data_code_window_g1(5); + } + + TAknLayoutRect layout; + layout.LayoutRect(TRect(), separator); + TRect rect(layout.Rect()); + return (TInt16)(rect.iTl.iY + rect.Height()); + } + +TInt16 CAknMultilineQueryControl::SecondLineHeight() const + { + TIndex LAFIndex(iLinePos,iSecondQueryPromptLines,iFirstQueryPromptLines); + + TAknWindowLineLayout separator; + if(!AknLayoutUtils::PenEnabled()) + { + separator = + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3()); + } + else + { + separator = AknLayoutScalable_Avkon::popup_query_data_code_window_g1(5); + } + TAknLayoutRect layout; + layout.LayoutRect(TRect(), separator); + TRect rect(layout.Rect()); + return (TInt16)(rect.iTl.iY + rect.Height()); + } + + +/** + * Draw method. + * + * Draw line between query lines only if we are the first line. + */ +void CAknMultilineQueryControl::Draw(const TRect& aRect) const + { + if (Layout_Meta_Data::IsLandscapeOrientation()) + { + CAknQueryControl::Draw(aRect); + return; + } + + CWindowGc& gc=SystemGc(); + TRect rect(Rect()); + + if (IsSecond()) + { + TAknWindowLineLayout dimension; + WindowLayout( dimension ); + + TAknLayoutRect layout; + layout.LayoutRect(iAvkonAppUi->ClientRect(), dimension); + TRect rect2(layout.Rect()); + TAknWindowLineLayout layoutLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(rect2,0); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect(rect2, layoutLine); + TRect rect3(layoutRect.Rect()); + rect.iBr.iY += rect3.Height() - rect.Height(); + } + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + if( CAknEnv::Static()->TransparencyEnabled() ) + { + RRegion clipReg; + clipReg.AddRect( rect ); + + if ( iHasEditor ) + { + clipReg.SubRect( iEditorFrame.Rect() ); + } + + if ( iEditIndicator ) + { + clipReg.SubRect( + TRect( iEditIndicator->Position(), + iEditIndicator->Size() ) ); + } + + gc.SetClippingRegion( clipReg ); + clipReg.Close(); + + AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage ); + + clipReg.AddRect( rect ); + + CCoeControl* ctrl = const_cast(this)->ControlByLayoutOrNull( iQueryType ); + if ( ctrl ) + { + clipReg.SubRect( ctrl->Rect() ); + } + + gc.CancelClippingRegion(); + gc.SetClippingRegion( clipReg ); + clipReg.Close(); + } + else + { + AknsDrawUtils::Background( skin, cc, this, gc, rect ); + } + + DrawEditorFrame(gc,rect); + + if( CAknEnv::Static()->TransparencyEnabled() ) + { + gc.CancelClippingRegion(); + } + + //if (iLinePos == EFirstLine || !Layout_Meta_Data::IsLandscapeOrientation()) + // iLayoutLineBetweenEntryFields.DrawRect(SystemGc()); + } + +void CAknMultilineQueryControl::WindowLayout( TAknWindowLineLayout& aLayout ) const + { + if (Layout_Meta_Data::IsLandscapeOrientation()) + { + TInt variety = 0; + TInt promptLines = ( iLinePos == EFirstLine ? iFirstQueryPromptLines-1 : iSecondQueryPromptLines-1 ); + + if (promptLines < 0) + { + promptLines = 0; + } + + AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); + + if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight) + { + static const TInt KPopupQueryDataWindowIndex[7] = + {13, 12, 11, 10, 9, 8, 7}; // variety numbers for right CBA are 7-13 + + variety = KPopupQueryDataWindowIndex[promptLines]; + } + else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft) + { + static const TInt KPopupQueryDataWindowIndex[7] = + {20, 19, 18, 17, 16, 15, 14}; // variety numbers for left CBA are 14-20 + variety = KPopupQueryDataWindowIndex[promptLines]; + } + else // bottom + { + static const TInt KPopupQueryDataWindowIndex[7] = + {0, 1, 2, 3, 4, 5, 6}; // variety numbers for bottom CBA are 0-6 + variety = KPopupQueryDataWindowIndex[promptLines]; + } + + if(!AknLayoutUtils::PenEnabled()) + { + aLayout = AknLayoutScalable_Avkon::popup_query_data_window(variety); + } + else + { + TBool button=EFalse; + + if(button || promptLines) + { + aLayout = AknLayoutScalable_Avkon::popup_query_code_window(4); + } + else + { + aLayout = AknLayoutScalable_Avkon::popup_query_code_window(3); + } + } + } + else + { + if(!AknLayoutUtils::PenEnabled()) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + aLayout = AKN_LAYOUT_WINDOW_popup_query_data_code_window(LAFIndex.MainPanePQDCWindow()); + } + else + { + aLayout = AknLayoutScalable_Avkon::popup_query_data_code_window(2); + } + } + } + +void CAknMultilineQueryControl::SizeChanged() + { + DialogSizeChanged(); + + LayoutPrompt(ECombinedCodeDataQueryLayoutM); + LayoutSeparator(ECombinedCodeDataQueryLayoutM); + LayoutEditor(ECombinedCodeDataQueryLayoutM); + + CAknQueryExtension* extension = QueryExtension(); + if( iHasEditor && extension && extension->EditorContext() ) + { + // Layout editor context + TAknLayoutRect topLeft; + TAknLayoutRect bottomRight; + + topLeft.LayoutRect(iEditorFrame.Rect(), SkinLayout::Input_field_skin_placing__general__Line_2()); + bottomRight.LayoutRect(TRect(iEditorFrame.Rect().iBr, iEditorFrame.Rect().iBr), SkinLayout::Input_field_skin_placing__general__Line_5()); + + TRect outerRect = TRect(topLeft.Rect().iTl, bottomRight.Rect().iBr); + TRect innerRect = TRect(topLeft.Rect().iBr, bottomRight.Rect().iTl); + + extension->EditorContext()->SetFrameRects( outerRect, innerRect ); + // Chain with the background (since the frame doesn't occupy the entire + // layout and it may even be transparent) + extension->EditorContext()->SetParentContext( AknsDrawUtils::ControlContextOfParent( this ) ); + + } + + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->ChangeFeedbackArea( this, 0, Rect() ); + feedback->EnableFeedbackForControl( this, !(IsFocused() || Layout_Meta_Data::IsLandscapeOrientation()) ); + } + } + +EXPORT_C void CAknMultilineQueryControl::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + CAknQueryControl::HandlePointerEventL(aPointerEvent); + } + +EXPORT_C void* CAknMultilineQueryControl::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +/** + * Layout the query prompt + */ +void CAknMultilineQueryControl::LayoutPrompt(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + iPrompt->SetRect(DialogRect()); + TRect rect = LayoutRect(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color; + TInt error = AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 ); + + for (TInt i = 0; i < NbrOfPromptLines(); i++) + { + if (iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + AknLayoutUtils::LayoutLabel(iPrompt->Line(i), rect, + AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_1 + (LAFIndex.CDCQPWindowTextsLine1(i))); + + else if (iLinePos == ESecondLine) + { + if(!AknLayoutUtils::PenEnabled()) + { + AknLayoutUtils::LayoutLabel(iPrompt->Line(i),rect, + AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_3 + (LAFIndex.CDCQPWindowTextsLine3(i))); + } + else + { + TAknTextComponentLayout promtLineVariant; + if(i == 0) + { + promtLineVariant = AknLayoutScalable_Avkon::popup_query_data_code_window_t3(0); + } + else + { + promtLineVariant = AknLayoutScalable_Avkon::popup_query_data_code_window_t4(0); + } + AknLayoutUtils::LayoutLabel(iPrompt->Line(i),rect,promtLineVariant); + } + } + + else + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + + if (!error) + { + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iPrompt->Line(i), EColorLabelText, color ) ); + } + + } + } +/** + * Layout the separation line between the two queries + */ +void CAknMultilineQueryControl::LayoutSeparator(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + iLayoutLineBetweenEntryFields.LayoutRect(LayoutRect(), + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3())); + } + +/** + * Following four function classes allow passing the AknLayoutUtils fcn as as + * parameter to DoLayoutEditor() + */ + +/** + * Layout text editors + */ +class FLayoutEdwin + { +public: + FLayoutEdwin() { } + void operator() (CEikEdwin* aEd, const TRect& aRect, const TAknWindowComponentLayout& aLay, + const CFont* aFont, TBool aMinimizedView) const + { + TAknTextLineLayout lay = TAknWindowComponentLayout::ComposeText(aLay, AknLayoutScalable_Avkon::query_popup_data_pane_t1(0)).LayoutLine(); + AknLayoutUtils::LayoutEdwin(aEd,aRect,lay,EAknsCIQsnTextColorsCG27,aFont,aMinimizedView); + AknsUtils::RegisterControlPosition(aEd); + } + }; + +/** + * Layout editors containing secret codes + */ +class FLayoutSecretEditor + { +public: + FLayoutSecretEditor() { } + void operator() (CEikSecretEditor* aEd, const TRect& aRect, const TAknWindowComponentLayout& aLay, + const CFont* /*aFont*/, TBool /*aMinimizedView*/) const + { + TAknTextLineLayout lay = TAknWindowComponentLayout::ComposeText(aLay, AknLayoutScalable_Avkon::query_popup_pane_t1()).LayoutLine(); + AknLayoutUtils::LayoutSecretEditor(aEd,aRect,lay); + AknsUtils::RegisterControlPosition(aEd); + } + }; + +/** + * Layout numeric editors + */ +class FLayoutNumericEdwin + { +public: + FLayoutNumericEdwin() { } + void operator() (CAknNumericEdwin* aEd, const TRect& aRect, const TAknWindowComponentLayout& aLay, + const CFont* aFont, TBool aMinimizedView) const + { + TAknTextLineLayout lay = TAknWindowComponentLayout::ComposeText(aLay, AknLayoutScalable_Avkon::query_popup_data_pane_t1(0)).LayoutLine(); + AknLayoutUtils::LayoutEdwin(aEd,aRect,lay,EAknsCIQsnTextColorsCG27,aFont,aMinimizedView); + AknsUtils::RegisterControlPosition(aEd); + } + }; + +/** + * Layout multifield numeric editors (MFNEs) + */ +class FLayoutMfne + { +public: + FLayoutMfne(){ } + void operator() (CEikMfne* aEd, const TRect& aRect, const TAknWindowComponentLayout& aLay, + const CFont* /*aFont*/, TBool /*aMinimizedView*/) const + { + TAknTextLineLayout lay = TAknWindowComponentLayout::ComposeText(aLay, AknLayoutScalable_Avkon::query_popup_pane_t1()).LayoutLine(); + AknLayoutUtils::LayoutMfne(aEd,aRect,lay); + AknsUtils::RegisterControlPosition(aEd); + } + }; + +/** + * Layout a single editor + */ +template +void DoLayoutEditor(const TRect& aRect, Edt* aEd, Fct aFcn, const CAknMultilineQueryControl::TIndex& aLAFIndex,TBool aButton,TInt aNbrPromptLines, + const CFont* aCustomFont=0, TBool aMinimizeEdwinView=EFalse) + { + if (aEd) + { + if (aLAFIndex.LinePos() == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + if(!AknLayoutUtils::PenEnabled() || !aButton) + { + aFcn(aEd, aRect, + AknLayoutScalable_Avkon::query_popup_data_pane_cp2(aLAFIndex.CDCQPWindowTextsLine2()),aCustomFont,aMinimizeEdwinView); + } + else + { + TAknLayoutRect editRect; + editRect.LayoutRect(aRect,AknLayoutScalable_Avkon::cont_query_data_pane()); + aFcn(aEd, editRect.Rect(), + AknLayoutScalable_Avkon::query_popup_pane_cp3(),aCustomFont,aMinimizeEdwinView); + } + } + + else if (aLAFIndex.LinePos() == ESecondLine) + { + if(!AknLayoutUtils::PenEnabled()) + { + aFcn(aEd, aRect, + AknLayoutScalable_Avkon::query_popup_pane_cp2(aLAFIndex.CDCQPWindowTextsLine4()),aCustomFont,aMinimizeEdwinView); + } + else + { + if(!aButton) + { + if(aNbrPromptLines == 1) + { + aFcn(aEd, aRect,AknLayoutScalable_Avkon::query_popup_pane_cp2(5),aCustomFont,aMinimizeEdwinView); + } + else //aNbrPromptLines = 2 + { + aFcn(aEd, aRect,AknLayoutScalable_Avkon::query_popup_pane_cp2(0),aCustomFont,aMinimizeEdwinView); + } + } + else + { + TAknLayoutRect editRect; + editRect.LayoutRect(aRect,AknLayoutScalable_Avkon::cont_query_data_pane_cp1()); + aFcn(aEd, editRect.Rect(), + AknLayoutScalable_Avkon::query_popup_pane_cp3(),aCustomFont,aMinimizeEdwinView); + } + } + } + + else + #ifdef _DEBUG + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + #endif + + aEd->SetBorder(TGulBorder::ENone); + } + } + +/** + * Layout every editor + * + */ +void CAknMultilineQueryControl::LayoutEditor(const TLayoutMethod& aLayoutM) + { + TRect rect = LayoutRect(); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + TIndex LAFIndex2(iLinePos,iSecondQueryPromptLines,iSecondQueryPromptLines); + + const TIndex *index = &LAFIndex; + if (Layout_Meta_Data::IsLandscapeOrientation() && iLinePos == ESecondLine) + { + index = &LAFIndex2; + } + + iHasEditor = ETrue; + LayoutEditorFrame(aLayoutM); + LayoutEditorIndicator(aLayoutM); + + TBool button=EFalse; + + TInt nbrPromptLines = CAknQueryControl::NbrOfPromptLines(); + DoLayoutEditor(rect,iEdwin,FLayoutEdwin(),*index,button,nbrPromptLines,0,ETrue); + DoLayoutEditor(rect,iSecretEd,FLayoutSecretEditor(),*index,button,nbrPromptLines); + + DoLayoutEditor(rect,iTimeEdwin,FLayoutMfne(),*index,button,nbrPromptLines); + DoLayoutEditor(rect,iDateEdwin,FLayoutMfne(),*index,button,nbrPromptLines); + + DoLayoutEditor(rect,iDurationEdwin,FLayoutMfne(),*index,button,nbrPromptLines); + DoLayoutEditor(rect,iNumberEdwin,FLayoutNumericEdwin(),*index,button,nbrPromptLines); + + DoLayoutEditor(rect,iPinEdwin,FLayoutSecretEditor(),*index,button,nbrPromptLines); + DoLayoutEditor(rect,LocationEd(),FLayoutMfne(),*index,button,nbrPromptLines); + } + +/** + * Layout the editor frame + */ +void CAknMultilineQueryControl::LayoutEditorFrame(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + TIndex LAFIndex2(EFirstLine,iSecondQueryPromptLines,iSecondQueryPromptLines); + TRect rect = LayoutRect(); + + const TIndex *index = &LAFIndex; + if (Layout_Meta_Data::IsLandscapeOrientation() && iLinePos == ESecondLine) + { + index = &LAFIndex2; + } + iEditorVerShadow.LayoutRect(rect, + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_1(!IsFocused(),index->CDCQPWindowLine1())); + + iEditorHorShadow.LayoutRect(rect, + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_2(!IsFocused(),index->CDCQPWindowLine2())); + + TBool button=EFalse; + + if(!AknLayoutUtils::PenEnabled()) + { + iEditorFrame.LayoutRect (rect, + AknLayout::Combined_data_and_code_query_pop_up_window_elements_Line_4(index->CDCQPWindowRectangles())); + } + else + { + if(!button) + { + if(iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + if(NbrOfPromptLines() == 1) + { + iEditorFrame.LayoutRect(rect,AknLayoutScalable_Avkon::query_popup_pane_cp2(4)); + } + else //2 lines + { + iEditorFrame.LayoutRect(rect,AknLayoutScalable_Avkon::query_popup_data_pane_cp2(0)); + } + } + else + { + if(NbrOfPromptLines() == 1) + { + iEditorFrame.LayoutRect(rect,AknLayoutScalable_Avkon::query_popup_pane_cp2(5)); + } + else + { + iEditorFrame.LayoutRect(rect,AknLayoutScalable_Avkon::query_popup_pane_cp2(0)); + } + } + } + else + { + TAknLayoutRect rectEditorFrame; + TAknLayoutRect popupRect; + if(iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + popupRect.LayoutRect(rect,AknLayoutScalable_Avkon::cont_query_data_pane()); + } + else + { + popupRect.LayoutRect(rect,AknLayoutScalable_Avkon::cont_query_data_pane_cp1()); + } + iEditorFrame.LayoutRect(popupRect.Rect(),AknLayoutScalable_Avkon::query_popup_pane_cp3()); + } + } + } + +/** + * Layout the editor indicator icons + */ +void CAknMultilineQueryControl::LayoutEditorIndicator(const TLayoutMethod& /*aLayoutM*/) + { + CCoeControl* editor = ControlByLayoutOrNull(iQueryType); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + if (!iEditIndicator || !editor || iFlags.IsSet(EEditorIndicatorOff)) + return; + + if (editor->IsFocused()) + { + TAknWindowLineLayout indicatorLine; + + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + TInt promptLines = ( iLinePos == EFirstLine ? + iFirstQueryPromptLines : iSecondQueryPromptLines ); + + static const TInt lineTable[4] = { 2, 2, 1, 3 }; + + indicatorLine = AknLayoutScalable_Avkon::indicator_popup_pane_cp4( lineTable[promptLines] ).LayoutLine(); + } + else + { + if(iLinePos == ESecondLine && AknLayoutUtils::PenEnabled()) + { + if(NbrOfPromptLines() == 1) + { + indicatorLine = AknLayoutScalable_Avkon::indicator_popup_pane_cp2(5); + } + else + { + indicatorLine = AknLayoutScalable_Avkon::indicator_popup_pane_cp2(0); + } + } + else + { + indicatorLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_5(LAFIndex.CDCQPWindowLine5()); + } + } + + AknLayoutUtils::LayoutControl( iEditIndicator, LayoutRect(), indicatorLine ); + } + else + iEditIndicator->SetRect(TRect(TPoint(0,0),TPoint(0,0))); + } + + +EXPORT_C void CAknMultilineQueryControl::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + CAknQueryExtension* extension = QueryExtension(); + if( iHasEditor && extension && extension->EditorContext() ) + { + extension->EditorContext()->SetParentContext( AknsDrawUtils::ControlContextOfParent( this ) ); + } + } + else if( aType == KEikDynamicLayoutVariantSwitch ) // JLa 22.09.2006 + { + SizeChanged(); + } + } + + +/***************************************************************** + * CAknMultilineQueryControl::TIndex + * + * Manage indexes into LAF tables + * + * PQDC stands for 'Popup Query Data Code' + * + * CDCQP stands for 'Combined Data Code Query Popup' + ******************************************************************/ + +/** + * Construction, iLinePos is the position of the current line, either first or + * second. iFirstLine is the numeber of prompt lines for the first query, either 1 + * or 2. iSecondline is the number of prompt lines for the second query, either 1 or 2 + */ +CAknMultilineQueryControl::TIndex::TIndex(const TLinePosition& aLinePos, + TInt aFirstQueryPromptLines, TInt aSecondQueryPromptLines) : + iLinePos(aLinePos), iFirstQueryPromptLines(aFirstQueryPromptLines), iSecondQueryPromptLines(aSecondQueryPromptLines) + { + } + +/** + * Check that we are in a consistent state for retrieving correct indexes + * + */ +void CAknMultilineQueryControl::TIndex::SelfTest() const + { + __ASSERT_DEBUG(iLinePos == EFirstLine || iLinePos == ESecondLine, + Panic(EAknPanicInvalidValue)); + __ASSERT_DEBUG(iFirstQueryPromptLines >= 0 && iFirstQueryPromptLines <= 2, + Panic(EAknPanicInvalidValue)); + __ASSERT_DEBUG(iSecondQueryPromptLines >= 0 && iSecondQueryPromptLines <= 2, + Panic(EAknPanicInvalidValue)); + } + +/** + * We tolerate a null number of prompt lines. If this is the case we set + * the number of lines to 1 (empty query will use layout of a query with a + * line of text). + */ +TInt CAknMultilineQueryControl::TIndex::FirstQueryPromptLines() const + { + SelfTest(); + return iFirstQueryPromptLines > 0 ? iFirstQueryPromptLines - 1 : 1; + } + +/** + * We tolerate a null number of prompt lines. If this is the case we set + * the number of lines to 1 (empty query will use layout of a query with a + * line of text). + */ +TInt CAknMultilineQueryControl::TIndex::SecondQueryPromptLines() const + { + SelfTest(); + return iSecondQueryPromptLines > 0 ? iSecondQueryPromptLines - 1: 1; + } + + +/** + * Return index into Main Pane PQDC Window, which + * depends on total number of prompt lines minus 2, e.g. + * index 0 for 2 prompt lines total. + * + */ +TInt CAknMultilineQueryControl::TIndex::MainPanePQDCWindow() const + { + SelfTest(); + static const TInt KMainPanePQDCWindow[3] = {0,1,2}; + return KMainPanePQDCWindow[FirstQueryPromptLines() + SecondQueryPromptLines()]; + } + +/** + * Return index into PQDC Window Rectangles, which + * depends on line position and number or prompt lines in + * both queries. + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowLine1() const + { + SelfTest(); + static const TInt KPQDCWindowRectanglesIndex[2][2][2] = + { + {{0,4},{2,6}}, //First line + {{1,5},{3,7}} //Second line + }; + return KPQDCWindowRectanglesIndex[(TInt)iLinePos][FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowLine2() const + { + return CDCQPWindowLine1(); + } + +/** + * Return index into PQDC Window Line 3, which depends on number of prompt + * lines in both queries + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowLine3() const + { + SelfTest(); + static const TInt KCDCQPWindowLine3Index[2][2] = + { + {0,2}, + {1,3} + }; + return KCDCQPWindowLine3Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowRectangles() const + { + return CDCQPWindowLine1(); + } + +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowLine5() const + { + return CDCQPWindowLine1(); + } + + +/** + * Return index into 'CDCQP Window texts Line 1', which + * depends on total number of promt lines and current + * prompt line number (received as parameter) + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowTextsLine1(TInt aLineNum) const + { + SelfTest(); + __ASSERT_DEBUG(aLineNum >= 0 && aLineNum < 2,Panic(EAknPanicInvalidValue)); + + static const TInt KPQDCWindowTextsLine1Index[2][3] = { + {0,0,2}, //First prompt line + {1,1,3} //Second prompt line + }; + return KPQDCWindowTextsLine1Index[aLineNum][FirstQueryPromptLines() + SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window texts Line 2', which + * depends on number of prompt lines in both queries + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowTextsLine2() const + { + static const TInt KPQDCWindowTextsLine2Index[2][2] = { + {3,2}, + {1,0} + }; + return KPQDCWindowTextsLine2Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + + } + +/** + * Return index into 'CDCQP Window texts Line 3', which + * depends on number of promt lines and current + * prompt line number (received as parameter) + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowTextsLine3(TInt aLineNum) const + { + SelfTest(); + __ASSERT_DEBUG(aLineNum >= 0 && aLineNum < 2,Panic(EAknPanicInvalidValue)); + + static const TInt KPQDCWindowTextsLine3Index[2][2][2] = { + {{0,0}, {2,3}}, //First prompt line + {{1,1}, {2,4}} //Second Prompt Line + }; + return KPQDCWindowTextsLine3Index[aLineNum][FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window texts Line 4', which + * depends on number of prompt lines in both queries + */ +TInt CAknMultilineQueryControl::TIndex::CDCQPWindowTextsLine4() const + { + static const TInt KPQDCWindowTextsLine4Index[2][2] = { + {3,2}, + {1,0} + }; + return KPQDCWindowTextsLine4Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window graphics Line 5', which + * depends on number of prompt lines in both queries + */ +TInt CAknMultilineQueryControl::TIndex::CDCPQWindowGraphicsLine5() const + { + static const TInt KCDCPQWindowGraphicsLine5Index[2][2] = { + {0,0}, + {0,1} + }; + return KCDCPQWindowGraphicsLine5Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + + + + +/***************************** + * CAknExtMultilineQueryControl + *****************************/ + + + +EXPORT_C CAknExtMultilineQueryControl::CAknExtMultilineQueryControl() + : CAknExtQueryControl(), iLinePos(EFirstLine) + { + AKNTASHOOK_ADD( this, "CAknExtMultilineQueryControl" ); + } + +// +//Destructor +// +EXPORT_C CAknExtMultilineQueryControl::~CAknExtMultilineQueryControl() + + { + AKNTASHOOK_REMOVE(); + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->RemoveFeedbackForControl( this ); + } + } + +/** + *Initializes the member data from resource + */ +void CAknExtMultilineQueryControl::ConstructQueryL(TResourceReader& aRes) + { + SetLinePosition(); + + if ( iQueryType == EMultiDataFirstIpEd || iQueryType == EMultiDataSecondIpEd ) + { + iIpEditor = new(ELeave)CAknIpFieldEditor; + iIpEditor->SetContainerWindowL(*this); + iIpEditor->ConstructFromResourceL(aRes); + iIpEditor->SetObserver(this); + iIpEditor->SetSkinTextColorL(EAknsCIQsnTextColorsCG27); + if ( AknLayoutUtils::PenEnabled() ) + { + iIpEditor->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight ); + } + } + + // Construct editor context + CAknQueryExtension* extension = QueryExtension(); + if( extension ) + { + extension->CreateEditorContextL(); + } + + MTouchFeedback* feedback = MTouchFeedback::Instance(); + CFeedbackSpec* spec = CFeedbackSpec::New(); + if ( feedback && spec ) + { + spec->AddFeedback( ETouchEventStylusDown, + ETouchFeedbackSensitiveList ); + feedback->SetFeedbackArea( this, 0, Rect(), spec ); + delete spec; + } + } + + +/** + * Layout rectangle (shift up and left by margins) + */ +TRect CAknExtMultilineQueryControl::LayoutRect() + { + TPoint topLeft(0,0); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + TAknLayoutRect layout; + layout.LayoutRect(DialogRect(), AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(DialogRect(), LAFIndex.CDCPQWindowGraphicsLine5())); + + TRect rect(layout.Rect()); + topLeft.iX -= rect.iTl.iX; + topLeft.iY -= rect.iTl.iY; + + TPoint bottomRight (topLeft); + TSize size (MinimumSize()); + bottomRight.iY += size.iHeight; + bottomRight.iX += size.iWidth; + + return TRect(topLeft,bottomRight); + } + + +/** + * Depending on layout type determine control position in the dialog + */ +void CAknExtMultilineQueryControl::SetLinePosition() + { + if ( iQueryType == EMultiDataSecondIpEd ) + { + iLinePos = ESecondLine; + } + } + + +/** + * Set the line width for the prompt lines + * + * This is a virtual method called by CAknQueryControl::DoSetPromptL() + * + * Depending on LAF information and on weather we are the first or the second + * query line, we can work out the line widths by indexing the LAF tables. + * + */ +void CAknExtMultilineQueryControl::SetLineWidthsL() + { + if (!iLineWidths) + return; + + iLineWidths->Reset(); + + TAknLayoutRect parentLayoutRect; + + if (Layout_Meta_Data::IsLandscapeOrientation()) + parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_window(0)); + else + parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_code_window(0)); + + //parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AKN_LAYOUT_WINDOW_popup_query_data_code_window(0)); + TAknLayoutText textRect; + + for (TInt i = 0; i < 2; i++) + { + if (iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_1(0)); + iLineWidths->AppendL(textRect.TextRect().Width()); + } + else if (iLinePos == ESecondLine) + { + textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_3(0)); + iLineWidths->AppendL(textRect.TextRect().Width()); + } + } + } + + +EXPORT_C TBool CAknExtMultilineQueryControl::IsFirst() const + { + return iLinePos == EFirstLine; + } + +EXPORT_C TBool CAknExtMultilineQueryControl::IsSecond() const + { + return !IsFirst(); + } + +/** + * Set the number of prompt lines. + * + * The query dialog calls this method in order to communicate the number of prompt lines + * in the other query line. Indexing into LAF tables depends on this. + * + */ +EXPORT_C void CAknExtMultilineQueryControl::SetNbrOfPromptLines( + TInt aNbrOfPromptLinesFirstLine, + TInt aNbrOfPromptLinesSecondLine) + { + iFirstQueryPromptLines = aNbrOfPromptLinesFirstLine; + iSecondQueryPromptLines = aNbrOfPromptLinesSecondLine; + } + + +EXPORT_C CCoeControl* CAknExtMultilineQueryControl::ControlByLayoutOrNull(TInt aLayout) + { + CCoeControl* ctrl=NULL; + if ( aLayout == EMultiDataFirstIpEd || aLayout == EMultiDataSecondIpEd ) + { + ctrl = iIpEditor; + } + return ctrl; + } + + +/** + * Return control minimum size + * + * Size is calculated by using LAF tables. Index in this table depends on the + * total number of prompt lines in both queries + */ +EXPORT_C TSize CAknExtMultilineQueryControl::MinimumSize() + { + TAknLayoutRect layout; + TAknWindowLineLayout window; + WindowLayout( window ); + + TRect mainPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, mainPane ); + layout.LayoutRect( mainPane, window ); + TRect rect2(layout.Rect()); + TSize size = rect2.Size(); + + if (IsFirst()) + { + size.iHeight = FirstLineHeight(); + } + else if (Layout_Meta_Data::IsLandscapeOrientation() && IsSecond()) + { + size.iHeight = SecondLineHeight(); + } + else if (IsSecond()) + { + TAknWindowLineLayout layoutLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(DialogRect(),0); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect(rect2, layoutLine); + TRect rect(layoutRect.Rect()); + size.iHeight = rect.Height() - FirstLineHeight(); + } + + else + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + + return size; + } + + +/** + * Return height of first line control, use separator to determine this. + */ +TInt16 CAknExtMultilineQueryControl::FirstLineHeight() const + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + TAknWindowLineLayout separator = + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3()); + + TAknLayoutRect layout; + layout.LayoutRect(TRect(), separator); + TRect rect(layout.Rect()); + return (TInt16)(rect.iTl.iY + rect.Height()); + } + +TInt16 CAknExtMultilineQueryControl::SecondLineHeight() const + { + TIndex LAFIndex(iLinePos,iSecondQueryPromptLines,iFirstQueryPromptLines); + + TAknWindowLineLayout separator = + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3()); + + TAknLayoutRect layout; + layout.LayoutRect(TRect(), separator); + TRect rect(layout.Rect()); + return (TInt16)(rect.iTl.iY + rect.Height()); + } + + +/** + * Draw method. + * + * Draw line between query lines only if we are the first line. + */ + +void CAknExtMultilineQueryControl::Draw(const TRect& aRect) const + { + if (Layout_Meta_Data::IsLandscapeOrientation()) + { + if( CAknEnv::Static()->TransparencyEnabled() ) + { + if ( IsFocused() ) + { + CAknExtQueryControl::Draw(aRect); + } + } + else + { + CAknExtQueryControl::Draw(aRect); + } + return; + } + + CWindowGc& gc=SystemGc(); + TRect rect(Rect()); + + if (IsSecond()) + { + TAknWindowLineLayout dimension; + WindowLayout( dimension ); + + TAknLayoutRect layout; + layout.LayoutRect(iAvkonAppUi->ClientRect(), dimension); + TRect rect2(layout.Rect()); + TAknWindowLineLayout layoutLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_graphics_Line_5(rect2,0); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect(rect2, layoutLine); + TRect rect3(layoutRect.Rect()); + rect.iBr.iY += rect3.Height() - rect.Height(); + } + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + if( CAknEnv::Static()->TransparencyEnabled() ) + { + RRegion clipReg; + clipReg.AddRect( rect ); + + if ( iHasEditor ) + { + clipReg.SubRect( iEditorFrame.Rect() ); + } + + if ( iEditIndicator ) + { + clipReg.SubRect( + TRect( iEditIndicator->Position(), + iEditIndicator->Size() ) ); + } + + gc.SetClippingRegion( clipReg ); + clipReg.Close(); + + AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage ); + + clipReg.AddRect( rect ); + + CCoeControl* ctrl = const_cast(this)->ControlByLayoutOrNull( iQueryType ); + if ( ctrl ) + { + clipReg.SubRect( ctrl->Rect() ); + } + + gc.CancelClippingRegion(); + gc.SetClippingRegion( clipReg ); + clipReg.Close(); + } + else + { + AknsDrawUtils::Background( skin, cc, this, gc, rect ); + } + + DrawEditorFrame(gc,rect); + + if( CAknEnv::Static()->TransparencyEnabled() ) + { + gc.CancelClippingRegion(); + } + } + + +EXPORT_C void CAknExtMultilineQueryControl::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + CAknExtQueryControl::HandlePointerEventL(aPointerEvent); + } + +EXPORT_C void* CAknExtMultilineQueryControl::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + +void CAknExtMultilineQueryControl::WindowLayout( TAknWindowLineLayout& aLayout ) const + { + if (Layout_Meta_Data::IsLandscapeOrientation()) + { + TInt variety = 0; + TInt promptLines = ( iLinePos == EFirstLine ? iFirstQueryPromptLines-1 : iSecondQueryPromptLines-1 ); + + if (promptLines < 0) + { + promptLines = 0; + } + + AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); + + if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight) + { + static const TInt KPopupQueryDataWindowIndex[7] = + {13, 12, 11, 10, 9, 8, 7}; // variety numbers for right CBA are 7-13 + + variety = KPopupQueryDataWindowIndex[promptLines]; + } + else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft) + { + static const TInt KPopupQueryDataWindowIndex[7] = + {20, 19, 18, 17, 16, 15, 14}; // variety numbers for left CBA are 14-20 + variety = KPopupQueryDataWindowIndex[promptLines]; + } + else // bottom + { + static const TInt KPopupQueryDataWindowIndex[7] = + {0, 1, 2, 3, 4, 5, 6}; // variety numbers for bottom CBA are 0-6 + variety = KPopupQueryDataWindowIndex[promptLines]; + } + + aLayout = AknLayoutScalable_Avkon::popup_query_data_window(variety); + } + else + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + aLayout = AKN_LAYOUT_WINDOW_popup_query_data_code_window(LAFIndex.MainPanePQDCWindow()); + } + } + + + +void CAknExtMultilineQueryControl::SizeChanged() + { + DialogSizeChanged(); + + LayoutPrompt(ECombinedCodeDataQueryLayoutM); + LayoutSeparator(ECombinedCodeDataQueryLayoutM); + LayoutEditor(ECombinedCodeDataQueryLayoutM); + + CAknQueryExtension* extension = QueryExtension(); + if( iHasEditor && extension && extension->EditorContext() ) + { + // Layout editor context + TAknLayoutRect topLeft; + TAknLayoutRect bottomRight; + + topLeft.LayoutRect(iEditorFrame.Rect(), SkinLayout::Input_field_skin_placing__general__Line_2()); + bottomRight.LayoutRect(TRect(iEditorFrame.Rect().iBr, iEditorFrame.Rect().iBr), SkinLayout::Input_field_skin_placing__general__Line_5()); + + TRect outerRect = TRect(topLeft.Rect().iTl, bottomRight.Rect().iBr); + TRect innerRect = TRect(topLeft.Rect().iBr, bottomRight.Rect().iTl); + + extension->EditorContext()->SetFrameRects( outerRect, innerRect ); + // Chain with the background (since the frame doesn't occupy the entire + // layout and it may even be transparent) + extension->EditorContext()->SetParentContext( AknsDrawUtils::ControlContextOfParent( this ) ); + } + + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->ChangeFeedbackArea( this, 0, Rect() ); + feedback->EnableFeedbackForControl( this, !(IsFocused() || Layout_Meta_Data::IsLandscapeOrientation()) ); + } + } + +/** + * Layout the query prompt + */ +void CAknExtMultilineQueryControl::LayoutPrompt(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + iPrompt->SetRect(DialogRect()); + TRect rect = LayoutRect(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color; + TInt error = AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 ); + + for (TInt i = 0; i < NbrOfPromptLines(); i++) + { + if (iLinePos == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + AknLayoutUtils::LayoutLabel(iPrompt->Line(i), rect, + AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_1 + (LAFIndex.CDCQPWindowTextsLine1(i))); + + else if (iLinePos == ESecondLine) + AknLayoutUtils::LayoutLabel(iPrompt->Line(i),rect, + AKN_LAYOUT_TEXT_Combined_data_and_code_query_pop_up_window_texts_Line_3 + (LAFIndex.CDCQPWindowTextsLine3(i))); + + else + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + + if (!error) + { + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iPrompt->Line(i), EColorLabelText, color ) ); + } + } + } +/** + * Layout the separation line between the two queries + */ +void CAknExtMultilineQueryControl::LayoutSeparator(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + iLayoutLineBetweenEntryFields.LayoutRect(LayoutRect(), + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_3 + (LAFIndex.CDCQPWindowLine3())); + } + + +/** + * Layout multifield numeric editors (MFNEs) + */ +class FLayoutMfne2 + { +public: + FLayoutMfne2(){ } + void operator() (CEikMfne* aEd, const TRect& aRect, const TAknWindowComponentLayout& aLay, + const CFont* /*aFont*/, TBool /*aMinimizedView*/) const + { + TAknTextLineLayout lay = TAknWindowComponentLayout::ComposeText(aLay, AknLayoutScalable_Avkon::query_popup_pane_t1()).LayoutLine(); + AknLayoutUtils::LayoutMfne(aEd,aRect,lay); + AknsUtils::RegisterControlPosition(aEd); + } + }; + +/** + * Layout a single editor + */ +template +void DoLayoutEditor(const TRect& aRect, Edt* aEd, Fct aFcn, const CAknExtMultilineQueryControl::TIndex& aLAFIndex, + const CFont* aCustomFont=0, TBool aMinimizeEdwinView=EFalse) + { + if (aEd) + { + if (aLAFIndex.LinePos() == EFirstLine || Layout_Meta_Data::IsLandscapeOrientation()) + { + aFcn(aEd, aRect, + AknLayoutScalable_Avkon::query_popup_data_pane_cp2(aLAFIndex.CDCQPWindowTextsLine2()),aCustomFont,aMinimizeEdwinView); + } + else if (aLAFIndex.LinePos() == ESecondLine) + { + aFcn(aEd, aRect, + AknLayoutScalable_Avkon::query_popup_pane_cp2(aLAFIndex.CDCQPWindowTextsLine4()),aCustomFont,aMinimizeEdwinView); + } + else + #ifdef _DEBUG + __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); + #endif + + aEd->SetBorder(TGulBorder::ENone); + } + } + + +/** + * Layout every editor + * + */ +void CAknExtMultilineQueryControl::LayoutEditor(const TLayoutMethod& aLayoutM) + { + TRect rect = LayoutRect(); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + TIndex LAFIndex2(iLinePos,iSecondQueryPromptLines,iSecondQueryPromptLines); + + const TIndex *index = &LAFIndex; + if (Layout_Meta_Data::IsLandscapeOrientation() && iLinePos == ESecondLine) + { + index = &LAFIndex2; + } + + iHasEditor = ETrue; + LayoutEditorFrame(aLayoutM); + LayoutEditorIndicator(aLayoutM); + + DoLayoutEditor(rect,iIpEditor,FLayoutMfne2(), *index); + } + +/** + * Layout the editor frame + */ +void CAknExtMultilineQueryControl::LayoutEditorFrame(const TLayoutMethod& /*aLayoutM*/) + { + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + TIndex LAFIndex2(EFirstLine,iSecondQueryPromptLines,iSecondQueryPromptLines); + TRect rect = LayoutRect(); + + const TIndex *index = &LAFIndex; + if (Layout_Meta_Data::IsLandscapeOrientation() && iLinePos == ESecondLine) + { + index = &LAFIndex2; + } + + iEditorVerShadow.LayoutRect(rect, + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_1(!IsFocused(), index->CDCQPWindowLine1())); + + iEditorHorShadow.LayoutRect(rect, + AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_2(!IsFocused(), index->CDCQPWindowLine2())); + + iEditorFrame.LayoutRect (rect, + AknLayout::Combined_data_and_code_query_pop_up_window_elements_Line_4(index->CDCQPWindowRectangles())); + } + +/** + * Layout the editor indicator icons + */ +void CAknExtMultilineQueryControl::LayoutEditorIndicator(const TLayoutMethod& /*aLayoutM*/) + { + CCoeControl* editor = ControlByLayoutOrNull(iQueryType); + TIndex LAFIndex(iLinePos,iFirstQueryPromptLines,iSecondQueryPromptLines); + + if (!iEditIndicator || !editor || iFlags.IsSet(EEditorIndicatorOff)) + return; + + if (editor->IsFocused()) + { + TAknWindowLineLayout indicatorLine; + + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + TInt promptLines = ( iLinePos == EFirstLine ? iFirstQueryPromptLines : iSecondQueryPromptLines ); + static const TInt lineTable[4] = { 2, 2, 1, 3 }; + indicatorLine = AknLayoutScalable_Avkon::indicator_popup_pane_cp4( lineTable[promptLines] ).LayoutLine(); + } + else + { + indicatorLine = AKN_LAYOUT_WINDOW_Combined_data_and_code_query_pop_up_window_elements_Line_5(LAFIndex.CDCQPWindowLine5()); + } + + AknLayoutUtils::LayoutControl( iEditIndicator, LayoutRect(), indicatorLine ); + } + else + iEditIndicator->SetRect(TRect(TPoint(0,0),TPoint(0,0))); + } + + +EXPORT_C void CAknExtMultilineQueryControl::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + CAknQueryExtension* extension = QueryExtension(); + if( iHasEditor && extension && extension->EditorContext() ) + { + extension->EditorContext()->SetParentContext( AknsDrawUtils::ControlContextOfParent( this ) ); + } + } + else if( aType == KEikDynamicLayoutVariantSwitch ) + { + SizeChanged(); + } + } + + +/***************************************************************** + * CAknExtMultilineQueryControl::TIndex + * + * Manage indexes into LAF tables + * + * PQDC stands for 'Popup Query Data Code' + * + * CDCQP stands for 'Combined Data Code Query Popup' + ******************************************************************/ + +/** + * Construction, iLinePos is the position of the current line, either first or + * second. iFirstLine is the numeber of prompt lines for the first query, either 1 + * or 2. iSecondline is the number of prompt lines for the second query, either 1 or 2 + */ +CAknExtMultilineQueryControl::TIndex::TIndex(const TLinePosition& aLinePos, + TInt aFirstQueryPromptLines, TInt aSecondQueryPromptLines) : + iLinePos(aLinePos), iFirstQueryPromptLines(aFirstQueryPromptLines), iSecondQueryPromptLines(aSecondQueryPromptLines) + { + } + +/** + * Check that we are in a consistent state for retrieving correct indexes + * + */ +void CAknExtMultilineQueryControl::TIndex::SelfTest() const + { + __ASSERT_DEBUG(iLinePos == EFirstLine || iLinePos == ESecondLine, + Panic(EAknPanicInvalidValue)); + __ASSERT_DEBUG(iFirstQueryPromptLines >= 0 && iFirstQueryPromptLines <= 2, + Panic(EAknPanicInvalidValue)); + __ASSERT_DEBUG(iSecondQueryPromptLines >= 0 && iSecondQueryPromptLines <= 2, + Panic(EAknPanicInvalidValue)); + } + +/** + * We tolerate a null number of prompt lines. If this is the case we set + * the number of lines to 1 (empty query will use layout of a query with a + * line of text). + */ +TInt CAknExtMultilineQueryControl::TIndex::FirstQueryPromptLines() const + { + SelfTest(); + return iFirstQueryPromptLines > 0 ? iFirstQueryPromptLines - 1 : 1; + } + +/** + * We tolerate a null number of prompt lines. If this is the case we set + * the number of lines to 1 (empty query will use layout of a query with a + * line of text). + */ +TInt CAknExtMultilineQueryControl::TIndex::SecondQueryPromptLines() const + { + SelfTest(); + return iSecondQueryPromptLines > 0 ? iSecondQueryPromptLines - 1: 1; + } + + +/** + * Return index into Main Pane PQDC Window, which + * depends on total number of prompt lines minus 2, e.g. + * index 0 for 2 prompt lines total. + * + */ +TInt CAknExtMultilineQueryControl::TIndex::MainPanePQDCWindow() const + { + SelfTest(); + static const TInt KMainPanePQDCWindow[3] = {0,1,2}; + return KMainPanePQDCWindow[FirstQueryPromptLines() + SecondQueryPromptLines()]; + } + +/** + * Return index into PQDC Window Rectangles, which + * depends on line position and number or prompt lines in + * both queries. + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowLine1() const + { + SelfTest(); + static const TInt KPQDCWindowRectanglesIndex[2][2][2] = + { + {{0,4},{2,6}}, //First line + {{1,5},{3,7}} //Second line + }; + return KPQDCWindowRectanglesIndex[(TInt)iLinePos][FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowLine2() const + { + return CDCQPWindowLine1(); + } + +/** + * Return index into PQDC Window Line 3, which depends on number of prompt + * lines in both queries + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowLine3() const + { + SelfTest(); + static const TInt KCDCQPWindowLine3Index[2][2] = + { + {0,2}, + {1,3} + }; + return KCDCQPWindowLine3Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowRectangles() const + { + return CDCQPWindowLine1(); + } + +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowLine5() const + { + return CDCQPWindowLine1(); + } + + +/** + * Return index into 'CDCQP Window texts Line 1', which + * depends on total number of promt lines and current + * prompt line number (received as parameter) + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowTextsLine1(TInt aLineNum) const + { + SelfTest(); + __ASSERT_DEBUG(aLineNum >= 0 && aLineNum < 2,Panic(EAknPanicInvalidValue)); + + static const TInt KPQDCWindowTextsLine1Index[2][3] = { + {0,0,2}, //First prompt line + {1,1,3} //Second prompt line + }; + return KPQDCWindowTextsLine1Index[aLineNum][FirstQueryPromptLines() + SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window texts Line 2', which + * depends on number of prompt lines in both queries + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowTextsLine2() const + { + static const TInt KPQDCWindowTextsLine2Index[2][2] = { + {3,2}, + {1,0} + }; + return KPQDCWindowTextsLine2Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + + } + +/** + * Return index into 'CDCQP Window texts Line 3', which + * depends on number of promt lines and current + * prompt line number (received as parameter) + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowTextsLine3(TInt aLineNum) const + { + SelfTest(); + __ASSERT_DEBUG(aLineNum >= 0 && aLineNum < 2,Panic(EAknPanicInvalidValue)); + + static const TInt KPQDCWindowTextsLine3Index[2][2][2] = { + {{0,0}, {2,3}}, //First prompt line + {{1,1}, {2,4}} //Second Prompt Line + }; + return KPQDCWindowTextsLine3Index[aLineNum][FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window texts Line 4', which + * depends on number of prompt lines in both queries + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCQPWindowTextsLine4() const + { + static const TInt KPQDCWindowTextsLine4Index[2][2] = { + {3,2}, + {1,0} + }; + return KPQDCWindowTextsLine4Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +/** + * Return index into 'CDCQP Window graphics Line 5', which + * depends on number of prompt lines in both queries + */ +TInt CAknExtMultilineQueryControl::TIndex::CDCPQWindowGraphicsLine5() const + { + static const TInt KCDCPQWindowGraphicsLine5Index[2][2] = { + {0,0}, + {0,1} + }; + return KCDCPQWindowGraphicsLine5Index[FirstQueryPromptLines()][SecondQueryPromptLines()]; + } + +// End of File