--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknQueryControl.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,3996 @@
+/*
+* 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: Implementation of AVKON query control.
+*
+*/
+
+
+// INCLUDE FILES
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefmacros.h>
+#endif
+#include "aknQueryControl.h" //This class
+#include <barsread.h> //For TResourceReader
+
+#include <aknenv.h>
+#include <AknBitmapAnimation.h>
+#include <aknconsts.h>
+#include <avkon.mbg>
+#include <avkon.rsg>
+#include <aknborders.h>
+#include <AknEcs.h>
+#include <aknedsts.h>
+#include <AknLayoutDef.h>
+#include <AknLayout.lag>
+
+#include "akntextcontrol.h"
+#include "aknqueryeditorindicator.h"
+#include "aknEditStateIndicator.h"
+#include "AknUtils.h"
+#include "aknnoteattributes.h"
+
+#include <AknsDrawUtils.h>
+#include <AknsConstants.h>
+#include <AknsFrameBackgroundControlContext.h>
+#include <AknsPointerStore.h>
+
+#include <in_sock.h>
+
+#include <AknPictographInterface.h>
+#include <AknPictographDrawerInterface.h>
+
+#include "AknQueryExtension.h"
+#include <skinlayout.cdl.h>
+
+#include <AknIconUtils.h>
+#include "aknappui.h"
+#include <layoutmetadata.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include "aknkeypad.h"
+
+
+#if defined( RD_SCALABLE_UI_V2)
+//class CAknButton is available from week 20 version 5.0 onwards
+#include "aknbutton.h"
+// For MAknMfneCommandObserver
+#include <aknmfnecommandobserver.h>
+#endif //if defined( RD_SCALABLE_UI_V2)
+#include <aknlocationed.h>
+
+#include <eikdialg.h>
+#include <eikdialogext.h>
+#include <gulicon.h>
+#include <StringLoader.h>
+
+#include <AknTasHook.h> // for testability hooks
+#include <tacticon.h>
+
+const TInt KPinCodeTacticonInterval = 30000000; // 30s
+const TInt KPinCodeMaxTacticons = 10;
+/*******
+ * CAknQueryControlExtension
+ */
+
+NONSHARABLE_CLASS(CAknQueryControlExtension) : public CBase
+{
+public:
+ ~CAknQueryControlExtension();
+
+ CAknLocationEditor *iLocationEd;
+
+ // Saved animation ID for later updates due to skin change.
+ // The value is saved in CAknQueryControl::ConstructQueryL().
+ TInt iAnimationId;
+
+ HBufC* iOriginalPrompt;
+ CAknButton* iBackspaceButton;
+ CAknKeypad* iKeypad;
+
+ // Flag indicating whether or not the query CBA has been
+ // changed to ECS softkeys (Call and Cancel).
+ TBool iEcsCbaShown;
+
+ // Timer for pincode query tacticon playback
+ CPeriodic* iPinTacticonTimer;
+ // Counter for tacticons played in a pincode query
+ TInt iPinTacticonsPlayed;
+};
+
+CAknQueryControlExtension::~CAknQueryControlExtension()
+ {
+ delete iOriginalPrompt;
+ delete iBackspaceButton;
+ delete iKeypad;
+
+ delete iPinTacticonTimer;
+ iPinTacticonTimer = NULL;
+ }
+
+CAknLocationEditor *CAknQueryControl::LocationEd() const
+{
+ if (iExtension)
+ return iExtension->iLocationEd;
+ else
+ return NULL;
+}
+CAknLocationEditor *&CAknQueryControl::LocationEd()
+{
+ return iExtension->iLocationEd;
+}
+
+
+/*****************************
+ * CAknQueryExtension
+ *****************************/
+
+void CAknQueryExtension::CreateEditorContextL()
+ {
+ delete iEditorContext;
+ iEditorContext = NULL;
+ iEditorContext = CAknsFrameBackgroundControlContext::NewL(
+ KAknsIIDQsnFrInput, TRect(0,0,1,1), TRect(0,0,1,1), EFalse );
+ }
+
+CAknsFrameBackgroundControlContext* CAknQueryExtension::EditorContext()
+ {
+ return iEditorContext;
+ }
+
+CAknQueryExtension* CAknQueryExtension::Instance(
+ const CAknQueryControl* aQueryControl )
+ {
+ return static_cast<CAknQueryExtension*>(
+ AknsPointerStore::RetrievePointer(
+ static_cast<const CBase*>(aQueryControl) ) );
+ }
+
+void CAknQueryExtension::CreateExtensionL(
+ const CAknQueryControl* aQueryControl )
+ {
+ CAknQueryExtension* extension = CAknQueryExtension::NewL();
+ CleanupStack::PushL( extension );
+ AknsPointerStore::StorePointerL(
+ static_cast<const CBase*>(aQueryControl), extension );
+ CleanupStack::Pop(); // extension
+ }
+
+void CAknQueryExtension::DestroyExtension(
+ const CAknQueryControl* aQueryControl )
+ {
+ delete Instance( aQueryControl );
+ AknsPointerStore::RemovePointer(
+ static_cast<const CBase*>(aQueryControl) );
+ }
+
+CAknQueryExtension* CAknQueryExtension::NewL()
+ {
+ return new (ELeave) CAknQueryExtension();
+ }
+
+CAknQueryExtension::~CAknQueryExtension()
+ {
+ delete iEditorContext;
+ }
+
+/*****************************
+ * TAknQueryEcsObserver
+ *****************************/
+
+/**
+*
+* This class is local to this cpp file. It is used to ensure that all reference to aknecs.h is
+* done within the CAknQueryControl class implementation and not in its header; that would cause
+* the client of CAknQueryControl (probably via CAknQueryDialog) to have to have Shared data and
+* phone client .h files in the INCLUDE path
+*
+*/
+NONSHARABLE_CLASS(TAknQueryEcsObserver): public MAknEcsObserver
+ {
+ public:
+ TAknQueryEcsObserver( CAknQueryControl* aParent );
+ // May be called from a sub-class of CAknEcsDetector in another DLL
+ IMPORT_C virtual void HandleEcsEvent(CAknEcsDetector* /*aDetector*/, CAknEcsDetector::TState aUpdatedState);
+ private:
+ CAknQueryControl* iParent; // Not owned; set by constructor initializaton
+ };
+
+TAknQueryEcsObserver::TAknQueryEcsObserver( CAknQueryControl* aParent ): iParent( aParent )
+ {
+ }
+
+
+EXPORT_C void TAknQueryEcsObserver::HandleEcsEvent( CAknEcsDetector* /*aDetector*/,
+ CAknEcsDetector::TState aUpdatedState )
+ {
+ TRAP_IGNORE( iParent->SetEcsCbaVisibleL( aUpdatedState == CAknEcsDetector::ECompleteMatch ) );
+
+ // Hide the emergency call number again.
+ // Number should be visible only in Partial or Complete match state
+ if ( aUpdatedState != CAknEcsDetector::EPartialMatch &&
+ aUpdatedState != CAknEcsDetector::ECompleteMatch )
+ {
+ if ( iParent->QueryType() == EPinLayout )
+ {
+ static_cast<CAknNumericSecretEditor*>
+ ( iParent->ControlByLayoutOrNull( EPinLayout ) )->RevealSecretText( EFalse );
+ }
+ }
+
+ // This check must be last action in the routine.
+ // If the query is cancelled, the iParent is deleted!
+ if ( aUpdatedState == CAknEcsDetector::ECallAttempted )
+ {
+ TRAP_IGNORE( iParent->CancelQueryL() );
+ }
+ }
+
+
+const TInt KMaxLinesInQuery=5;
+
+/*****************************
+ * CAknQueryControl
+ *****************************/
+
+/************************************************
+ * KQueryTypeToLayout
+ *
+ * The index into this table is the query type,
+ * according to the query constants enum in
+ * avkon.hrh. The values
+ * are the layout methods according to the enum
+ * TLayoutMethod. So this table maps a query type
+ * as read from resource file to a lyout method
+ ************************************************/
+
+const CAknQueryControl::TLayoutMethod KQueryTypeToLayout[]= {
+ CAknQueryControl::EDataQueryLayoutM, // NOT USED
+ CAknQueryControl::EDataQueryLayoutM, // EDataLayout=1,
+ CAknQueryControl::EConfQueryLayoutM, // EConfirmationQueryLayout and EConfirmationLayout
+ CAknQueryControl::ECodeQueryLayoutM, // ECodeLayout,
+ CAknQueryControl::ETimeQueryLayoutM, // ETimeLayout,
+ CAknQueryControl::EDateQueryLayoutM, // EDateLayout,
+ CAknQueryControl::ECodeQueryLayoutM, // EListLayout,
+ CAknQueryControl::ECodeQueryLayoutM, // EMultiListLayout,
+ CAknQueryControl::ECodeQueryLayoutM, // EMultiLineDataLayout,
+ CAknQueryControl::ETimeQueryLayoutM, // EDurationLayout,
+ CAknQueryControl::ECodeQueryLayoutM, // ETextSoftNotification, - THIS IS USED FOR NOTES
+ CAknQueryControl::EDataQueryLayoutM, // ENumberLayout,
+ CAknQueryControl::ECodeQueryLayoutM, // EPinLayout,
+ CAknQueryControl::EDataQueryLayoutM, // EPhoneLayout,
+ CAknQueryControl::EDataQueryLayoutM, // EMessageQueryLayout,
+ CAknQueryControl::EDataQueryLayoutM, // EStaticSizeDataLayout
+ CAknQueryControl::EDataQueryLayoutM, // EFloatingPointLayout
+ CAknQueryControl::ETimeQueryLayoutM, // EIpLayout
+ CAknQueryControl::EDataQueryLayoutM, // EFixedPointLayout
+ CAknQueryControl::EDataQueryLayoutM // EDataLayoutAllowEmptyInput - USED FOR EMPTY INPUT
+ };
+
+///
+/// Construction and Destruction methods
+///
+
+/**
+ *
+ */
+EXPORT_C CAknQueryControl::CAknQueryControl() :/* iQueryType(EConfirmationLayout),*/ iNumberOfEditorLines(-1), iHasEditor(EFalse)
+ {
+ AKNTASHOOK_ADD( this, "CAknQueryControl" );
+ }
+
+/**
+ *
+ */
+EXPORT_C CAknQueryControl::~CAknQueryControl()
+ {
+ AKNTASHOOK_REMOVE();
+ if (iEdwin)
+ AknsUtils::DeregisterControlPosition(iEdwin);
+ else if (iNumberEdwin)
+ AknsUtils::DeregisterControlPosition(iNumberEdwin);
+ else if (iFloatingPointEditor)
+ AknsUtils::DeregisterControlPosition(iFloatingPointEditor);
+ else if (iDateEdwin)
+ AknsUtils::DeregisterControlPosition(iDateEdwin);
+ else if (iTimeEdwin)
+ AknsUtils::DeregisterControlPosition(iTimeEdwin);
+ else if (iDurationEdwin)
+ AknsUtils::DeregisterControlPosition(iDurationEdwin);
+ else if (iSecretEd)
+ AknsUtils::DeregisterControlPosition(iSecretEd);
+ else if (iPinEdwin)
+ AknsUtils::DeregisterControlPosition(iPinEdwin);
+ else if (iExtension && LocationEd())
+ AknsUtils::DeregisterControlPosition(LocationEd());
+
+
+ delete iLineWidths;
+ delete iEcsDetector;
+ delete iEcsObserver;
+ delete iPrompt;
+ delete iEditIndicator;
+ if ( iImage && iImage->IsPictureOwnedExternally() )
+ {
+ delete ((CApaMaskedBitmap*) iImage->Bitmap());
+ }
+ delete iImage;
+ delete iEdwin;
+ delete iDateEdwin;
+ delete iTimeEdwin;
+ delete iDurationEdwin;
+ delete iSecretEd;
+ delete iNumberEdwin;
+ delete iPinEdwin;
+ delete iFloatingPointEditor;
+ if (iExtension)
+ delete LocationEd();
+ delete iAnimation;
+ if ( iQueryType ) // As we must maintain BC, we cannot add private members or change protected members.
+ { // We have to use iQueryType to distinguish if the context was added to stack or not
+ // This won't affect to normal usage of iQueryType any way, only a way to indicate if
+ // construction was succesful until context was set.
+ CCoeBrushAndPenContext* brushAndPenContext = (CCoeBrushAndPenContext*)ControlContext();
+ delete brushAndPenContext;
+ }
+ CAknQueryExtension::DestroyExtension( this );
+ delete iExtension;
+
+#if defined( RD_SCALABLE_UI_V2)
+ delete iIncreaseValueButton;
+ delete iDecreaseValueButton;
+#endif //defined( RD_SCALABLE_UI_V2)
+ }
+
+/**
+ * Construct from resource
+ */
+EXPORT_C void CAknQueryControl::ConstructFromResourceL(TResourceReader &aRes)
+ {
+ // Construct extension
+ CAknQueryExtension::CreateExtensionL( this );
+ iExtension = new (ELeave)CAknQueryControlExtension;
+
+ iEcsObserver = new (ELeave) TAknQueryEcsObserver(this);
+ iEditIndicator = CAknQueryEditIndicator::NewL(this);
+ iEditIndicator->SetObserver(this);
+
+ iLineWidths = new(ELeave)CArrayFixFlat<TInt>(5);
+
+ CCoeBrushAndPenContext* brushAndPenContext=CCoeBrushAndPenContext::NewL();
+ brushAndPenContext->SetBrushStyle(CGraphicsContext::ENullBrush);
+ SetControlContext(brushAndPenContext);
+ // This must be straight after setting Graphics Context, it is the only way to indicate
+ // brushAndPenContext is added to stack or not.
+ iQueryType = aRes.ReadUint16();
+ __ASSERT_DEBUG(iQueryType, Panic(EAknPanicLayoutResourceProblem));
+
+ iEditIndicator->SetQueryType(iQueryType);
+
+ SetLineWidthsL();
+ ReadPromptL(aRes);
+ ConstructQueryL(aRes);
+
+ CEikDialog* dlg;
+ MopGetObject( dlg );
+ if ( dlg )
+ {
+ if ( CAknEnv::Static()->TransparencyEnabled() )
+ {
+ dlg->Extension()->iPublicFlags.Set( CEikDialogExtension::EClipChildControlRect );
+ }
+
+ // set dialog's window as button group's container window in case a fullscreen
+ // virtual input dialog is requested
+ if ( EmbeddedVirtualInput() )
+ {
+ CEikCba* cba = static_cast<CEikCba*>( dlg->ButtonGroupContainer().ButtonGroup() );
+ cba->SetContainerWindowL( *this );
+ dlg->ButtonGroupContainer().SetContainerWindowL( *cba );
+ dlg->ButtonGroupContainer().SetParent( NULL );
+ cba->SetPosition( TPoint( 0, 0 ) );
+
+ iExtension->iKeypad = CAknKeypad::NewL( *this, iQueryType );
+ }
+ }
+ }
+
+void CAknQueryControl::ConstructQueryL(TResourceReader& aRes)
+ {
+ switch(iQueryType)
+ {
+ case EConfirmationQueryLayout:
+ {
+ TPtrC bmpFile=aRes.ReadTPtrC();
+ TInt bmpId=aRes.ReadInt16();
+ TInt bmpMask=aRes.ReadInt16();
+ TInt animationId = aRes.ReadUint32();
+
+ // Animation overrides bitmap if it is set.
+ if ( (animationId == 0) && (bmpFile.Length() != 0))
+ {
+ iImage = new(ELeave) CEikImage;
+ iImage->SetContainerWindowL(*this);
+
+ TBool skinnedFound( EFalse );
+ if ( bmpFile.CompareF(KAvkonBitmapFile) == 0 ) // Skinning is supported only avkon bitmaps
+ {
+ TAknsItemID id;
+ id.Set(0,0);
+ id = CAknNoteAttributes::GetSkinnedBitmapID(bmpId);
+ if ( id.iMajor && id.iMinor ) // skin id found, try loading
+ {
+ CApaMaskedBitmap* bitmap = NULL;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ TRAPD( err, bitmap = AknsUtils::CreateMaskedBitmapL(skin,id));
+ if ( !err )
+ {
+ CFbsBitmap* mask = bitmap->Mask();
+ iImage->SetPicture(bitmap,mask);
+ iImage->SetPictureOwnedExternally(ETrue);
+ skinnedFound = ETrue;
+ }
+ }
+ }
+ if ( !skinnedFound)
+ {
+ iImage->CreatePictureFromFileL(bmpFile,bmpId,bmpMask);
+ }
+ }
+ else
+ {
+ if (animationId == 0)
+ {
+ // Default animation if neither bitmap nor animation is set.
+ animationId = R_QGN_NOTE_QUERY_ANIM;
+ }
+ }
+
+ if (animationId != 0)
+ {
+ if (!iAnimation)
+ {// no animation previously set
+ // Save animation ID for possible skin changes
+
+ //iExtension->iAnimationId = animationId;
+
+ TRAPD( err, SetAnimationL( animationId ) );
+ if ( err != KErrNone )
+ {
+ iAnimation = NULL;
+ }
+ }
+ }
+ break;
+ }
+ case EDataLayoutAllowEmptyInput:
+ {
+ CAknQueryExtension* extension = QueryExtension();
+ if( extension )
+ {
+ extension->iAllowEmptyInput = ETrue;
+ }
+ iQueryType = EDataLayout;
+ // fall through
+ }
+ case EDataLayout:
+ case EStaticSizeDataLayout:
+ {
+ iEdwin = new(ELeave)CEikEdwin;
+ iEdwin->SetContainerWindowL(*this);
+ iEdwin->SetEdwinObserver(this);
+ iEdwin->ConstructFromResourceL(aRes);
+ iEdwin->SetObserver(this);
+ iEdwin->SetEdwinSizeObserver(this);
+
+
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ CreateBackspaceButtonL();
+ //HACK
+ iEdwin->AddFlagToUserFlags( CEikEdwin::EAvkonDisableVKB );
+
+ iEdwin->SetMaximumHeightInLines( 1 );
+
+
+ }
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+
+
+//Set maximum height in lines to KMaxLinesInQuery if it is unset, or an
+//invalid value has been used.
+ if (!iEdwin->MaximumHeightInLines()||iEdwin->MaximumHeightInLines()>KMaxLinesInQuery)
+ iEdwin->SetMaximumHeightInLines(KMaxLinesInQuery);
+
+//If the maximum number of lines is 1,
+// ensure flags are consistent with a single-line editor scrolling mechanism
+//else
+// ensure flags are consistent with a multi-line editor scrolling mechanism
+
+ if (1==iEdwin->MaximumHeightInLines())
+ iEdwin->RemoveFlagFromUserFlags(EEikEdwinNoHorizScrolling | EEikEdwinResizable);
+ else
+ iEdwin->AddFlagToUserFlags(EEikEdwinNoHorizScrolling | EEikEdwinResizable);
+ if (EDataLayout==iQueryType && iEdwin->InputCapabilities().IsNone())
+ {
+ iEdwin->SetAknEditorAllowedInputModes(EAknEditorTextInputMode | EAknEditorNumericInputMode );
+ }
+ break;
+ }
+ case ECodeLayout:
+ {
+ iSecretEd = new(ELeave)CEikSecretEditor;
+ iSecretEd->SetContainerWindowL(*this);
+ iSecretEd->ConstructFromResourceL(aRes);
+ iSecretEd->SetObserver(this);
+ iSecretEd->SetSkinTextColorL(EAknsCIQsnTextColorsCG27);
+
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ CreateBackspaceButtonL();
+ iSecretEd->SetFeature(CEikSecretEditor::EDisablePenInput, 1);
+ }
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+
+ break;
+ }
+ case EDateLayout:
+ {
+ iDateEdwin = new(ELeave)CEikDateEditor;
+ iDateEdwin->SetContainerWindowL(*this);
+ iDateEdwin->ConstructFromResourceL(aRes);
+ iDateEdwin->SetObserver(this);
+ iDateEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27);
+
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ CreateBackspaceButtonL();
+ iDateEdwin->SetFeature(CEikMfne::EDisablePenInput, 1);
+ }
+ else
+ {
+ iDateEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight );
+ }
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+
+ break;
+ }
+ case ETimeLayout:
+ {
+ iTimeEdwin = new(ELeave)CEikTimeEditor;
+ iTimeEdwin->SetContainerWindowL(*this);
+ iTimeEdwin->ConstructFromResourceL(aRes);
+ iTimeEdwin->SetObserver(this);
+ iTimeEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27);
+
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ CreateBackspaceButtonL();
+ iTimeEdwin->SetFeature(CEikMfne::EDisablePenInput, 1);
+ }
+ else
+ {
+ iTimeEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight );
+ }
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+
+ break;
+ }
+ case EDurationLayout:
+ {
+ iDurationEdwin = new(ELeave)CEikDurationEditor;
+ iDurationEdwin->SetContainerWindowL(*this);
+ iDurationEdwin->ConstructFromResourceL(aRes);
+ iDurationEdwin->SetObserver(this);
+ iDurationEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27);
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ iDurationEdwin->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight );
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+ break;
+ }
+ case ENumberLayout:
+ {
+ iNumberEdwin = new(ELeave)CAknIntegerEdwin;
+ iNumberEdwin->SetContainerWindowL(*this);
+ iNumberEdwin->ConstructFromResourceL(aRes);
+ iNumberEdwin->SetObserver(this);
+ break;
+ }
+ case EPinLayout:
+ {
+ iPinEdwin = new(ELeave)CAknNumericSecretEditor;
+ iPinEdwin->SetContainerWindowL(*this);
+ iPinEdwin->ConstructFromResourceL(aRes);
+ iPinEdwin->SetObserver(this);
+ iPinEdwin->SetSkinTextColorL(EAknsCIQsnTextColorsCG27);
+
+ // reset tacticon playback counter and play tacticon, which
+ // also resets the tacticon timer
+ if ( iExtension )
+ {
+ iExtension->iPinTacticonsPlayed = 0;
+ PlayPinCodeTacticon();
+ }
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ CreateBackspaceButtonL();
+ iPinEdwin->SetFeature(CEikSecretEditor::EDisablePenInput, 1);
+ }
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+
+ break;
+ }
+ case EPhoneLayout:
+ {
+ iEdwin = new(ELeave)CEikEdwin;
+ iEdwin->AddFlagToUserFlags(EEikEdwinAlternativeWrapping);
+ iEdwin->SetContainerWindowL(*this);
+ iEdwin->SetEdwinObserver(this);
+ iEdwin->ConstructFromResourceL(aRes);
+ iEdwin->SetEdwinSizeObserver(this);
+
+//Set maximum height in lines to KMaxLinesInQuery if it is unset, or an
+//invalid value has been used.
+ if (!iEdwin->MaximumHeightInLines()||iEdwin->MaximumHeightInLines()>KMaxLinesInQuery)
+ iEdwin->SetMaximumHeightInLines(KMaxLinesInQuery);
+
+//If the maximum number of lines is 1,
+// ensure flags are consistent with a single-line editor scrolling mechanism
+//else
+// ensure flags are consistent with a multi-line editor scrolling mechanism
+
+ if (1==iEdwin->MaximumHeightInLines())
+ iEdwin->RemoveFlagFromUserFlags(EEikEdwinNoHorizScrolling | EEikEdwinResizable);
+ else
+ iEdwin->AddFlagToUserFlags(EEikEdwinNoHorizScrolling | EEikEdwinResizable);
+ iEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode);
+ iEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode);
+ iEdwin->SetObserver(this);
+ break;
+ }
+ case EFloatingPointLayout:
+ {
+ iFloatingPointEditor = new ( ELeave ) CEikFloatingPointEditor;
+ iFloatingPointEditor->SetContainerWindowL( *this );
+ iFloatingPointEditor->SetEdwinObserver( this );
+ iFloatingPointEditor->ConstructFromResourceL( aRes );
+ iFloatingPointEditor->SetAknEditorAllowedInputModes( EAknEditorNumericInputMode );
+ iFloatingPointEditor->SetObserver(this);
+ break;
+ }
+ default:
+ __ASSERT_DEBUG(0, Panic(EAknPanicLayoutControlResourceProblem));
+ break;
+ }
+
+ // Construct editor context
+ CAknQueryExtension* extension = QueryExtension();
+ if( extension )
+ {
+ extension->CreateEditorContextL();
+ }
+ }
+
+TInt CAknQueryControl::PinCodeTimeoutCallback( TAny* aThis )
+ {
+ // play tacticon
+ static_cast<CAknQueryControl*>( aThis )->PlayPinCodeTacticon();
+
+ return KErrNone;
+ }
+
+void CAknQueryControl::PlayPinCodeTacticon()
+ {
+ // play tacticon
+ RTacticon client;
+ if ( KErrNone == client.Connect() )
+ {
+ client.PlayTacticon( ENeutralTacticon );
+ client.Close();
+ }
+
+ if ( iExtension )
+ {
+ iExtension->iPinTacticonsPlayed++;
+
+ // if the maximum amount of pincode query tacticons has not been
+ // reached, reset timer
+ if ( iExtension->iPinTacticonsPlayed < KPinCodeMaxTacticons )
+ {
+ ResetPinCodeTacticonTimer();
+ }
+ else
+ {
+ // max amount reached, stop timer for good
+ StopPinCodeTacticonTimer();
+ }
+ }
+ }
+
+void CAknQueryControl::ResetPinCodeTacticonTimer()
+ {
+ // stop old timer
+ StopPinCodeTacticonTimer();
+
+ if ( iExtension )
+ {
+ // create new one
+ iExtension->iPinTacticonTimer =
+ CPeriodic::New( CActive::EPriorityStandard );
+
+ // start timer, if creation succeeded
+ if ( iExtension->iPinTacticonTimer )
+ {
+ iExtension->iPinTacticonTimer->Start(
+ KPinCodeTacticonInterval, KPinCodeTacticonInterval,
+ TCallBack( PinCodeTimeoutCallback, this ) );
+ }
+ }
+ }
+
+void CAknQueryControl::StopPinCodeTacticonTimer()
+ {
+ if ( iExtension )
+ {
+ // delete timer
+ delete iExtension->iPinTacticonTimer;
+
+ // set the timer null, so that it will not be used again
+ iExtension->iPinTacticonTimer = NULL;
+ }
+ }
+
+///
+/// CCoeControl methods
+///
+
+/**
+ *Returns the control owned by this control by the index
+ */
+CCoeControl* CAknQueryControl::ComponentControl(TInt anIndex) const
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ CCoeControl* cba = NULL;
+ CEikDialog* dialog;
+
+ const_cast<CAknQueryControl*>( this )->MopGetObject( dialog );
+
+ if ( dialog && EmbeddedVirtualInput() )
+ {
+ cba = static_cast<CEikCba*>( dialog->ButtonGroupContainer().ButtonGroup() );
+ }
+
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iEdwin, iDateEdwin, LocationEd(),
+ iTimeEdwin, iSecretEd, iDurationEdwin,
+ iNumberEdwin, iPinEdwin, iFloatingPointEditor,
+ iImage, iAnimation
+#if defined( RD_SCALABLE_UI_V2)
+ ,iIncreaseValueButton, iDecreaseValueButton
+ ,( iExtension && iExtension->iKeypad) ? cba : NULL
+ ,iExtension ? iExtension->iKeypad : NULL
+ ,iExtension ? iExtension->iBackspaceButton : NULL
+#endif //if defined( RD_SCALABLE_UI_V2)
+ };
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ //subtle: index is decremented only if control is not NULL!
+ if (controls[ii] && anIndex-- == 0)
+ {
+ return controls[ii];
+ }
+ }
+ }
+ else
+ {
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iEdwin, iDateEdwin, LocationEd(),
+ iTimeEdwin, iSecretEd, iDurationEdwin,
+ iNumberEdwin, iPinEdwin, iFloatingPointEditor,
+ iImage, iAnimation
+ };
+ //TODO add buttons to array
+
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ //subtle: index is decremented only if control is not NULL!
+ if (controls[ii] && anIndex-- == 0)
+ {
+ return controls[ii];
+ }
+ }
+ }
+ return NULL;
+ }
+
+/**
+ * Returns the number of controls inside the compound control.
+ */
+TInt CAknQueryControl::CountComponentControls() const
+ {
+ TInt count = 0;
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ CCoeControl* cba = NULL;
+ CEikDialog* dialog;
+
+ const_cast<CAknQueryControl*>( this )->MopGetObject( dialog );
+
+ if ( dialog && EmbeddedVirtualInput() )
+ {
+ cba = static_cast<CEikCba*>( dialog->ButtonGroupContainer().ButtonGroup() );
+ }
+
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iEdwin, iDateEdwin, LocationEd(),
+ iTimeEdwin, iSecretEd, iDurationEdwin,
+ iNumberEdwin, iPinEdwin, iFloatingPointEditor,
+ iImage, iAnimation
+#if defined( RD_SCALABLE_UI_V2)
+ ,iIncreaseValueButton, iDecreaseValueButton,
+ ( iExtension && iExtension->iKeypad) ? cba : NULL,
+ iExtension ? iExtension->iKeypad : NULL,
+ iExtension ? iExtension->iBackspaceButton : NULL
+#endif //if defined( RD_SCALABLE_UI_V2)
+ };
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ if (controls[ii])
+ {
+ count++;
+ }
+ }
+ }
+ else
+ {
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iEdwin, iDateEdwin, LocationEd(),
+ iTimeEdwin, iSecretEd, iDurationEdwin,
+ iNumberEdwin, iPinEdwin, iFloatingPointEditor,
+ iImage, iAnimation
+ };
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ if (controls[ii])
+ {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+
+/**
+ * Forward key event to the editor
+ */
+EXPORT_C TKeyResponse CAknQueryControl::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType)
+ {
+ TKeyResponse response( EKeyWasNotConsumed );
+
+ // Send key handling for emergency call support
+ if ( aKeyEvent.iCode == EKeyYes )
+ {
+ if ( iEcsDetector )
+ {
+ AttemptEmergencyCallL();
+ }
+ // Always eat the key, however, as in former handling of this key
+ response = EKeyWasConsumed;
+ }
+
+ CCoeControl* ctrl = ControlByLayoutOrNull( iQueryType );
+ if ( ctrl && ctrl->IsFocused() )
+ {
+ response = ctrl->OfferKeyEventL( aKeyEvent, aType );
+
+ // pin query received key, reset timer if it exists
+ if ( iExtension && iExtension->iPinTacticonTimer &&
+ iQueryType == EPinLayout && response == EKeyWasConsumed )
+ {
+ ResetPinCodeTacticonTimer();
+ }
+ }
+ return response;
+ }
+
+/**
+ * Handle a focus changed
+ */
+void CAknQueryControl::FocusChanged(TDrawNow aDrawNow)
+ {
+ CCoeControl* ctrl = ControlByLayoutOrNull( iQueryType );
+ if (ctrl)
+ {
+ ctrl->DrawDeferred();
+ ctrl->SetFocus( IsFocused(), aDrawNow );
+ Layout();
+ }
+ if ( iAnimation )
+ {
+ iAnimation->SetFocus( IsFocused(), aDrawNow );
+ }
+ }
+
+void CAknQueryControl::PrepareForFocusLossL()
+ {
+ CCoeControl* ctrl = ControlByLayoutOrNull( iQueryType );
+ if (ctrl)
+ {
+ ctrl->PrepareForFocusLossL();
+ }
+ }
+
+///
+/// Observer related methods (Handle* methods)
+///
+
+//
+//Set observer for component
+//
+EXPORT_C void CAknQueryControl::SetQueryControlObserver(MAknQueryControlObserver* aQueryControlObserver)
+ {
+ iQueryControlObserver = aQueryControlObserver;
+ }
+
+//
+//Handle edwin events
+//
+EXPORT_C void CAknQueryControl::HandleEdwinEventL(CEikEdwin* /*aEdwin*/,TEdwinEvent /*aEventType*/)
+ {
+
+ }
+
+//
+//Call observer when edwin size changed
+//
+EXPORT_C TBool CAknQueryControl::HandleEdwinSizeEventL(CEikEdwin* /*aEdwin*/, TEdwinSizeEvent /*aEventType*/, TSize /*aDesirableEdwinSize*/)
+ {
+ TInt editorNbr = NbrOfEditorLines();
+ TInt maxLines = KMaxLinesInQuery;
+ if (iEdwin)
+ {
+ const TInt mHIL = iEdwin->MaximumHeightInLines();
+ if (mHIL)
+ {
+ maxLines = mHIL;
+ }
+ }
+
+ if(iQueryControlObserver && editorNbr <= maxLines)
+ {
+ iQueryControlObserver->HandleQueryEditorSizeEventL(this,MAknQueryControlObserver::EQueryControltSizeChanging);
+ }
+ return EFalse;
+ }
+
+
+EXPORT_C void CAknQueryControl::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
+ {
+ if (iEditIndicator && aControl == iEditIndicator)
+ {
+ if ( iExtension && iExtension->iKeypad )
+ {
+ iExtension->iKeypad->SetState(iEditIndicator->State());
+ }
+ return;
+ }
+
+ if(iQueryControlObserver && aEventType == EEventStateChanged)
+ {
+ if ( iNumberEdwin || iFloatingPointEditor)
+ {
+ TInt intValue;
+ TReal realValue;
+ CAknNumericEdwin::TValidationStatus status = iNumberEdwin ?
+ iNumberEdwin->GetTextAsInteger(intValue) :
+ iFloatingPointEditor->GetValueAsReal(realValue);
+ switch( status )
+ {
+ case CAknNumericEdwin::EEmpty:
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorEmpty);
+ break;
+ }
+ case CAknNumericEdwin::EValueTooLarge:
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueTooLarge);
+ break;
+ }
+ case CAknNumericEdwin::EValueTooSmall:
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueTooSmall);
+ break;
+ }
+ case CAknNumericEdwin::EValueNotParsed:
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueNotParsed);
+ break;
+ }
+ case CAknNumericEdwin::EValueValid:
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueValid);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if(GetTextLength())
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueValid);
+ }
+ else
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorEmpty);
+ }
+ }
+
+ // Emergency Call support. Set the buffer in the Ecs copied from the editor
+ if ( iEcsDetector )
+ {
+ if ( iNumberEdwin || iPinEdwin )
+ {
+ // In either case, we need to copy the first KAknEcsMaxMatchingLength
+ // characters to the emergency call buffer
+ if ( iNumberEdwin )
+ {
+ TBuf<KAknEcsMaxMatchingLength> buf;
+ iNumberEdwin->Text()->Extract(buf, 0, KAknEcsMaxMatchingLength );
+ iEcsDetector->SetBuffer( buf );
+ }
+ else if ( iPinEdwin )
+ {
+ TPtrC secretBuffer = iPinEdwin->Buffer().Left(KAknEcsMaxMatchingLength);
+ iEcsDetector->SetBuffer( secretBuffer );
+ // Manage appearance of the PIN query
+ // If match is complete, or complete + Send key, show the number
+ TBool reveal = EFalse;
+ TInt ecsState( iEcsDetector->State() );
+ if ( ( ecsState == CAknEcsDetector::ECompleteMatch ) ||
+ ( ecsState == CAknEcsDetector::ECompleteMatchThenSendKey ) )
+ {
+ // Further check to ensure that the matched number is the entire buffer
+ // Get the matched text and see if is the same length as the current query length
+ if ( GetTextLength() == iEcsDetector->CurrentMatch().Length() )
+ {
+ reveal = ETrue;
+
+ if ( ecsState == CAknEcsDetector::ECompleteMatch )
+ {
+ SetEcsCbaVisibleL( ETrue );
+ }
+ }
+ }
+ iPinEdwin->RevealSecretText( reveal );
+ }
+ }
+ }
+
+ if (aControl)
+ {
+
+#if defined( RD_SCALABLE_UI_V2)
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ if(aControl == iIncreaseValueButton)
+ {
+ if(iTimeEdwin)
+ {
+ iTimeEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneIncrementCurrentFieldValue);
+ }
+ if(iDateEdwin)
+ {
+ iDateEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneIncrementCurrentFieldValue);
+ }
+ if(iDurationEdwin)
+ {
+ iDurationEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneIncrementCurrentFieldValue);
+ }
+ if(iExtension && LocationEd())
+ {
+ LocationEd()->HandleMfneCommandL(MAknMfneCommandObserver::EMfneIncrementCurrentFieldValue);
+ }
+
+ }
+ else if(aControl == iDecreaseValueButton)
+ {
+ if(iTimeEdwin)
+ {
+ iTimeEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneDecrementCurrentFieldValue);
+ }
+ if(iDateEdwin)
+ {
+ iDateEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneDecrementCurrentFieldValue);
+ }
+ if(iDurationEdwin)
+ {
+ iDurationEdwin->HandleMfneCommandL(MAknMfneCommandObserver::EMfneDecrementCurrentFieldValue);
+ }
+ if(iExtension && LocationEd())
+ {
+ LocationEd()->HandleMfneCommandL(MAknMfneCommandObserver::EMfneIncrementCurrentFieldValue);
+ }
+ }
+ else if( iExtension && aControl == iExtension->iBackspaceButton )
+ {
+ TInt scanCode = EStdKeyBackspace;
+ TRawEvent event;
+ event.Set( TRawEvent::EKeyDown, scanCode );
+ event.SetTip( ETrue );
+
+ if (iEikonEnv->AppUi())
+ {
+ static_cast<CAknAppUi*>(iEikonEnv->EikAppUi())->DisableNextKeySound( scanCode );
+ }
+
+ CCoeEnv::Static()->WsSession().SimulateRawEvent( event );
+ event.Set( TRawEvent::EKeyUp, scanCode );
+ CCoeEnv::Static()->WsSession().SimulateRawEvent( event );
+ }
+ }
+#endif //if defined( RD_SCALABLE_UI_V2)
+ }
+ }
+ }
+
+///
+/// DRAWING METHODS
+///
+
+/**
+ * Draw the following:-
+ * - Text editor frame if there is a text editor, which is true for all
+ * queries except confirmation queries
+ */
+void CAknQueryControl::Draw(const TRect& /*aRect*/) const
+ {
+ CWindowGc& gc=SystemGc();
+ TRect rect(Rect());
+
+ TRect dialogRect = DialogRect();
+ rect.iBr.iY += dialogRect.iBr.iY;
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ TRgb color;
+ TInt error = AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 );
+ if ( !error )
+ {
+ TRAP_IGNORE(AknLayoutUtils::OverrideControlColorL( *(CAknQueryControl*)this, EColorLabelText, color ) );
+ }
+
+ 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<CAknQueryControl*>(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();
+ }
+ }
+
+/**
+ * Draw text editor frame and shadow
+ */
+void CAknQueryControl::DrawEditorFrame(CWindowGc& aGc,TRect& /*aRect*/) const
+ {
+ if (iHasEditor)
+ {
+ TBool skinnedDraw( EFalse );
+
+ CAknQueryExtension* extension = QueryExtension();
+ if( extension && extension->EditorContext() )
+ {
+ // If first-level image exists, frame has already been drawn
+ // as part of the context.
+
+ if ( CAknEnv::Static()->TransparencyEnabled() )
+ {
+ const CCoeControl* ctrl = const_cast<CAknQueryControl*>(this)->ControlByLayoutOrNull( iQueryType );
+ if ( ctrl )
+ {
+ skinnedDraw = AknsDrawUtils::Background(
+ AknsUtils::SkinInstance(),
+ extension->EditorContext(),
+ ctrl,
+ aGc,
+ iEditorFrame.Rect(),
+ KAknsDrawParamNoClearUnderImage );
+ }
+ }
+ else
+ {
+ skinnedDraw = AknsDrawUtils::Background(
+ AknsUtils::SkinInstance(),
+ extension->EditorContext(),
+ aGc,
+ iEditorFrame.Rect() );
+ }
+ }
+
+ // ... otherwise, draw the non-skinned frame
+ if( !skinnedDraw )
+ {
+ iEditorFrame.DrawOutLineRect(aGc);
+ iEditorVerShadow.DrawRect(aGc);
+ iEditorHorShadow.DrawRect(aGc);
+ }
+ }
+ }
+
+
+///
+/// LAYOUT METHODS
+///
+
+/**
+ * Depending on query type and on the number of prompt or editor lines
+ * return the window layout.
+ *
+ * This is used by a dialog to layout the control correctly.
+ *
+ */
+void CAknQueryControl::WindowLayout( TAknWindowLineLayout& aLayout ) const
+ {
+ if ( EmbeddedVirtualInput() )
+ {
+ aLayout = AknLayoutScalable_Avkon::application_window( 0 );
+ return;
+ }
+
+ TIndex LAFIndex(NbrOfPromptLines());
+
+ switch (KQueryTypeToLayout[iQueryType])
+ {
+ case EConfQueryLayoutM:
+ aLayout = AknLayoutScalable_Avkon::popup_note_window(LAFIndex.PNWindow());
+ break;
+
+ case EDataQueryLayoutM:
+ aLayout = AknLayoutScalable_Avkon::popup_query_data_window(LAFIndex.PQDWindow(NbrOfEditorLines()));
+ break;
+
+ case ECodeQueryLayoutM:
+ aLayout = AknLayoutScalable_Avkon::popup_query_code_window(LAFIndex.PQCWindow());
+ break;
+
+ case ETimeQueryLayoutM:
+ aLayout = AknLayoutScalable_Avkon::popup_query_code_window(LAFIndex.PQCWindow());
+ break;
+
+ case EDateQueryLayoutM:
+ aLayout = AknLayoutScalable_Avkon::popup_query_code_window(LAFIndex.PQCWindow());;
+ break;
+
+ default:
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported));
+ aLayout = AknLayoutScalable_Avkon::popup_note_window(LAFIndex.PNWindow());
+ break;
+ }
+ }
+
+/**
+ * Layout information in LAF is relative to the size of the dialog and not to the
+ * size of the internal area (dialog size - margins from UIKLAF). Therefore when
+ * doing layout do not use Rect(), but LayoutRect() - which returns the size of the
+ * dialog.
+ *
+ * Position is always (0,0) - top
+ *
+ */
+TRect CAknQueryControl::LayoutRect()
+ {
+#ifndef RD_NO_DIALOG_BORDERS
+ TPoint topLeft = Position();
+ TRect parent = DialogRect();
+ TAknLayoutRect layout;
+
+ if (KQueryTypeToLayout[iQueryType] == EDataQueryLayoutM)
+ layout.LayoutRect(parent, AKN_LAYOUT_WINDOW_Data_query_pop_up_window_graphics_Line_5(parent));
+ else
+ layout.LayoutRect(parent, AKN_LAYOUT_WINDOW_Note_pop_up_window_graphics_Line_5(parent));
+
+ TRect rect(layout.Rect());
+ topLeft.iX -= rect.iTl.iX;
+ topLeft.iY -= rect.iTl.iY;
+
+ TPoint bottomRight (topLeft);
+ TSize size (DialogSize());
+ bottomRight.iY += size.iHeight;
+ bottomRight.iX += size.iWidth;
+
+ return TRect(topLeft,bottomRight);
+#else
+ return Rect();
+#endif
+ }
+
+/**
+ * Do layout (call SizeChanged) and if the control is
+ * activated do a redraw
+ */
+void CAknQueryControl::Layout()
+ {
+ SizeChanged();
+ }
+
+/**
+ * Perform layout depending on query type.
+ */
+void CAknQueryControl::SizeChanged()
+ {
+ DialogSizeChanged();
+ iPrompt->SetRect(LayoutRect());
+ LayoutPrompt(KQueryTypeToLayout[iQueryType]);
+
+ LayoutImageOrAnim(KQueryTypeToLayout[iQueryType]);
+ LayoutEditor(KQueryTypeToLayout[iQueryType]);
+
+
+ // Layout Keypad
+
+ if ( iExtension && iExtension->iKeypad )
+ {
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::grid_vitu2_itu_pane( landscape ? 5 : 0 ) ).LayoutLine() );
+
+ iExtension->iKeypad->SetRect( layoutRect.Rect() );
+ }
+
+
+ // Layout Backspace Button
+
+ if ( iExtension && iExtension->iBackspaceButton )
+ {
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+ TAknLayoutRect layout;
+ layout.LayoutRect(layoutRect.Rect(), AknLayoutScalable_Apps::bg_button_pane_cp022( 0 ));
+
+ iExtension->iBackspaceButton->SetRect(layout.Rect());
+ }
+
+ // Layout CBA
+
+ CEikDialog* dlg;
+ MopGetObject( dlg );
+ if ( dlg )
+ {
+ // Note: iExtension->iKeypad is used to ensure that SetRect is not called too early
+ if ( iExtension && iExtension->iKeypad && EmbeddedVirtualInput() )
+ {
+ CEikCba* cba = static_cast<CEikCba*>( dlg->ButtonGroupContainer().ButtonGroup() );
+
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+ TAknLayoutRect leftLayout;
+ leftLayout.LayoutRect(layoutRect.Rect(), AknLayoutScalable_Apps::bg_button_pane_cp018( 0 ));
+
+ TAknLayoutRect rightLayout;
+ rightLayout.LayoutRect(layoutRect.Rect(), AknLayoutScalable_Apps::bg_button_pane_cp021( 0 ));
+
+ TRect rect;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ rect.iTl = rightLayout.Rect().iTl;
+ rect.iBr = leftLayout.Rect().iBr;
+ }
+ else
+ {
+ rect.iTl = leftLayout.Rect().iTl;
+ rect.iBr = rightLayout.Rect().iBr;
+ }
+
+ cba->SetRect( rect );
+ }
+ }
+
+ CAknQueryExtension* extension = QueryExtension();
+ if( iHasEditor && extension && extension->EditorContext() )
+ {
+ // Layout editor context
+ TAknLayoutRect topLeft;
+ TAknLayoutRect bottomRight;
+
+ //How to handle lanscape layout in full screen queries?
+
+ 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 ) );
+
+
+#if defined( RD_SCALABLE_UI_V2)
+
+ // Create backspace button if not created yet
+ if ( AknLayoutUtils::PenEnabled() && EmbeddedVirtualInput() )
+ {
+ TRAP_IGNORE( CreateBackspaceButtonL() );
+ }
+
+#endif //if defined( RD_SCALABLE_UI_V2)
+ }
+
+ if (iImage)
+ {
+ TAknLayoutRect rect;
+ rect.LayoutRect( Rect(), AKN_LAYOUT_WINDOW_Note_pop_up_window_elements_Line_1 );
+ AknIconUtils::SetSize( CONST_CAST( CFbsBitmap*, iImage->Bitmap() ), rect.Rect().Size() );
+ }
+ }
+
+/**
+ * Return the minimum size for the control.
+ *
+ * This depends on the type of query and the number of prompt and/or
+ * editor lines.
+ *
+ * Changed this to use only data-query layout
+ */
+EXPORT_C TSize CAknQueryControl::MinimumSize()
+ {
+ DialogSizeChanged();
+#ifndef RD_NO_DIALOG_BORDERS
+ TRect parent = DialogRect();
+ TAknLayoutRect layout;
+ layout.LayoutRect(parent, AKN_LAYOUT_WINDOW_Data_query_pop_up_window_graphics_Line_5(parent));
+ TRect rect(layout.Rect());
+ return (TSize(rect.Size()));
+#else
+ return DialogRect().Size();
+#endif
+ }
+
+/**
+ * Return rect that is used by dialog to lay itself out
+ * This is determined by LAF values only.
+ */
+TRect CAknQueryControl::DialogRect() const
+ {
+ return TRect(TPoint(0,0),DialogSize());
+ }
+
+/**
+ * Return the size of the dialog
+ */
+TSize CAknQueryControl::DialogSize() const
+ {
+ return iDialogSize;
+ }
+
+/**
+ * Calculates the size of the dialog. This is determined by
+ * LAF values only.
+ */
+void CAknQueryControl::DialogSizeChanged()
+ {
+ TAknWindowLineLayout lay;
+ WindowLayout( lay );
+ TAknLayoutRect layout;
+ layout.LayoutRect(Rect(), lay);
+ TRect rect(layout.Rect());
+ iDialogSize = TSize(rect.Size());
+ }
+
+/**
+* Layout the query prompt.
+*
+* There are two possible ways of laying
+* out the text, either according to the general note LAF specs
+* or according to the data query LAF specs
+*
+* Data queries layout the prompt according to data query LAF specs.
+* Other queries layout the text according to the general note spces
+*
+* This method is called from SizeChanged, which determines the layout method
+* to use (general note or data query) depending on the query type.
+*/
+void CAknQueryControl::LayoutPrompt(const TLayoutMethod& aLayoutM)
+ {
+ __ASSERT_DEBUG(iPrompt,Panic(EAknPanicNullPointer));
+
+ if ( AknLayoutUtils::PenEnabled() && EmbeddedVirtualInput() )
+ {
+ LayoutPromptForFullScreen();
+ return;
+ }
+
+ TRect rect = LayoutRect();
+ for (TInt i = 0; i < NbrOfPromptLines(); i++)
+ {
+ if (aLayoutM == EConfQueryLayoutM)
+ {
+ // AknLayoutScalable_Avkon::popup_note_window_t1 ?
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(i), rect, AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(i) );
+ }
+ else if (aLayoutM == ECodeQueryLayoutM || aLayoutM == ETimeQueryLayoutM || aLayoutM == EDateQueryLayoutM )
+ {
+ // AknLayoutScalable_Avkon::popup_query_code_window_t1 ?
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(i), rect, AKN_LAYOUT_TEXT_Code_query_pop_up_window_texts_Line_1(i) );
+ }
+ else if (aLayoutM == EDataQueryLayoutM)
+ {
+ // AknLayoutScalable_Avkon::popup_query_code_window_t1 ?
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(i), rect, AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(i));
+ }
+ else
+ {
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported));
+ }
+ }
+ }
+
+/**
+ * Layout the image or the animation.
+ *
+ * Confirmation queries can have either an image or an animation and the
+ * layout is similar to general notes.
+ *
+ * This method is called from SizeChanged.
+ */
+void CAknQueryControl::LayoutImageOrAnim(const TLayoutMethod& aLayoutM)
+ {
+ if (aLayoutM == EConfQueryLayoutM)
+ {
+ // AknLayoutScalable_Avkon::popup_note_window_g1() ?
+ if (iImage)
+ AknLayoutUtils::LayoutImage(iImage, LayoutRect(), AKN_LAYOUT_WINDOW_Note_pop_up_window_elements_Line_1);
+
+ if (iAnimation)
+ AknLayoutUtils::LayoutControl(iAnimation, LayoutRect(), AKN_LAYOUT_WINDOW_Note_pop_up_window_elements_Line_1);
+ }
+ }
+
+/**
+ * Layout the editor and its frame.
+ *
+ * Queries other than confirmation queries have an editor that the user needs
+ * to input the query data. This method does the layout of the editor.
+ *
+ * Data queries have a resizable editor and its layout is specified in the LAF.
+ *
+ * Other queries have a fixed size editor with layout specified.
+ *
+ *
+ * This method is called from SizeChanged. Depending on the query type, the
+ * layout method is chosen accordingly, e.g. data queries use the data query
+ * method, other queires use the code query method.
+ *
+ * The macros at the top are just for avoiding code repetition.
+ */
+void CAknQueryControl::LayoutEditor(const TLayoutMethod& aLayoutM)
+ {
+ if ( AknLayoutUtils::PenEnabled() && EmbeddedVirtualInput() )
+ {
+ LayoutEditorForFullScreen( aLayoutM );
+ return;
+ }
+
+ TIndex LAFIndex(NbrOfPromptLines());
+
+ if (aLayoutM == EDataQueryLayoutM)
+ {
+ iHasEditor = ETrue;
+
+ LayoutEditorFrame(aLayoutM);
+
+ LayoutEditorIndicator(aLayoutM);
+
+ TInt promptLines = NbrOfPromptLines();
+ TInt numberTextLines = NbrOfEditorLines();
+
+ TInt isNumeric = 0;
+ CEikEdwin* editor = iEdwin;
+ if (iNumberEdwin)
+ {
+ editor = iNumberEdwin;
+ }
+ else if (iFloatingPointEditor)
+ {
+ editor = iFloatingPointEditor;
+ }
+
+ if ( editor )
+ {
+ TRect parentRect = LayoutRect();
+ if (promptLines > 1)
+ {
+ // There isn't way to give number of prompt lines to layout adaptation layer
+ // through Data_query_pop_up_window_texts_Line_2 layout API. Adaptation layer
+ // does'n know which layout should be used. For that reason 2nd and 3rd prompt
+ // line area is reduced from the parent rect and adaptation layer expects
+ // that only one prompt line exists.
+ TAknLayoutText prompt1;
+ prompt1.LayoutText(parentRect, AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(0));
+
+ TAknLayoutText prompt2;
+ prompt2.LayoutText(parentRect, AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(1));
+
+ TInt parentOffset = prompt2.TextRect().iBr.iY - prompt1.TextRect().iBr.iY;
+ parentRect.iTl.iY += parentOffset * (promptLines - 1);
+ }
+ AknLayoutUtils::LayoutEdwin( editor, parentRect,
+ AKN_LAYOUT_MULTILINE_TEXT_Data_query_pop_up_window_texts_Line_2( isNumeric, numberTextLines ), EAknsCIQsnTextColorsCG27);
+
+ //layout data not correct? if editor height is bigger than frame - reduce editor height by one step
+ if (numberTextLines >= KMaxLinesInQuery && editor->Rect().iBr.iY > iEditorFrame.Rect().iBr.iY)
+ {
+ AknLayoutUtils::LayoutEdwin( editor, parentRect,
+ AKN_LAYOUT_MULTILINE_TEXT_Data_query_pop_up_window_texts_Line_2( isNumeric, numberTextLines-1 ), EAknsCIQsnTextColorsCG27);
+
+ //last line possibly w/ cursor might disappear - reveal it
+ TRAP_IGNORE(editor->MoveDisplayL(TCursorPosition::EFLineDown));
+ }
+
+ editor->SetBorder(TGulBorder::ENone);
+ if (IsFocused() && !(editor->IsFocused()) )
+ editor->SetFocus(ETrue);
+ }
+
+ AknsUtils::RegisterControlPosition(editor);
+ }
+ else if (aLayoutM == ECodeQueryLayoutM || aLayoutM == EDateQueryLayoutM || aLayoutM == ETimeQueryLayoutM)
+ {
+ iHasEditor = ETrue;
+
+ LayoutEditorFrame(aLayoutM);
+
+ LayoutEditorIndicator(aLayoutM);
+
+ if (iSecretEd)
+ {
+ AknLayoutUtils::LayoutSecretEditor(iSecretEd, LayoutRect(),
+ AKN_LAYOUT_TEXT_Code_query_pop_up_window_texts_Line_2(LAFIndex.PromptLine()));
+ iSecretEd->SetBorder(TGulBorder::ENone);
+ if (IsFocused() && !iSecretEd->IsFocused())
+ iSecretEd->SetFocus(ETrue);
+ }
+ if (iPinEdwin)
+ {
+ AknLayoutUtils::LayoutSecretEditor(iPinEdwin, LayoutRect(),
+ AKN_LAYOUT_TEXT_Code_query_pop_up_window_texts_Line_2(LAFIndex.PromptLine()));
+ iPinEdwin->SetBorder(TGulBorder::ENone);
+ if (IsFocused() && !iPinEdwin->IsFocused())
+ iPinEdwin->SetFocus(ETrue);
+ }
+
+//LAYOUT for TIME, DATE and DURATION EDITORS
+ CEikMfne* edwin = NULL;
+
+ if ( iTimeEdwin )
+ {
+ edwin = iTimeEdwin;
+ }
+ else if ( iDateEdwin )
+ {
+ edwin = iDateEdwin;
+ }
+ else if ( iDurationEdwin )
+ {
+ edwin = iDurationEdwin;
+ }
+ else if ( LocationEd() )
+ {
+ edwin = LocationEd();
+ }
+
+ if ( edwin )
+ {
+ TInt variety( LAFIndex.PromptLine() );
+
+ AknLayoutUtils::LayoutMfne( edwin, LayoutRect(),
+ TAknWindowComponentLayout::ComposeText(
+ AknLayoutScalable_Avkon::query_popup_pane( variety ),
+ AknLayoutScalable_Avkon::query_popup_pane_t1() ) );
+
+ edwin->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !edwin->IsFocused() )
+ {
+ edwin->SetFocus( ETrue );
+ }
+ edwin->SetUpAndDownKeysConsumed( ETrue );
+ }
+ }
+ }
+
+/**
+ * Layout the editor frame.
+ *
+ * For queries that do have an editor, this method will position its frame.
+ *
+ * This method is called by LayoutEditor only if the layout
+ * method implies the presence of an editor, hence the panic if
+ * the layout is not recognised.
+ *
+ */
+void CAknQueryControl::LayoutEditorFrame(const TLayoutMethod& aLayoutM)
+ {
+ TIndex LAFIndex(NbrOfPromptLines());
+
+ TRect rect = LayoutRect();
+ TRect parent = DialogRect();
+
+ if (aLayoutM == EDataQueryLayoutM)
+ {
+ iEditorVerShadow.LayoutRect( rect, AKN_LAYOUT_WINDOW_Data_query_pop_up_window_elements_Line_1(LAFIndex.PromptLine()));
+ iEditorHorShadow.LayoutRect( rect, AKN_LAYOUT_WINDOW_Data_query_pop_up_window_elements_Line_2(parent,LAFIndex.PromptLine()));
+ iEditorFrame.LayoutRect ( rect, AKN_LAYOUT_WINDOW_Data_query_pop_up_window_elements_Line_3(parent,LAFIndex.PromptLine()));
+ }
+ else if (aLayoutM == ECodeQueryLayoutM || aLayoutM == EDateQueryLayoutM || aLayoutM == ETimeQueryLayoutM)
+ {
+ TInt variety( LAFIndex.PromptLine() );
+ iEditorVerShadow.LayoutRect( rect, AKN_LAYOUT_WINDOW_Code_query_pop_up_window_elements_Line_1( variety ) );
+ iEditorHorShadow.LayoutRect( rect, AKN_LAYOUT_WINDOW_Code_query_pop_up_window_elements_Line_2( variety ) );
+
+ iEditorFrame.LayoutRect( rect, AknLayoutScalable_Avkon::query_popup_pane( variety ) );
+ }
+ else
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported));
+ }
+
+/**
+ * Layout editor indicator.
+ *
+ * For queries that do have an editor, this method does
+ * layout for its editing state icons.
+ *
+ * If these icons are not to be displayed then this method
+ * returns without doing anything.
+ *
+ * This method is called by LayoutEditor only if the layout
+ * method implies the presence of an editor, hence the panic if
+ * the layout is not recognised.
+ */
+void CAknQueryControl::LayoutEditorIndicator(const TLayoutMethod& aLayoutM)
+ {
+ TIndex LAFIndex(NbrOfPromptLines());
+
+ if (!iEditIndicator)
+ return;
+
+ if (aLayoutM == EDataQueryLayoutM)
+ {
+ AknLayoutUtils::LayoutControl(iEditIndicator, LayoutRect(),
+ AKN_LAYOUT_WINDOW_Data_query_pop_up_window_elements_Line_4(LAFIndex.PromptLine()));
+ }
+ else if (aLayoutM == ECodeQueryLayoutM || aLayoutM == EDateQueryLayoutM || aLayoutM == ETimeQueryLayoutM)
+ {
+ TInt variety( LAFIndex.PromptLine() );
+
+ AknLayoutUtils::LayoutControl(iEditIndicator, LayoutRect(),
+ AknLayoutScalable_Avkon::indicator_popup_pane( variety ) );
+ }
+ else
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported));
+ }
+
+//
+// Extension
+//
+
+CAknQueryExtension* CAknQueryControl::QueryExtension() const
+ {
+ return CAknQueryExtension::Instance( this );
+ }
+
+//
+// Prompt related methods
+//
+
+/**
+ * Read prompt text from resouce
+ */
+EXPORT_C void CAknQueryControl::ReadPromptL(TResourceReader &aRes)
+ {
+ delete iPrompt;
+ iPrompt = NULL;
+
+ iPrompt = CAknTextControl::NewL(CAknText::EFormatted);
+ iPrompt->ConstructFromResourceL(aRes);
+ iPrompt->SetContainerWindowL(*this);
+
+ TCallBack cb( StaticPictographCallBack, this );
+ iPrompt->SetPictographCallBackL( cb );
+
+ DoSetPromptL();
+ }
+
+/**
+ * Set new text into prompt and parse the text
+ */
+EXPORT_C void CAknQueryControl::SetPromptL(const TDesC& aDesC)
+ {
+ __ASSERT_DEBUG(iPrompt,Panic(EAknPanicNullPointer));
+ iPrompt->SetTextL(aDesC);
+ DoSetPromptL();
+ }
+
+/**
+ * Parse the text in the prompt
+ *
+ * Line widths of prompt depend on layout information and on
+ * query type
+ */
+void CAknQueryControl::DoSetPromptL()
+ {
+ __ASSERT_DEBUG(iPrompt,Panic(EAknPanicNullPointer));
+
+ TAknLayoutText textRect;
+
+ TAknWindowLineLayout dialogLay;
+ WindowLayout( dialogLay );
+
+ TAknLayoutRect dialogLayRect;
+ dialogLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(), dialogLay);
+ TSize dialogSize = dialogLayRect.Rect().Size();
+ TRect parent(TPoint(0,0),dialogSize);
+
+ if (iQueryType == EConfirmationQueryLayout)
+ {
+ textRect.LayoutText(parent, AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(1));
+ }
+ else
+ {
+ textRect.LayoutText(parent, AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(1));
+ }
+
+ SetLineWidthsL();
+ const CFont *font = textRect.Font();
+ iPrompt->ParseTextL(font,iLineWidths);
+
+ // Next code block inserts line feeds into the given prompt text so that
+ // it always consumes the same amount of vertical space. Prompt should
+ // always be placed just above the editor i.e. empty lines are added before
+ // the prompt if needed.
+ //
+
+ if ( EmbeddedVirtualInput() )
+ {
+ // Set line widths for prompt text using Query Input layout
+
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TAknLayoutRect rect;
+ rect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+ TAknLayoutText layoutText;
+ layoutText.LayoutText( rect.Rect(),
+ AknLayoutScalable_Apps::area_vitu2_query_pane_t4( 1 ) );
+
+ font = layoutText.Font();
+
+ iLineWidths->Reset();
+ for (TInt i = 0; i < 3; i++)
+ {
+ iLineWidths->AppendL(layoutText.TextRect().Width());
+ }
+
+ // text parsing is needed to get correct return value
+ // from function NbrOfPromptLines
+ iPrompt->ParseTextL( font, iLineWidths );
+
+
+ // calculate needed amount of empty lines
+ TInt lineFeeds = 3 - NbrOfPromptLines();
+
+ // add empty lines if needed
+ if ( lineFeeds > 0)
+ {
+ HBufC* oldText = iPrompt->Text().AllocLC();
+ HBufC* newText = oldText->ReAllocL( oldText->Length() + lineFeeds );
+
+ CleanupStack::Pop(); // oldText
+ CleanupStack::PushL( newText );
+
+ // add empty lines
+ for ( TInt i = 0; i < lineFeeds; ++i )
+ {
+ newText->Des().Insert( 0, _L( "\n" ) );
+ }
+ iPrompt->SetTextL( *newText );
+
+ // text parsing is needed because empty lines are added
+ iPrompt->ParseTextL( font, iLineWidths );
+
+ CleanupStack::PopAndDestroy(); // newText
+ }
+ }
+
+ Layout();
+ }
+
+void CAknQueryControl::SetLineWidthsL()
+ {
+ if (!iLineWidths)
+ return;
+
+ iLineWidths->Reset();
+
+ switch(KQueryTypeToLayout[iQueryType])
+ {
+ case EConfQueryLayoutM:
+ {
+ TAknLayoutRect parentLayoutRect;
+ parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AknLayoutScalable_Avkon::popup_note_window(0));
+ TAknLayoutText textRect;
+ for (TInt i = 0; i < 5; i++)
+ {
+ textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(i));
+ iLineWidths->AppendL(textRect.TextRect().Width());
+ }
+ break;
+ }
+ case EDataQueryLayoutM:
+ {
+ TAknLayoutRect parentLayoutRect;
+ parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AknLayoutScalable_Avkon::popup_query_data_window(0));
+ TAknLayoutText textRect;
+ for (TInt i = 0; i < 3; i++)
+ {
+ textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(i));
+ iLineWidths->AppendL(textRect.TextRect().Width());
+ }
+ break;
+ }
+ case ECodeQueryLayoutM:
+ case ETimeQueryLayoutM:
+ case EDateQueryLayoutM:
+ {
+ TAknLayoutRect parentLayoutRect;
+ parentLayoutRect.LayoutRect(iAvkonAppUi->ClientRect(), AknLayoutScalable_Avkon::popup_query_code_window(0));
+ TAknLayoutText textRect;
+ for (TInt i = 0; i < 3; i++)
+ {
+ textRect.LayoutText(parentLayoutRect.Rect(), AKN_LAYOUT_TEXT_Code_query_pop_up_window_texts_Line_1(i));
+ iLineWidths->AppendL(textRect.TextRect().Width());
+ }
+ break;
+ }
+ default:
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported));
+ }
+ }
+
+
+///
+/// Editor text related methos
+///
+
+/**
+ *Get text from editors
+ */
+EXPORT_C void CAknQueryControl::GetText(TDes &aDes) const
+ {
+ if(iEdwin)
+ {
+ iEdwin->GetText(aDes);
+ }
+ else if(iSecretEd)
+ {
+ iSecretEd->GetText(aDes);
+ }
+ else if(iPinEdwin)
+ {
+ iPinEdwin->GetText(aDes);
+ }
+ else if(iNumberEdwin)
+ {
+ iNumberEdwin->GetText(aDes);
+ }
+ else if (iFloatingPointEditor)
+ {
+ iFloatingPointEditor->GetText(aDes);
+ }
+ }
+
+/**
+ *Set default text in editors
+ */
+EXPORT_C void CAknQueryControl::SetTextL(const TDesC &aDesC)
+ {
+ if( iEdwin )
+ {
+ __ASSERT_DEBUG
+ (
+ iEdwin->MaxLength()>=aDesC.Length(),
+ Panic(EAknPanicOverflow)
+ );
+ iEdwin->SetTextL(&aDesC);
+ }
+ else if( iSecretEd )
+ {
+ __ASSERT_DEBUG
+ (
+ iSecretEd->MaxLength()>=aDesC.Length(),
+ Panic(EAknPanicOverflow)
+ );
+ iSecretEd->SetText(aDesC);
+ }
+ else if( iPinEdwin )
+ {
+ __ASSERT_DEBUG
+ ( // secret editor derived
+ iPinEdwin->MaxLength()>=aDesC.Length(),
+ Panic(EAknPanicOverflow)
+ );
+ iPinEdwin->SetText(aDesC);
+ }
+ else if( iNumberEdwin )
+ {
+ __ASSERT_DEBUG
+ (
+ iNumberEdwin->MaxLength()>=aDesC.Length(),
+ Panic(EAknPanicOverflow)
+ );
+
+ iNumberEdwin->SetTextL(&aDesC);
+ }
+ else if (iFloatingPointEditor)
+ {
+ __ASSERT_DEBUG
+ (
+ iFloatingPointEditor->MaxLength()>=aDesC.Length(),
+ Panic(EAknPanicOverflow)
+ );
+
+ iFloatingPointEditor->SetTextL(&aDesC);
+ }
+ }
+
+/**
+ *Set max. length in text based editors.
+ */
+EXPORT_C void CAknQueryControl::SetTextEntryLength(TInt aLength)
+ {
+ if( iEdwin )
+ {
+ iEdwin->SetMaxLength(aLength);
+ }
+ else if( iSecretEd )
+ {
+ iSecretEd->SetMaxLength(aLength);
+ }
+ else if( iPinEdwin )
+ {
+ iPinEdwin->SetMaxLength(aLength);
+ }
+ else if( iNumberEdwin )
+ {
+ iNumberEdwin->SetMaxLength(aLength);
+ }
+ else if ( iFloatingPointEditor )
+ {
+ iFloatingPointEditor->SetMaxLength(aLength);
+ }
+ }
+
+/**
+ * Get maximum text length in text based editors
+ */
+EXPORT_C TInt CAknQueryControl::GetTextEntryLength() const
+ {
+ if( iEdwin )
+ {
+ return iEdwin->MaxLength();
+ }
+ if(iSecretEd)
+ {
+ return iSecretEd->MaxLength();
+ }
+ if(iPinEdwin)
+ {
+ return iPinEdwin->MaxLength();
+ }
+ if(iNumberEdwin)
+ {
+ return iNumberEdwin->MaxLength();
+ }
+ if (iFloatingPointEditor)
+ {
+ return iFloatingPointEditor->MaxLength();
+ }
+ return -1;
+ }
+
+///
+/// API Set methods
+///
+
+EXPORT_C void CAknQueryControl::SetMinimumAndMaximum(const TTime& aMinimum, const TTime& aMaximum)
+ {
+ if( iDateEdwin )
+ {
+ iDateEdwin->SetMinimumAndMaximum(aMinimum, aMaximum);
+ }
+ else if( iTimeEdwin )
+ {
+ iTimeEdwin->SetMinimumAndMaximum(aMinimum, aMaximum);
+ }
+ }
+
+EXPORT_C void CAknQueryControl::SetMinimumAndMaximum(const TTimeIntervalSeconds& aMinimumDuration, const TTimeIntervalSeconds& aMaximumDuration)
+ {
+ if( iDurationEdwin )
+ {
+ iDurationEdwin->SetMinimumAndMaximum(aMinimumDuration, aMaximumDuration);
+ }
+ }
+
+EXPORT_C void CAknQueryControl::SetMinimumAndMaximum(TInt aMinimumValue, TInt aMaximumValue)
+ {
+ if( iNumberEdwin )
+ {
+ iNumberEdwin->SetMinimumIntegerValue(aMinimumValue);
+ iNumberEdwin->SetMaximumIntegerValue(aMaximumValue);
+ }
+ }
+
+EXPORT_C void CAknQueryControl::SetMinimumAndMaximum(const TReal& aMinimumValue, const TReal& aMaximumValue)
+ {
+ if( iFloatingPointEditor )
+ {
+ iFloatingPointEditor->SetMinMax(aMinimumValue, aMaximumValue);
+ }
+ }
+
+
+
+EXPORT_C TBool CAknQueryControl::CheckNumber()
+ {
+ return iNumberEdwin->CheckNumber();
+ }
+
+EXPORT_C void CAknQueryControl::SetDuration(TTimeIntervalSeconds& aDuration)
+//
+//Set duration to editor
+//
+{
+ if( iDurationEdwin )
+ {
+ iDurationEdwin->SetDuration(aDuration);
+ }
+}
+
+EXPORT_C void CAknQueryControl::SetNumberL(TInt aNumber)
+//
+//Set number from editor
+//
+{
+ if( iNumberEdwin )
+ {
+ iNumberEdwin->SetValueL(aNumber);
+ }
+}
+
+EXPORT_C void CAknQueryControl::SetTime(TTime& aTime)
+//
+//Set time or date to editor
+//
+{
+ if( iTimeEdwin )
+ {
+ iTimeEdwin->SetTime(aTime);
+ }
+ else if( iDateEdwin )
+ {
+ iDateEdwin->SetDate(aTime);
+ }
+}
+
+EXPORT_C void CAknQueryControl::SetFloatingPointNumberL(const TReal* aNumber)
+//
+//Set number from editor
+//
+{
+ if( iFloatingPointEditor )
+ {
+ iFloatingPointEditor->SetValueL( aNumber );
+ }
+}
+
+EXPORT_C void CAknQueryControl::SetLocation(const TPosition &aLocation)
+{
+ if (iExtension && LocationEd())
+ {
+ LocationEd()->Set( aLocation );
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ LocationEd()->SetFeature( CEikMfne::EFingerSupport, CEikMfne::EnableWithAllHighlight );
+ }
+ }
+}
+
+EXPORT_C void CAknQueryControl::SetNumberOfEditorLines(TInt aNum)
+ {
+ iNumberOfEditorLines = aNum;
+ }
+
+///
+/// API Get methods
+///
+
+EXPORT_C TInt CAknQueryControl::GetTextLength() const
+//
+//Get text length
+//
+{
+ if ( iSecretEd )
+ {
+ return iSecretEd->Buffer().Length();
+ }
+ if ( iPinEdwin )
+ {
+ return iPinEdwin->Buffer().Length();
+ }
+ if( iEdwin )
+ {
+ return iEdwin->TextLength();
+ }
+ if( iNumberEdwin )
+ {
+ return iNumberEdwin->TextLength();
+ }
+ if (iFloatingPointEditor)
+ {
+ return iFloatingPointEditor->TextLength();
+ }
+
+ return -1;
+}
+
+EXPORT_C TTime CAknQueryControl::GetTime() const
+//
+//Get time or date from editor
+//
+{
+ TTime time(0);
+
+ if( iTimeEdwin )
+ {
+ return iTimeEdwin->Time();
+ }
+
+ if( iDateEdwin )
+ {
+ return iDateEdwin->Date();
+ }
+
+ return time;
+}
+
+EXPORT_C TReal CAknQueryControl::GetFloatingPointNumberL() const
+//
+//Set number from editor
+//
+{
+ TReal ret = 0;
+ if( iFloatingPointEditor )
+ {
+ iFloatingPointEditor->GetValueAsReal( ret );
+ }
+ return ret;
+}
+
+EXPORT_C void CAknQueryControl::GetLocation(TPosition &aLocation) const
+{
+ if (LocationEd())
+ {
+ LocationEd()->Get(aLocation);
+ }
+}
+
+
+EXPORT_C TInt CAknQueryControl::GetNumber() const
+{
+ TInt value = 0;
+ if(iNumberEdwin)
+ {
+ iNumberEdwin->GetTextAsInteger( value );
+ }
+ else
+ {
+ ASSERT(EFalse);
+ }
+ return value;
+}
+
+EXPORT_C TTimeIntervalSeconds CAknQueryControl::GetDuration() const
+//
+//Get duration from editor
+//
+{
+ if( iDurationEdwin )
+ {
+ return iDurationEdwin->Duration();
+ }
+ return NULL;
+}
+
+/**
+ * Return number of lines in the editor
+ *
+ * For data queries this can be 1 to 5 lines except if there are 3 lines
+ * of prompt text in which case only 1 line is permitted.
+ *
+ * For all other queries there is only 1 line of text.
+ */
+EXPORT_C TInt CAknQueryControl::NbrOfEditorLines() const
+ {
+ TInt nbrOfLines = 0;
+ if(iEdwin && KQueryTypeToLayout[iQueryType] == EDataQueryLayoutM)
+ {
+ if (iNumberOfEditorLines == -1)
+ {
+ TInt nL = Min(iEdwin->TextLayout()->NumFormattedLines(),KMaxLinesInQuery);
+ const TInt mHIL= Min(iEdwin->MaximumHeightInLines(),KMaxLinesInQuery);
+
+ if ( mHIL )
+ {
+ nbrOfLines = Min(nL,mHIL);
+ }
+ else
+ {
+ nbrOfLines = nL;
+ }
+ }
+
+ else if (iNumberOfEditorLines >= 0 && iNumberOfEditorLines <= KMaxLinesInQuery)
+ {
+ nbrOfLines = iNumberOfEditorLines;
+ }
+ }
+
+ return Max(1,nbrOfLines);
+ }
+
+/**
+ * Return number of prompt lines
+ *
+ * Only confirmation queries can have more than 2 lines
+ */
+EXPORT_C TInt CAknQueryControl::NbrOfPromptLines() const
+ {
+ if (iPrompt)
+ return iPrompt->NumberOfLines();
+ return 1;
+ }
+
+
+/**
+ * Return text editor depening on query type
+ */
+EXPORT_C CCoeControl* CAknQueryControl::ControlByLayoutOrNull(TInt aLayout)
+ {
+ CCoeControl* ctrl=NULL;
+ switch ( aLayout )
+ {
+ case EStaticSizeDataLayout:
+ case EDataLayout:
+ case EPhoneLayout:
+ ctrl=iEdwin;
+ break;
+ case ECodeLayout:
+ ctrl=iSecretEd;
+ break;
+ case EDateLayout:
+ ctrl=iDateEdwin;
+ break;
+ case ETimeLayout:
+ ctrl=iTimeEdwin;
+ break;
+ case EDurationLayout:
+ ctrl=iDurationEdwin;
+ break;
+ case ENumberLayout:
+ ctrl=iNumberEdwin;
+ break;
+ case EPinLayout:
+ ctrl=iPinEdwin;
+ break;
+ case EFloatingPointLayout:
+ ctrl=iFloatingPointEditor;
+ break;
+ case ELocationLayout:
+ ctrl=LocationEd();
+ break;
+ default:
+ break;
+ }
+ return ctrl;
+ }
+
+/**
+*
+* Sends and ESC key to the app. This cannot be called from within OfferKeyEventL. It must be called
+* from within some other non-key event that subsequently does not require references to the object
+*
+*/
+void CAknQueryControl::CancelQueryL()
+ {
+ if (iQueryControlObserver)
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this, MAknQueryControlObserver::EEmergencyCallAttempted, MAknQueryControlObserver::EEditorValueValid);
+ }
+ else
+ {
+ TKeyEvent key;
+ key.iCode=EKeyEscape;
+ key.iModifiers=0;
+ key.iScanCode = EStdKeyNull;
+ iEikonEnv->SimulateKeyEventL(key, EEventKey);
+ }
+ }
+
+/**
+* This method looks at the flags that have been set in the query control and
+* acts upon them if possible
+*
+*/
+void CAknQueryControl::DeployFlagsL()
+ {
+ // Handle the Emergency call support flags
+ if (!iEcsDetector )
+ {
+ if (
+ (iNumberEdwin && iFlags.IsSet( EEmergencyCallsEnabledByAPI) )
+ ||
+ ( iPinEdwin && iFlags.IsSet( EEmergencyCallsEnabledByAPI) )
+ )
+ {
+ iEcsDetector = CAknEcsDetector::NewL();
+ // Set the control to be the CAknEcsDetector observer, if the object exists
+ iEcsDetector->SetObserver( iEcsObserver );
+ }
+
+ }
+
+ // Handle the T9 suppression in edwins. If the flag has not been set, then
+ // suppress the T9
+ if ( iFlags.IsClear ( EPredictiveTextEntryPermitted ) )
+ {
+ if ( iEdwin )
+ {
+ // set the noT9 flag
+ iEdwin->SetAknEditorFlags( EAknEditorFlagNoT9 | iEdwin->AknEdwinFlags() );
+ }
+ }
+
+ }
+
+/**
+* Method to first set the flags and then to use them on the contained editors
+*
+*/
+
+void CAknQueryControl::SetAndUseFlagsL(TBitFlags16 aFlags)
+ {
+ SetFlags( aFlags );
+ DeployFlagsL();
+ }
+
+void CAknQueryControl::SetFlags(TBitFlags16 aFlags)
+ {
+ iFlags = aFlags;
+ iEditIndicator->SetFlags( aFlags );
+ }
+
+EXPORT_C void CAknQueryControl::SetImageL(CEikImage* aImage)
+ { // Gets ownership of the aImage
+
+ if ( iImage && iImage->IsPictureOwnedExternally() )
+ {
+ delete ((CApaMaskedBitmap*) iImage->Bitmap());
+ }
+
+ delete iImage;
+ iImage = aImage;
+
+ if ( iImage )
+ {
+ iImage->SetContainerWindowL(*this);
+ }
+
+ delete iAnimation;
+ iAnimation = NULL;
+
+ Layout();
+ }
+
+EXPORT_C void CAknQueryControl::SetImageL(const TDesC& aImageFile,
+ TInt aBmpId, TInt aBmpMaskId)
+ {
+ CEikImage* image = new(ELeave) CEikImage;
+ CleanupStack::PushL( image );
+
+ TBool skinnedFound( EFalse );
+ if ( aImageFile.CompareF(KAvkonBitmapFile) == 0 ) // Skinning is supported only avkon bitmaps
+ {
+ TAknsItemID id;
+ id.Set(0,0);
+ id = CAknNoteAttributes::GetSkinnedBitmapID(aBmpId);
+ if ( id.iMajor && id.iMinor ) // skin id found, try loading
+ {
+ CApaMaskedBitmap* bitmap = NULL;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ TRAPD( err, bitmap = AknsUtils::CreateMaskedBitmapL(skin,id));
+ if ( !err )
+ {
+ CFbsBitmap* mask = bitmap->Mask();
+ iImage->SetPicture(bitmap,mask);
+ iImage->SetPictureOwnedExternally(ETrue);
+ skinnedFound = ETrue;
+ }
+ }
+ }
+ if ( !skinnedFound)
+ {
+ image->CreatePictureFromFileL(aImageFile,aBmpId,aBmpMaskId);
+ }
+
+ CleanupStack::Pop(); //image
+ SetImageL(image); // gets ownership
+ }
+
+EXPORT_C void CAknQueryControl::SetAnimationL(TInt aResource)
+ {
+ delete iAnimation;
+ iAnimation = NULL;
+ iAnimation = CAknBitmapAnimation::NewL();
+ iAnimation->SetContainerWindowL(*this);
+
+ TAknsItemID iid;
+ iid.Set( EAknsMajorAvkon, aResource );
+ if( !iAnimation->ConstructFromSkinL( iid ) )
+ {
+ TResourceReader readerForAnimation;
+ iCoeEnv->CreateResourceReaderLC(readerForAnimation,aResource);
+ iAnimation->ConstructFromResourceL(readerForAnimation);
+ CleanupStack::PopAndDestroy(); // readerForAnimation
+ }
+
+ // Save the animation resource id, because this function will be re-called
+ // when handling resource change.
+ iExtension->iAnimationId = aResource;
+
+ Layout();
+ }
+
+EXPORT_C void CAknQueryControl::StartAnimationL()
+ {
+ if (iAnimation)
+ {
+ CBitmapAnimClientData *animClientData = iAnimation->BitmapAnimData();
+ if (animClientData != NULL && animClientData->FrameArray().Count() <= 1)
+ {
+ // Not set background frame, if there is only one frame in animation.
+ }
+ else
+ {
+ const TDisplayMode displayMode(
+ CCoeEnv::Static()->ScreenDevice()->DisplayMode() );
+
+ CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+
+ User::LeaveIfError( bitmap->Create( iAnimation->Rect().Size(), displayMode ) );
+
+ CFbsBitmapDevice* doubleBufferDev = CFbsBitmapDevice::NewL( bitmap );
+ CleanupStack::PushL(doubleBufferDev);
+
+ CFbsBitGc* doubleBufferGc = 0;
+ User::LeaveIfError( doubleBufferDev->CreateContext( doubleBufferGc ) );
+ CleanupStack::PushL(doubleBufferGc);
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+ AknsDrawUtils::DrawBackground( skin, cc, this, *doubleBufferGc,
+ TPoint(0,0), iAnimation->Rect(), KAknsDrawParamDefault );
+
+ CleanupStack::PopAndDestroy(2); // doubleBufferGc, doubleBufferDev
+
+ CBitmapFrameData* data = CBitmapFrameData::NewL();
+ data->SetBitmapsOwnedExternally( EFalse );
+ data->SetBitmap( bitmap );
+
+ // Set frame to animation
+ iAnimation->BitmapAnimData()->SetBackgroundFrame( data ); // gets ownership
+
+ CleanupStack::Pop(bitmap);
+ }
+
+ iAnimation->StartAnimationL();
+ }
+ }
+
+EXPORT_C TInt CAknQueryControl::CancelAnimation()
+ {
+ if ( iAnimation )
+ {
+ return iAnimation->CancelAnimation();
+ }
+ return KErrGeneral;
+ }
+
+
+
+/**
+ * Return true if editor content is valid for query, false
+ * otherwise. Some editors always have a valid content. Others
+ * (those that have a text associated with them) may or may
+ * not have a valid content.
+ */
+TBool CAknQueryControl::EditorContentIsValidL() const
+ {
+ TInt ret = EFalse;
+ if (iDateEdwin || iTimeEdwin || iDurationEdwin ||LocationEd())
+ {
+ CEikMfne* editor = iDateEdwin;
+ if (!editor && iTimeEdwin)
+ editor = iTimeEdwin;
+ if (!editor && iDurationEdwin)
+ editor = iDurationEdwin;
+ if (!editor && LocationEd())
+ editor = static_cast<CEikMfne*>(LocationEd());
+ ret = editor->Field(editor->CurrentField())->IsValid();
+ }
+ else if (iNumberEdwin || iFloatingPointEditor)
+ {
+ TInt intValue;
+ TReal realValue;
+
+ CAknNumericEdwin::TValidationStatus status = iNumberEdwin ?
+ iNumberEdwin->GetTextAsInteger(intValue) : iFloatingPointEditor->GetValueAsReal(realValue);
+
+ // At this point too large or small values don't affect the valicy of content,
+ // range is checked when OkToExitL-method is called when user tries to confirm the query
+ if (iNumberEdwin && (status == CAknNumericEdwin::EValueTooSmall ||
+ status == CAknNumericEdwin::EValueTooLarge ) )
+ {
+ status = CAknNumericEdwin::EValueValid;
+ }
+ ret = status == CAknNumericEdwin::EValueValid;
+ }
+ else
+ {//Remaining editors have a non-empty text with at least one char
+ // which is not a space and is not a control char
+ CAknQueryExtension* extension = QueryExtension();
+ if( extension )
+ {
+ if ( extension->iAllowEmptyInput )
+ {
+ return ETrue;
+ }
+ }
+
+ HBufC* buf = HBufC::NewLC(GetTextEntryLength()); //max length
+ TPtr ptr = buf->Des();
+ if (GetTextEntryLength()) //check if zero is set as maxlength
+ {
+ GetText(ptr);
+ }
+ ret = AknTextUtils::IsEmptyText( ptr );
+
+ if ( !ret && ptr.Length() > 0 && iSecretEd )
+ {
+ TBool isSpace = ETrue;
+ for ( TInt i = 0; i < ptr.Length(); i++ )
+ {
+ TChar c( ptr[i] );
+ if ( !c.IsSpace() )
+ {
+ isSpace = EFalse;
+ break;
+ }
+ }
+ if ( isSpace )
+ {
+ ret = ETrue;
+ }
+ }
+
+ // Check if pictographs in buffer
+ if (!ret && iEdwin && iPrompt && ptr.Length())
+ {
+ CAknPictographInterface* picto = iPrompt->PictographInterface();
+
+ if ( picto && picto->Interface() && picto->Interface()->ContainsPictographs( ptr ) )
+ {
+ ret = ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy(); // buf
+ }
+ return ret;
+ }
+
+/*****************************************************************
+ * CAknQueryControl::TIndex
+ *
+ * Manage indexes into LAF tables
+ *
+ * PN stands for "Popup Note"
+ *
+ * PQD stands for "Popup Query Data'
+ *
+ * PQC stands for "Popup Query Code'
+ *
+ * 'DPQ' stands for "Data Query Popup"
+ ******************************************************************/
+
+
+CAknQueryControl::TIndex::TIndex(TInt aNumberOfPromptLines)
+ : iNumberOfPromptLines(aNumberOfPromptLines)
+ {
+ }
+
+void CAknQueryControl::TIndex::SelfTest() const
+ {
+ __ASSERT_DEBUG(iNumberOfPromptLines >= 0 && iNumberOfPromptLines <= 5,
+ Panic(EAknPanicInvalidValue));
+ }
+
+/**
+ * Return index into LAF tables that depend directly on number of prompt lines,
+ * index is equal to number of prompt lines minus one unless there are no prompt
+ * lines in which case the index is zero
+ */
+TInt CAknQueryControl::TIndex::PromptLine() const
+ {
+ SelfTest();
+ return iNumberOfPromptLines > 0 ? iNumberOfPromptLines - 1 : 0;
+ }
+
+/**
+ * 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 CAknQueryControl::TIndex::DQPWindowTextsLine2(TInt aLineNum) const
+ {
+ SelfTest();
+ __ASSERT_DEBUG(aLineNum > 0 && aLineNum <= 5,Panic(EAknPanicInvalidValue));
+
+ static const TInt KDataQueryPopupWindowTextsLine2Index[3][5] =
+ { {0, 1, 2, 3, 4}, //1 PROMPT LINE
+ {5, 6, 7, 8, 9}, //2 PROMPT LINES
+ {10, 10, 10, 10, 10} }; //3 PROMPT LINES
+
+ return KDataQueryPopupWindowTextsLine2Index[PromptLine()][aLineNum-1];
+ }
+
+TInt CAknQueryControl::TIndex::PNWindow() const
+ {
+ SelfTest();
+
+ static const TInt KPopupNoteWindowIndex[5] = { 0,0,0,1,2 };
+
+ AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
+ if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight)
+ {
+ // variety numbers for right CBA are 3,4 and 5
+ return (KPopupNoteWindowIndex[PromptLine()] + 3);
+ }
+ else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft)
+ {
+ /// variety numbers for left CBA are 6,7 and 8
+ return (KPopupNoteWindowIndex[PromptLine()] + 6);
+ }
+ else // bottom
+ {
+ return KPopupNoteWindowIndex[PromptLine()];
+ }
+ }
+
+TInt CAknQueryControl::TIndex::PQDWindow(TInt aLineNum) const
+ {
+ SelfTest();
+ __ASSERT_DEBUG(aLineNum > 0 && aLineNum <= 5,Panic(EAknPanicInvalidValue));
+
+ 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
+ return KPopupQueryDataWindowIndex[PromptLine()+aLineNum-1];
+ }
+ 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
+ return KPopupQueryDataWindowIndex[PromptLine()+aLineNum-1];
+ }
+ else // bottom
+ {
+ static const TInt KPopupQueryDataWindowIndex[7] =
+ {0, 1, 2, 3, 4, 5, 6}; // variety numbers for bottom CBA are 0-6
+ return KPopupQueryDataWindowIndex[PromptLine()+aLineNum-1];
+ }
+ }
+
+TInt CAknQueryControl::TIndex::PQCWindow() const
+ {
+ SelfTest();
+
+ AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
+
+ if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight)
+ {
+ // variety numbers for right CBA are 3,4 and 5
+ return iNumberOfPromptLines > 0 ? (iNumberOfPromptLines - 1 + 3) : 3;
+ }
+ else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft)
+ {
+ // variety numbers for left CBA are 6,7 and 8
+ return iNumberOfPromptLines > 0 ? (iNumberOfPromptLines - 1 + 6) : 6;
+ }
+ else // bottom
+ {
+ // variety numbers for bottom CBA are 0,1 and 2
+ return iNumberOfPromptLines > 0 ? (iNumberOfPromptLines - 1) : 0;
+ }
+ }
+
+TTypeUid::Ptr CAknQueryControl::MopSupplyObject( TTypeUid aId )
+ {
+ CAknQueryExtension* extension = QueryExtension();
+ if( (aId.iUid == MAknsControlContext::ETypeId) &&
+ extension && extension->EditorContext() && iHasEditor )
+ {
+ // Return specific context iff editor exists and the context
+ // has been constructed.
+ return MAknsControlContext::SupplyMopObject(
+ aId, extension->EditorContext() );
+ }
+
+ if ( aId.iUid == CAknQueryControl::ETypeId )
+ {
+ return aId.MakePtr( this );
+ }
+
+ return SupplyMopObject( aId, iEditIndicator );
+ }
+
+// Callback for doing a redraw when animating pictographs
+TInt CAknQueryControl::StaticPictographCallBack( TAny* aPtr )
+ {
+ CAknQueryControl* me = static_cast<CAknQueryControl*>( aPtr );
+ me->PictographCallBack();
+ return KErrNone;
+ }
+
+void CAknQueryControl::PictographCallBack()
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+ for ( TInt i = 0 ; i < iPrompt->NumberOfLines() ; i++ )
+ {
+ CAknPictographInterface* picto = iPrompt->PictographInterface();
+
+ // Only update the note line if it contains pictographs
+
+ if ( picto->Interface()->ContainsPictographs(
+ *( iPrompt->Line( i )->Text() ) ) )
+ {
+ TRect lineRect = iPrompt->Line(i)->Rect();
+ Window().Invalidate( lineRect );
+
+ ActivateGc();
+ Window().BeginRedraw();
+
+ AknsDrawUtils::Background(
+ skin,
+ cc,
+ this,
+#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
+ SystemGc(),
+#else
+ iCoeEnv->SystemGc(),
+#endif
+ lineRect );
+
+ Window().EndRedraw();
+ DeactivateGc();
+
+ // Draw the label after the background.
+ iPrompt->Line( i )->ActivateL(); // Never leaves
+ iPrompt->Line( i )->DrawNow();
+ iPrompt->SetLineModified( i, EFalse );
+ }
+ }
+ }
+
+TBool CAknQueryControl::EmbeddedVirtualInput() const
+ {
+ if ( !QueryExtension()->iVirtualInputStatusFlags.IsSet( CAknQueryExtension::EVirtualInputCheckedAlready ) )
+ {
+ QueryExtension()->iVirtualInputStatusFlags.Set( CAknQueryExtension::EVirtualInputCheckedAlready );
+
+ CEikDialog* dialog = NULL;
+
+ // Remove constness. This is unfortunate but this method needs to be
+ // called from several const methods so better to do it in one place.
+ const_cast<CAknQueryControl*>( this )->MopGetObject( dialog );
+
+ if ( dialog )
+ {
+ if ( dialog->DialogFlags() & EEikDialogFlagVirtualInput )
+ {
+ QueryExtension()->iVirtualInputStatusFlags.Set( CAknQueryExtension::EVirtualInputEnabled );
+ }
+ }
+ }
+
+#ifdef RD_SCALABLE_UI_V2
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ return QueryExtension()->iVirtualInputStatusFlags.IsSet( CAknQueryExtension::EVirtualInputEnabled );
+ }
+#endif
+ return false;
+ }
+
+
+CEikDialog* CAknQueryControl::Dialog() const
+ {
+ CAknQueryControl* control = const_cast<CAknQueryControl*>( this );
+
+ CEikDialog* dialog = NULL;
+ control->MopGetObject( dialog );
+ return dialog;
+ }
+
+
+void CAknQueryControl::CreateIncAndDecButtonsL()
+ {
+ if (!iIncreaseValueButton)
+ {
+ iIncreaseValueButton =
+ CAknButton::NewL(KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_button_increase,
+ EMbmAvkonQgn_indi_button_increase_mask,
+ -1,
+ -1,
+ EMbmAvkonQgn_indi_button_increase_pressed,
+ EMbmAvkonQgn_indi_button_increase_pressed_mask,
+ -1,
+ -1,
+ KNullDesC,
+ KNullDesC,
+ KAknButtonNoFrame | KAknButtonKeyRepeat,
+ 0,
+ KAknsIIDQgnIndiButtonIncrease,
+ KAknsIIDNone,
+ KAknsIIDQgnIndiButtonIncreasePressed,
+ KAknsIIDNone );
+
+ iIncreaseValueButton->SetContainerWindowL(*this);
+ iIncreaseValueButton->SetParent(this);
+ iIncreaseValueButton->SetObserver(this);
+ iIncreaseValueButton->MakeVisible(ETrue);
+ iIncreaseValueButton->SetFocusing(EFalse);
+ }
+
+ if (!iDecreaseValueButton)
+ {
+ iDecreaseValueButton =
+ CAknButton::NewL(KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_button_decrease,
+ EMbmAvkonQgn_indi_button_decrease_mask,
+ -1,
+ -1,
+ EMbmAvkonQgn_indi_button_decrease_pressed,
+ EMbmAvkonQgn_indi_button_decrease_pressed_mask,
+ -1,
+ -1,
+ KNullDesC,
+ KNullDesC,
+ KAknButtonNoFrame | KAknButtonKeyRepeat,
+ 0,
+ KAknsIIDQgnIndiButtonDecrease,
+ KAknsIIDNone,
+ KAknsIIDQgnIndiButtonDecreasePressed,
+ KAknsIIDNone );
+
+ iDecreaseValueButton->SetContainerWindowL(*this);
+ iDecreaseValueButton->SetParent(this);
+ iDecreaseValueButton->SetObserver(this);
+ iDecreaseValueButton->MakeVisible(ETrue);
+ iDecreaseValueButton->SetFocusing(EFalse);
+ }
+ }
+
+void CAknQueryControl::CreateBackspaceButtonL()
+ {
+ if (iExtension && !iExtension->iBackspaceButton)
+ {
+ iExtension->iBackspaceButton =
+ CAknButton::NewL(KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_navi_arrow_left,
+ EMbmAvkonQgn_indi_navi_arrow_left_mask,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ KNullDesC,
+ KNullDesC,
+ KAknButtonKeyRepeat | KAknButtonReportOnKeyDown,
+ 0,
+ KAknsIIDQgnIndiItutBackspace,
+ KAknsIIDNone,
+ KAknsIIDNone,
+ KAknsIIDNone );
+ iExtension->iBackspaceButton->SetContainerWindowL(*this);
+ iExtension->iBackspaceButton->SetParent(this);
+ iExtension->iBackspaceButton->SetObserver(this);
+ iExtension->iBackspaceButton->MakeVisible(ETrue);
+ iExtension->iBackspaceButton->SetFocusing(EFalse);
+
+
+ iExtension->iBackspaceButton->SetBackgroundIds( KAknsIIDQsnFrFunctionButtonNormal,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive );
+
+
+ CFbsBitmap *icon = NULL;
+ CFbsBitmap *mask = NULL;
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsUtils::CreateColorIconL( skin,
+ KAknsIIDQgnIndiItutBackspace,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnIconColorsCG30,
+ icon, mask,
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_navi_arrow_left,
+ EMbmAvkonQgn_indi_navi_arrow_left_mask,
+ KRgbBlack );
+
+ CGulIcon* gulIcon = CGulIcon::NewL( icon, mask );
+ iExtension->iBackspaceButton->State()->SetIcon( gulIcon );
+ }
+ }
+
+
+void CAknQueryControl::LayoutEditorForFullScreen( const TLayoutMethod& /*aLayoutM*/ )
+ {
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TIndex LAFIndex(NbrOfPromptLines());
+ iHasEditor = ETrue;
+
+ TInt variety( LAFIndex.PromptLine() );
+ iEditorVerShadow.LayoutRect( LayoutRect(), AKN_LAYOUT_WINDOW_Code_query_pop_up_window_elements_Line_1( variety ) );
+ iEditorHorShadow.LayoutRect( LayoutRect(), AKN_LAYOUT_WINDOW_Code_query_pop_up_window_elements_Line_2( variety ) );
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+
+ // Layout editor frame
+
+ iEditorFrame.LayoutRect( layoutRect.Rect(), AknLayoutScalable_Apps::input_focus_pane_cp09( 0 ) );
+
+ // Layout editor indicator
+
+ TAknWindowLineLayout lineLayout = AknLayoutScalable_Apps::area_vitu2_query_pane_g1( 0 );
+ AknLayoutUtils::LayoutControl(iEditIndicator, layoutRect.Rect(), lineLayout );
+
+ // Layout secret editor
+
+ if( iSecretEd )
+ {
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ) );
+
+ AknLayoutUtils::LayoutSecretEditor( iSecretEd, layoutRect.Rect(),
+ TAknWindowComponentLayout::ComposeText(
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane_t3( 1 ) ) );
+
+ iSecretEd->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !iSecretEd->IsFocused() )
+ {
+ iSecretEd->SetFocus( ETrue );
+ }
+ }
+
+ // Layout pin editor
+
+ if( iPinEdwin )
+ {
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ) );
+
+ AknLayoutUtils::LayoutSecretEditor( iPinEdwin, layoutRect.Rect(),
+ TAknWindowComponentLayout::ComposeText(
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane_t3( 1 ) ) );
+
+ iPinEdwin->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !iPinEdwin->IsFocused() )
+ {
+ iPinEdwin->SetFocus( ETrue );
+ }
+ }
+
+ // Layout MFNE editor
+
+ CEikMfne* edwin = NULL;
+ if ( iTimeEdwin )
+ {
+ edwin = iTimeEdwin;
+ }
+ else if ( iDateEdwin )
+ {
+ edwin = iDateEdwin;
+ }
+ if ( edwin )
+ {
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ) );
+
+ AknLayoutUtils::LayoutMfne( edwin, layoutRect.Rect(),
+ TAknWindowComponentLayout::ComposeText(
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane_t3( 1 ) ) );
+
+ edwin->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !edwin->IsFocused() )
+ {
+ edwin->SetFocus( ETrue );
+ }
+ edwin->SetUpAndDownKeysConsumed( ETrue );
+ }
+
+ // Layout Edwin editor
+
+ if ( iEdwin )
+ {
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+ TAknTextComponentLayout textLayout =
+ AknLayoutScalable_Apps::area_vitu2_query_pane_t3(1);
+
+ TRect rect( layoutRect.Rect() );
+ rect.iBr.iX -= 10;
+ AknLayoutUtils::LayoutEdwin( iEdwin,
+ rect,
+ textLayout.LayoutLine(),
+ EAknsCIQsnTextColorsCG27,
+ 0,
+ ETrue );
+
+ iEdwin->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !( iEdwin->IsFocused() ) )
+ {
+ iEdwin->SetFocus(ETrue);
+ }
+ }
+ }
+
+void CAknQueryControl::LayoutPromptForFullScreen()
+ {
+ if ( NbrOfPromptLines() != 3 )
+ {
+ return;
+ }
+
+ TBool landscape = Layout_Meta_Data::IsLandscapeOrientation();
+
+ TAknLayoutRect rect;
+ rect.LayoutRect( LayoutRect(), TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Apps::popup_vitu2_window( landscape ? 1 : 0 ),
+ AknLayoutScalable_Apps::area_vitu2_query_pane( landscape ? 1 : 0 ) ).LayoutLine() );
+
+ TAknTextLineLayout lineLayout = AknLayoutScalable_Apps::area_vitu2_query_pane_t4( 1 ).LayoutLine();
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(0), rect.Rect(), lineLayout );
+
+ lineLayout = AknLayoutScalable_Apps::area_vitu2_query_pane_t5( 1 ).LayoutLine();
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(1), rect.Rect(), lineLayout );
+
+ lineLayout = AknLayoutScalable_Apps::area_vitu2_query_pane_t6( 1 ).LayoutLine();
+ AknLayoutUtils::LayoutLabel(iPrompt->Line(2), rect.Rect(), lineLayout );
+ }
+
+EXPORT_C void CAknQueryControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ CEikMfne* edwin = NULL;
+ if ( iTimeEdwin )
+ {
+ edwin = iTimeEdwin;
+ }
+ else if ( iDateEdwin )
+ {
+ edwin = iDateEdwin;
+ }
+ else if ( LocationEd() )
+ {
+ edwin = LocationEd();
+ }
+ else if ( iDurationEdwin )
+ {
+ edwin = iDurationEdwin;
+ }
+
+ if ( edwin && iEditorFrame.Rect().Contains(aPointerEvent.iPosition) )
+ {
+ edwin->HandlePointerEventL(aPointerEvent);
+ }
+ else
+ {
+ CAknControl::HandlePointerEventL(aPointerEvent);
+ }
+ }
+
+EXPORT_C void* CAknQueryControl::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+EXPORT_C void CAknQueryControl::HandleResourceChange(TInt aType)
+ {
+ CCoeControl::HandleResourceChange(aType);
+
+ if( aType == KAknsMessageSkinChange && iExtension->iAnimationId )
+ {
+ TRAP_IGNORE(SetAnimationL( iExtension->iAnimationId ));
+ TRAP_IGNORE(StartAnimationL());
+ }
+ else if( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ SizeChanged();
+ TRAP_IGNORE(DoSetPromptL());
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Return prompt text needed by FEP to query dialog
+// ---------------------------------------------------------------------------
+//
+void CAknQueryControl::GetCaption(TDes& aCaption) const
+ {
+ aCaption = KNullDesC;
+
+ TPtr prompt= iPrompt->Text();
+ if ( prompt != KNullDesC )
+ {
+ const TInt maximumLength=aCaption.MaxLength();
+
+ if ( prompt.Length() > maximumLength )
+ {
+ aCaption=prompt.Left(maximumLength);
+ }
+ else
+ {
+ aCaption= prompt;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sets the state of ECS number visibility in the query.
+// ---------------------------------------------------------------------------
+//
+void CAknQueryControl::SetEcsCbaVisibleL( TBool aVisible )
+ {
+ if ( iExtension &&
+ !COMPARE_BOOLS( aVisible, iExtension->iEcsCbaShown ) &&
+ iFlags.IsSet( EEmergencyCallsCBASupport ) )
+ {
+ CEikDialog* dlg;
+ MopGetObject( dlg );
+ if ( dlg )
+ {
+ CEikButtonGroupContainer& cba = dlg->ButtonGroupContainer();
+
+ if ( aVisible
+ && (GetTextLength() == iEcsDetector->CurrentMatch().Length()) )
+ // Further check to ensure that the matched number is the
+ // entire buffer. Get the matched text and see if is the same
+ // length as the current query length.
+ {
+ HBufC* cbaLabel =
+ StringLoader::LoadLC( R_AVKON_SOFTKEY_CALL_TEXT );
+ cba.AddCommandToStackL( 0,
+ EAknSoftkeyEmergencyCall,
+ *cbaLabel );
+ CleanupStack::PopAndDestroy( cbaLabel );
+ iExtension->iEcsCbaShown = ETrue;
+ }
+ else
+ {
+ if ( iExtension->iEcsCbaShown )
+ {
+ cba.RemoveCommandFromStack( 0, EAknSoftkeyEmergencyCall );
+ iExtension->iEcsCbaShown = EFalse;
+ }
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Attempts an emergency call.
+// ---------------------------------------------------------------------------
+//
+void CAknQueryControl::AttemptEmergencyCallL()
+ {
+ if ( iEcsDetector )
+ {
+ if ( iEcsDetector->State() == CAknEcsDetector::ECompleteMatch )
+ {
+ // Further check to ensure that the matched number is the
+ // entire buffer. Get the matched text and see if is the same
+ // length as the current query length.
+ if ( GetTextLength() == iEcsDetector->CurrentMatch().Length() )
+ {
+ iEcsDetector->AddChar( (TText)EKeyYes );
+ SetEcsCbaVisibleL( EFalse );
+
+ // stop playing tacticons for pincode query
+ StopPinCodeTacticonTimer();
+ }
+ }
+ }
+ }
+
+
+/*****************************
+ * CAknExtQueryControl
+ *****************************/
+
+
+///
+/// Construction and Destruction methods
+///
+
+/**
+ *
+ */
+EXPORT_C CAknExtQueryControl::CAknExtQueryControl() : CAknQueryControl()
+ {
+ AKNTASHOOK_ADD( this, "CAknExtQueryControl" );
+ }
+
+/**
+ *
+ */
+EXPORT_C CAknExtQueryControl::~CAknExtQueryControl()
+ {
+ AKNTASHOOK_REMOVE();
+ if (iFixedPointEditor)
+ AknsUtils::DeregisterControlPosition(iFixedPointEditor);
+ if (iIpEditor)
+ AknsUtils::DeregisterControlPosition(iIpEditor);
+ delete iIpEditor;
+ delete iFixedPointEditor;
+ }
+
+
+void CAknExtQueryControl::ConstructQueryL(TResourceReader& aRes)
+ {
+ if ( iQueryType == EIpLayout)
+ {
+ 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 );
+ }
+ }
+ else if ( iQueryType == EFixedPointLayout)
+ {
+ iFixedPointEditor = new(ELeave)CEikFixedPointEditor;
+ iFixedPointEditor->SetContainerWindowL(*this);
+ iFixedPointEditor->ConstructFromResourceL(aRes);
+ iFixedPointEditor->SetAknEditorAllowedInputModes( EAknEditorNumericInputMode );
+ iFixedPointEditor->SetObserver(this);
+ }
+ else
+ __ASSERT_DEBUG(0, Panic(EAknPanicLayoutControlResourceProblem));
+
+ // Construct editor context
+ CAknQueryExtension* extension = QueryExtension();
+ if( extension )
+ {
+ extension->CreateEditorContextL();
+ }
+ }
+
+
+///
+/// CCoeControl methods
+///
+
+/**
+ *Returns the control owned by this control by the index
+ */
+CCoeControl* CAknExtQueryControl::ComponentControl(TInt anIndex) const
+ {
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iIpEditor,
+ iFixedPointEditor,
+ iImage, iAnimation };
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ //subtle: index is decremented only if control is not NULL!
+ if (controls[ii] && anIndex-- == 0)
+ {
+ return controls[ii];
+ }
+ }
+ return NULL;
+ }
+
+/**
+ * Returns the number of controls inside the compound control.
+ */
+TInt CAknExtQueryControl::CountComponentControls() const
+ {
+ TInt count = 0;
+ CCoeControl* controls[] = { iPrompt,
+ iEditIndicator,
+ iIpEditor,
+ iFixedPointEditor,
+ iImage, iAnimation };
+
+ for (TUint ii=0;ii<sizeof(controls)/sizeof(CCoeControl*);ii++)
+ {
+ if (controls[ii])
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+
+/**
+ * Handle a focus changed
+ */
+void CAknExtQueryControl::FocusChanged(TDrawNow aDrawNow)
+ {
+ CCoeControl* ctrl = ControlByLayoutOrNull( iQueryType );
+ if (ctrl)
+ {
+ ctrl->SetFocus( IsFocused(), aDrawNow );
+ Layout();
+ }
+ }
+
+void CAknExtQueryControl::PrepareForFocusLossL()
+ {
+ CCoeControl* ctrl = ControlByLayoutOrNull( iQueryType );
+ if (ctrl)
+ {
+ ctrl->PrepareForFocusLossL();
+ }
+ }
+
+EXPORT_C void CAknExtQueryControl::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType)
+ {
+ //CAknQueryControl::HandleControlEventL(NULL, aEventType);
+
+ if(iQueryControlObserver && aEventType == EEventStateChanged)
+ {
+ if(GetTextLength())
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorValueValid);
+ }
+ else
+ {
+ iQueryControlObserver->HandleQueryEditorStateEventL(this,MAknQueryControlObserver::EQueryControlEditorStateChanging, MAknQueryControlObserver::EEditorEmpty);
+ }
+ }
+ }
+
+
+///
+/// DRAWING METHODS
+///
+
+/**
+ * Layout the ip editor and its frame.
+ *
+ *
+ * Queries other than confirmation queries have an editor that the user needs
+ * to input the query data. This method does the layout of the editor.
+ *
+ * Data queries have a resizable editor and its layout is specified in the LAF.
+ *
+ * Other queries have a fixed size editor with layout specified.
+ *
+ *
+ * This method is called from SizeChanged. Depending on the query type, the
+ * layout method is chosen accordingly, e.g. data queries use the data query
+ * method, other queires use the code query method.
+ *
+ * The macros at the top are just for avoiding code repetition.
+ */
+void CAknExtQueryControl::LayoutEditor(const TLayoutMethod& aLayoutM)
+ {
+ TIndex LAFIndex(NbrOfPromptLines());
+
+ if (aLayoutM == EDataQueryLayoutM)
+ {
+ iHasEditor = ETrue;
+
+ LayoutEditorFrame(aLayoutM);
+ LayoutEditorIndicator(aLayoutM);
+
+ TInt promptLines = NbrOfPromptLines();
+ TInt numberTextLines = NbrOfEditorLines();
+ TInt isNumeric = 0;
+
+ if ( iFixedPointEditor )
+ {
+ if ( promptLines >= 3 )
+ {
+ AknLayoutUtils::LayoutEdwin( iFixedPointEditor,
+ LayoutRect(),
+ AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_2( LAFIndex.DQPWindowTextsLine2(numberTextLines), isNumeric ),
+ EAknsCIQsnTextColorsCG27 ) ;
+ }
+ else
+ {
+ if ( promptLines == 2 )
+ {
+ AknLayoutUtils::LayoutEdwin( iFixedPointEditor,
+ LayoutRect(),
+ AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_2( LAFIndex.DQPWindowTextsLine2(1), isNumeric ),
+ EAknsCIQsnTextColorsCG27 );
+ }
+ else
+ {
+ AknLayoutUtils::LayoutEdwin( iFixedPointEditor,
+ LayoutRect(),
+ AKN_LAYOUT_MULTILINE_TEXT_Data_query_pop_up_window_texts_Line_2( isNumeric, numberTextLines ),
+ EAknsCIQsnTextColorsCG27 );
+ }
+ }
+ iFixedPointEditor->SetBorder(TGulBorder::ENone);
+ if (IsFocused() && !(iFixedPointEditor->IsFocused()) )
+ iFixedPointEditor->SetFocus(ETrue);
+
+ AknsUtils::RegisterControlPosition( iFixedPointEditor );
+ }
+ }
+ else if (aLayoutM == ETimeQueryLayoutM)
+ {
+ iHasEditor = ETrue;
+
+ LayoutEditorFrame(aLayoutM);
+
+ LayoutEditorIndicator(aLayoutM);
+
+//LAYOUT for IP EDITOR
+ if(iIpEditor)
+ {
+ AknLayoutUtils::LayoutMfne(iIpEditor,LayoutRect(),
+ AKN_LAYOUT_TEXT_Code_query_pop_up_window_texts_Line_2(LAFIndex.PromptLine()));
+
+ iIpEditor->SetBorder( TGulBorder::ENone );
+ if ( IsFocused() && !iIpEditor->IsFocused() )
+ iIpEditor->SetFocus(ETrue);
+ iIpEditor->SetUpAndDownKeysConsumed( ETrue );
+ }
+ }
+ }
+
+EXPORT_C void CAknExtQueryControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ if ( iIpEditor && iEditorFrame.Rect().Contains(aPointerEvent.iPosition) )
+ {
+ iIpEditor->HandlePointerEventL(aPointerEvent);
+ }
+ else
+ {
+ CAknQueryControl::HandlePointerEventL(aPointerEvent);
+ }
+ }
+
+EXPORT_C void* CAknExtQueryControl::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+EXPORT_C TInetAddr CAknExtQueryControl::GetInetAddress() const
+ {
+ TInetAddr ret = TInetAddr();
+ if( iIpEditor )
+ {
+ return iIpEditor->Address();
+ }
+ return ret;
+ }
+
+
+EXPORT_C void CAknExtQueryControl::SetInetAddress(TInetAddr& aInetAddress)
+ {
+ if( iIpEditor )
+ {
+ iIpEditor->SetAddress(aInetAddress);
+ }
+ }
+
+EXPORT_C TInt CAknExtQueryControl::GetFixedPointNumber() const
+ {
+ TInt ret = 0;
+ if( iFixedPointEditor )
+ {
+ return iFixedPointEditor->Value();
+ }
+ return ret;
+ }
+
+
+EXPORT_C void CAknExtQueryControl::SetFixedPointNumberL(const TInt* aNumber)
+ {
+ if( iFixedPointEditor )
+ {
+ iFixedPointEditor->SetValueL(aNumber);
+ }
+ }
+
+
+EXPORT_C void CAknExtQueryControl::SetMinimumAndMaximum(const TInetAddr& aMinimumAddress, const TInetAddr& aMaximumAddress)
+ {
+ if( iIpEditor )
+ {
+ iIpEditor->SetMinimumAndMaximum(aMinimumAddress, aMaximumAddress);
+ }
+ }
+
+EXPORT_C void CAknExtQueryControl::SetMinimumAndMaximum(TInt aMinimumValue, TInt aMaximumValue)
+ {
+ if( iFixedPointEditor )
+ {
+ iFixedPointEditor->SetMinMax(aMinimumValue, aMaximumValue);
+ }
+ }
+
+
+/**
+ * Return text editor depening on query type
+ */
+EXPORT_C CCoeControl* CAknExtQueryControl::ControlByLayoutOrNull(TInt aLayout)
+ {
+ CCoeControl* ctrl=NULL;
+ if ( aLayout == EIpLayout )
+ {
+ ctrl = iIpEditor;
+ }
+ else if ( aLayout == EFixedPointLayout )
+ {
+ ctrl = iFixedPointEditor;
+ }
+ return ctrl;
+ }
+
+
+/**
+* This method looks at the flags that have been set in the query control and
+* acts upon them if possible
+*
+*/
+void CAknExtQueryControl::DeployFlagsL()
+ {
+ }
+
+/**
+* Method to first set the flags and then to use them on the contained editors
+*
+*/
+
+void CAknExtQueryControl::SetAndUseFlagsL(TBitFlags16 /*aFlags*/)
+ {
+ }
+
+void CAknExtQueryControl::SetFlags(TBitFlags16 /*aFlags*/)
+ {
+ }
+
+
+/**
+ * Return true if editor content is valid for query, false
+ * otherwise. Ip editor always have a valid content.
+ *
+ *
+ */
+TBool CAknExtQueryControl::EditorContentIsValidL() const
+ {
+ TInt ret = EFalse;
+ if ( iIpEditor )
+ {
+ CEikMfne* editor = iIpEditor;
+ ret = editor->Field(editor->CurrentField())->IsValid();
+ }
+ else if ( iFixedPointEditor )
+ {
+ TInt intValue;
+ CAknNumericEdwin::TValidationStatus status = iFixedPointEditor->GetValueAsInteger(intValue);
+ ret = status == CAknNumericEdwin::EValueValid;
+ }
+ return ret;
+ }
+
+
+/*****************************************************************
+ * CAknExtQueryControl::TIndex
+ *
+ * Manage indexes into LAF tables
+ *
+ * PN stands for "Popup Note"
+ *
+ * PQD stands for "Popup Query Data'
+ *
+ * 'DPQ' stands for "Data Query Popup"
+ ******************************************************************/
+
+
+CAknExtQueryControl::TIndex::TIndex(TInt aNumberOfPromptLines)
+ : iNumberOfPromptLines(aNumberOfPromptLines)
+ {
+ }
+
+void CAknExtQueryControl::TIndex::SelfTest() const
+ {
+ __ASSERT_DEBUG(iNumberOfPromptLines >= 0 && iNumberOfPromptLines <= 5,
+ Panic(EAknPanicInvalidValue));
+ }
+
+/**
+ * Return index into LAF tables that depend directly on number of prompt lines,
+ * index is equal to number of prompt lines minus one unless there are no prompt
+ * lines in which case the index is zero
+ */
+TInt CAknExtQueryControl::TIndex::PromptLine() const
+ {
+ SelfTest();
+ return iNumberOfPromptLines > 0 ? iNumberOfPromptLines - 1 : 0;
+ }
+
+/**
+ * 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 CAknExtQueryControl::TIndex::DQPWindowTextsLine2(TInt aLineNum) const
+ {
+ SelfTest();
+ __ASSERT_DEBUG(aLineNum > 0 && aLineNum <= 5,Panic(EAknPanicInvalidValue));
+
+ static const TInt KDataQueryPopupWindowTextsLine2Index[3][5] =
+ { {0, 1, 2, 3, 4}, //1 PROMPT LINE
+ {5, 6, 7, 8, 9}, //2 PROMPT LINES
+ {10, 10, 10, 10, 10} }; //3 PROMPT LINES
+
+ return KDataQueryPopupWindowTextsLine2Index[PromptLine()][aLineNum-1];
+ }
+
+TInt CAknExtQueryControl::TIndex::PNWindow() const
+ {
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); // We should never be here
+ return 0;
+ /*
+ SelfTest();
+ static const TInt KPopupNoteWindowIndex[5] = { 0,0,0,1,2 };
+
+ return KPopupNoteWindowIndex[PromptLine()];
+ */
+ }
+
+TInt CAknExtQueryControl::TIndex::PQDWindow(TInt aLineNum) const
+ {
+ (void)aLineNum; // to remove warning
+ __ASSERT_DEBUG(0,Panic(EAknPanicNotSupported)); // We should never be here
+ return 0;
+ /*
+ SelfTest();
+ __ASSERT_DEBUG(aLineNum > 0 && aLineNum <= 5,Panic(EAknPanicInvalidValue));
+
+ static const TInt KPopupQueryDataWindowIndex[3][5] =
+ { {0, 1, 3, 6, 8}, //1 PROMPT LINE
+ {2, 4, 7, 9, 10}, //2 PROMPT LINES
+ {5, 6, 8, 10, 11} }; //3 PROMPT LINES
+
+ return KPopupQueryDataWindowIndex[PromptLine()][aLineNum-1];
+ */
+ }
+
+
+// Callback for doing a redraw when animating pictographs
+TInt CAknExtQueryControl::StaticPictographCallBack( TAny* aPtr )
+ {
+ CAknExtQueryControl* me = static_cast<CAknExtQueryControl*>( aPtr );
+ me->PictographCallBack();
+ return KErrNone;
+ }
+
+void CAknExtQueryControl::PictographCallBack()
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+ for ( TInt i = 0 ; i < iPrompt->NumberOfLines() ; i++ )
+ {
+ CAknPictographInterface* picto = iPrompt->PictographInterface();
+
+ // Only update the note line if it contains pictographs
+
+ if ( picto->Interface()->ContainsPictographs(
+ *( iPrompt->Line( i )->Text() ) ) )
+ {
+ TRect lineRect = iPrompt->Line(i)->Rect();
+ Window().Invalidate( lineRect );
+
+ ActivateGc();
+ Window().BeginRedraw();
+
+ AknsDrawUtils::Background(
+ skin,
+ cc,
+ this,
+#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
+ SystemGc(),
+#else
+ iCoeEnv->SystemGc(),
+#endif
+ lineRect );
+
+ Window().EndRedraw();
+ DeactivateGc();
+
+ // Draw the label after the background.
+ iPrompt->Line( i )->ActivateL(); // Never leaves
+ iPrompt->Line( i )->DrawNow();
+ iPrompt->SetLineModified( i, EFalse );
+ }
+ }
+ }
+
+// End of File