/*
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
* Phonebook Memory entry Defaults dialog methods.
*
*/
// INCLUDE FILES
#include "CPbkMemoryEntryDefaultsDlg.h"
#include <aknlists.h> // EikControlFactory
#include <StringLoader.h>
#include <featmgr.h>
#include <pbkview.rsg>
#include "MPbkClipListBoxText.h"
#include "CPbkFieldListBoxModel.h"
#include <CPbkIconArray.h>
// PbkEng classes
#include <CPbkContactEngine.h>
#include <CPbkFieldInfo.h>
#include <CPbkConstants.h>
#include <CPbkContactItem.h>
#include <DigCleanupResetPointer.h>
#include <CPbkExtGlobals.h>
#include <MPbkExtensionFactory.h>
#include <PbkDebug.h>
// Unnamed namespace for local definitions
namespace {
// LOCAL CONSTANTS AND MACROS
/**
* Enum for default field types. Defines also order of items in list.
*
* Because the list returns the index of the currently displayed item,
* it's been decided to treat the two versions of SMS (regular SMS versus
* the enhanced email-over-sms version) the same when populating the list,
* and differentiate between the two when an SMS operation is selected.
*/
enum TDefaults
{
EPbkCallDefault = 0,
EPbkVideoDefault,
EPbkVoipDefault,
EPbkPocDefault,
EPbkSmsDefault,
EPbkMmsDefault,
EPbkEmailDefault,
KPbkNumberOfDefaults
};
static const TInt KMaxIntLength = 15;
#ifdef _DEBUG
enum TPanicCode
{
EPanicPostCond_Constructor = 1,
EPanicPostCond_ConstructL,
EPanicPreCond_FixIndex
};
static void Panic(TPanicCode aReason)
{
_LIT(KPanicText, "CPbkMemoryEntryDefaultsDlg");
User::Panic(KPanicText, aReason);
}
#endif // _DEBUG
} // namespace
// MODULE DATA STRUCTURES
NONSHARABLE_CLASS(CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg) :
public CBase,
public MPbkClipListBoxText
{
public: // Interface
CPbkMemoryEntryDefaultAssignDlg();
TInt ExecuteLD(CPbkFieldArray& aArray);
~CPbkMemoryEntryDefaultAssignDlg();
public: // from MPbkClipListBoxText
TBool ClipFromBeginning(TDes& aBuffer, TInt aItemIndex,
TInt aSubCellNumber);
private: // Data
/// Own: field selection listbox
CEikFormattedCellListBox* iListBox;
/// Own: popup list for the listbox
CAknPopupList* iPopupList;
/// Ref: Referred TBool is set ETrue in destructor
TBool* iDestroyedPtr;
};
/**
* Returns default field identified by aDefaultIndex from aContact
* or NULL if the default is not set.
*/
TPbkContactItemField* DefaultField
(const CPbkContactItem& aContact, TInt aDefaultIndex)
{
TPbkContactItemField* result = NULL;
switch (aDefaultIndex)
{
case EPbkCallDefault:
{
result = aContact.DefaultPhoneNumberField();
break;
}
case EPbkVideoDefault:
{
result = aContact.DefaultVideoNumberField();
break;
}
case EPbkMmsDefault:
{
result = aContact.DefaultMmsField();
break;
}
case EPbkSmsDefault:
{
if (FeatureManager::FeatureSupported(KFeatureIdEmailOverSms))
{
result = aContact.DefaultEmailOverSmsField();
}
else
{
result = aContact.DefaultSmsField();
}
break;
}
case EPbkEmailDefault:
{
result = aContact.DefaultEmailField();
break;
}
case EPbkVoipDefault:
{
result = aContact.DefaultVoipField();
break;
}
case EPbkPocDefault:
{
result = aContact.DefaultPocField();
break;
}
default:
{
break;
}
}
return result;
}
/**
* Returns the default UI text for default field identified by aDefaultIndex.
*/
HBufC* DefaultFieldTextLC(TInt aDefaultIndex)
{
HBufC* result = NULL;
switch (aDefaultIndex)
{
case EPbkCallDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_CALL_DEFAULT);
break;
}
case EPbkVideoDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_VIDEO_DEFAULT);
break;
}
case EPbkMmsDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_MMS_DEFAULT);
break;
}
case EPbkSmsDefault:
{
// this is the same text for either SMS or EmailOverSms
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_SMS_DEFAULT);
break;
}
case EPbkEmailDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_EMAIL_DEFAULT);
break;
}
case EPbkVoipDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_VOIP_DEFAULT);
break;
}
case EPbkPocDefault:
{
result = StringLoader::LoadLC(R_QTN_PHOB_SETI_POC_DEFAULT);
break;
}
default:
{
break;
}
}
return result;
}
/**
* Returns true if aField is an applicable default field of type identified
* by aDefaultIndex.
*/
TBool IsApplicableDefaultField
(const TPbkContactItemField& aField, TInt aDefaultIndex)
{
TBool result = EFalse;
switch (aDefaultIndex)
{
case EPbkCallDefault:
{
if ( aField.FieldInfo().IsPhoneNumberField() &&
aField.Text().Length() > 0 )
{
result = ETrue;
}
break;
}
case EPbkVideoDefault:
{
if ( aField.FieldInfo().IsPhoneNumberField() &&
aField.Text().Length() > 0 )
{
if ( ( aField.FieldInfo().FieldId() != EPbkFieldIdFaxNumber ) &&
( aField.FieldInfo().FieldId() != EPbkFieldIdPagerNumber ) )
{
result = ETrue;
}
}
break;
}
case EPbkSmsDefault:
{
if (FeatureManager::FeatureSupported(KFeatureIdEmailOverSms))
{
if (aField.FieldInfo().IsEmailOverSmsField() &&
aField.Text().Length() > 0)
{
result = ETrue;
}
}
else
{
if (aField.FieldInfo().IsPhoneNumberField() &&
aField.Text().Length() > 0)
{
result = ETrue;
}
}
break;
}
case EPbkMmsDefault:
{
if (aField.FieldInfo().IsMmsField() &&
aField.Text().Length() > 0)
{
result = ETrue;
}
break;
}
case EPbkEmailDefault:
{
if (aField.FieldInfo().FieldId()==EPbkFieldIdEmailAddress &&
aField.Text().Length() > 0)
{
result = ETrue;
}
break;
}
case EPbkVoipDefault:
{
if ( aField.FieldInfo().IsVoipField() &&
aField.Text().Length() > 0 )
{
result = ETrue;
}
break;
}
case EPbkPocDefault:
{
if (aField.FieldInfo().IsPocField() &&
aField.Text().Length() > 0)
{
result = ETrue;
}
break;
}
default:
{
break;
}
}
// Check that the field contains something
if (aField.IsEmptyOrAllSpaces())
{
result = EFalse;
}
return result;
}
/**
* Sets aField as the default field for aContact identified by aField.
*/
TBool SetDefaultL
(CPbkContactItem& aContact,
TInt aDefaultIndex,
TPbkContactItemField* aField)
{
TBool result = EFalse;
switch (aDefaultIndex)
{
case EPbkCallDefault:
{
aContact.SetDefaultPhoneNumberFieldL(aField);
result = ETrue;
break;
}
case EPbkVideoDefault:
{
aContact.SetDefaultVideoNumberFieldL(aField);
result = ETrue;
break;
}
case EPbkMmsDefault:
{
aContact.SetDefaultMmsFieldL(aField);
result = ETrue;
break;
}
case EPbkSmsDefault:
{
if (FeatureManager::FeatureSupported(KFeatureIdEmailOverSms))
{
aContact.SetDefaultEmailOverSmsFieldL(aField);
}
else
{
aContact.SetDefaultSmsFieldL(aField);
}
result = ETrue;
break;
}
case EPbkEmailDefault:
{
aContact.SetDefaultEmailFieldL(aField);
result = ETrue;
break;
}
case EPbkVoipDefault:
{
aContact.SetDefaultVoipFieldL(aField);
result = ETrue;
break;
}
case EPbkPocDefault:
{
aContact.SetDefaultPocFieldL(aField);
result = ETrue;
break;
}
default:
{
break;
}
}
return result;
}
// ================= MEMBER FUNCTIONS =======================
inline CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultsDlg
(CPbkContactEngine& aEngine, TContactItemId aContactId) :
iContactId(aContactId),
iEngine(aEngine)
{
__ASSERT_DEBUG(
iContactId==aContactId && &iEngine==&aEngine && !iListBox &&
!iDefaultAssignDlg && !iDestroyedPtr,
Panic(EPanicPostCond_Constructor));
}
EXPORT_C CPbkMemoryEntryDefaultsDlg* CPbkMemoryEntryDefaultsDlg::NewL
(TContactItemId aContactId,
CPbkContactEngine& aEngine)
{
CPbkMemoryEntryDefaultsDlg* self = new(ELeave)
CPbkMemoryEntryDefaultsDlg(aEngine, aContactId);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
EXPORT_C void CPbkMemoryEntryDefaultsDlg::ExecuteLD()
{
CAknPopupList::ExecuteLD();
}
CPbkMemoryEntryDefaultsDlg::~CPbkMemoryEntryDefaultsDlg()
{
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("CPbkMemoryEntryDefaultsDlg destructor start"));
if (iDestroyedPtr)
{
*iDestroyedPtr = ETrue;
}
delete iDefaultAssignDlg;
delete iListBox;
FeatureManager::UnInitializeLib();
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("CPbkMemoryEntryDefaultsDlg destructor end"));
}
void CPbkMemoryEntryDefaultsDlg::ProcessCommandL(TInt aCommandId)
{
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("CPbkMemoryEntryDefaultsDlg::ProcessCommandL start"));
switch (aCommandId)
{
case EAknSoftkeyOk:
{
if (DefaultsAssignPopupL(iListBox->CurrentItemIndex()))
{
CreateLinesL();
iListBox->DrawDeferred();
}
// If DefaultsAssignPopupL returns false, this object
// might be destroyed
break;
}
default:
{
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("About to call CAknPopupList::ProcessCommandL"));
CAknPopupList::ProcessCommandL(aCommandId);
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("Called CAknPopupList::ProcessCommandL"));
break;
}
}
PBK_DEBUG_PRINT(PBK_DEBUG_STRING
("CPbkMemoryEntryDefaultsDlg::ProcessCommandL end"));
}
void CPbkMemoryEntryDefaultsDlg::HandleListBoxEventL
(CEikListBox* aListBox, TListBoxEvent aEventType)
{
// Respond to events from listboxitem
if (aListBox == iListBox)
{
if (aEventType == MEikListBoxObserver::EEventEnterKeyPressed)
{
// Ok/Enter key pressed, command is same as EAknSoftkeyOk
ProcessCommandL(EAknSoftkeyOk);
}
}
}
void CPbkMemoryEntryDefaultsDlg::CreateLinesL() const
{
CPbkContactItem* item = iEngine.ReadContactLC(iContactId);
CDesCArray* lines = static_cast<CDesCArray*>
(iListBox->Model()->ItemTextArray());
lines->Reset();
_LIT(KFormat, "%S\t%S");
HBufC* noDefault = StringLoader::LoadLC(R_QTN_PHOB_SETI_NO_DEFAULT);
for (TInt row=0; row < KPbkNumberOfDefaults; ++row)
{
// Only supported lines are created
if (IsSupported(row))
{
HBufC* defaultFieldText = DefaultFieldTextLC(row);
const TPbkContactItemField* field = DefaultField(*item, row);
TPtrC label;
if(field)
{
label.Set(field->Label());
}
else
{
label.Set(*noDefault);
}
// Allocate and format the listbox line
HBufC* lineBuf = HBufC::NewLC(KFormat().Length()
+ defaultFieldText->Length() + label.Length());
TPtr line(lineBuf->Des());
line.Format(KFormat, defaultFieldText, &label);
lines->AppendL(line);
// Cleanup
CleanupStack::PopAndDestroy(2); // lineBuf, defaultFieldText
}
}
CleanupStack::PopAndDestroy(2); // noDefault, item
}
TBool CPbkMemoryEntryDefaultsDlg::DefaultsAssignPopupL(TInt aDefaultIndex)
{
TBool thisDestroyed = EFalse;
iDestroyedPtr = &thisDestroyed;
CPbkContactItem* item = iEngine.OpenContactL(iContactId);
CleanupStack::PushL(item);
CPbkFieldArray* fields = new(ELeave) CPbkFieldArray(4 /*granularity*/);
CleanupStack::PushL(fields);
const TInt fieldCount = item->CardFields().Count();
for (TInt i=0; i < fieldCount; ++i)
{
TPbkContactItemField& field = item->CardFields()[i];
TInt theIndex = FixIndex(aDefaultIndex); // we have to fix the index
if (IsApplicableDefaultField(field, theIndex))
{
fields->AppendL(field);
}
}
iDefaultAssignDlg = new(ELeave) CPbkMemoryEntryDefaultAssignDlg;
TInt fieldIndex = 0;
TRAPD(err, fieldIndex = iDefaultAssignDlg->ExecuteLD(*fields));
iDefaultAssignDlg = NULL;
if (err)
{
User::Leave(err);
}
TBool result = EFalse;
if (!thisDestroyed && fieldIndex >= 0)
{
TPbkContactItemField* field = NULL;
if (fieldIndex < fields->Count())
{
field = &(*fields)[fieldIndex];
}
TInt theIndex = FixIndex(aDefaultIndex); // we have to fix the index
result = SetDefaultL(*item, theIndex, field);
}
CleanupStack::PopAndDestroy(fields);
if (result)
{
iEngine.CommitContactL(*item);
}
else
{
iEngine.CloseContactL(iContactId);
}
CleanupStack::PopAndDestroy(item);
return result;
}
void CPbkMemoryEntryDefaultsDlg::ConstructL()
{
// initialize feature manager
FeatureManager::InitializeLibL();
// Create a list box
iListBox = static_cast<CEikColumnListBox*>
(EikControlFactory::CreateByTypeL
(EAknCtMenuDoublePopupMenuListBox).iControl);
CAknPopupList::ConstructL
(iListBox, R_PBK_SOFTKEYS_ASSIGN_BACK,
AknPopupLayouts::EMenuDoubleWindow);
// Init list box
iListBox->ConstructL(this, CEikListBox::ELeftDownInViewRect);
iListBox->CreateScrollBarFrameL(ETrue);
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
// set title of popuplist
HBufC* heading = StringLoader::LoadLC(R_QTN_PHOB_TITLE_DEFAULT_SETTINGS);
SetTitleL(*heading);
CleanupStack::PopAndDestroy(heading);
CreateLinesL();
__ASSERT_DEBUG(
iListBox && !iDefaultAssignDlg && !iDestroyedPtr,
Panic(EPanicPostCond_ConstructL));
}
////////////////////////////////////////////////////////////
// CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg
inline CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg::
CPbkMemoryEntryDefaultAssignDlg()
{
// CBase::operator new(TLeave) will reset members
}
TInt CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg::ExecuteLD
(CPbkFieldArray& aArray)
{
CleanupStack::PushL(this);
TBool thisDestroyed = EFalse;
iDestroyedPtr = &thisDestroyed;
// Create a list box
iListBox = static_cast<CEikFormattedCellListBox*>
(EikControlFactory::CreateByTypeL
(EAknCtDoubleGraphicPopupMenuListBox).iControl);
// Create a popup list
CAknPopupList* popupList = CAknPopupList::NewL
(iListBox, R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT,
AknPopupLayouts::EMenuDoubleLargeGraphicWindow);
CleanupStack::PushL(popupList);
// Init list box
iListBox->ConstructL(popupList, CEikListBox::ELeftDownInViewRect);
iListBox->CreateScrollBarFrameL(ETrue);
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
// set title of popuplist
// Select number §qtn.phob.title.select.default§
HBufC* heading = StringLoader::LoadLC(R_QTN_PHOB_TITLE_SELECT_DEFAULT);
popupList->SetTitleL(*heading);
CleanupStack::PopAndDestroy(heading);
CPbkIconArray* iconArray = new(ELeave) CPbkIconArray(4 /*granularity*/);
CleanupStack::PushL(iconArray);
iconArray->ConstructFromResourceL(R_PBK_FIELDTYPE_ICONS);
// get extension factory for setting extension icons
CPbkExtGlobals* extGlobal = CPbkExtGlobals::InstanceL();
extGlobal->PushL();
MPbkExtensionFactory& factory = extGlobal->FactoryL();
factory.AddPbkFieldIconsL(NULL, iconArray);
CleanupStack::PopAndDestroy(extGlobal);
CleanupStack::Pop(); // iconArray
iListBox->ItemDrawer()->ColumnData()->SetIconArray(iconArray);
// create model
HBufC* timeFormat = CCoeEnv::Static()->AllocReadResourceLC
(R_QTN_DATE_USUAL);
CPbkFieldListBoxModel::TParams params(aArray, *timeFormat, *iconArray);
CPbkFieldListBoxModel* listBoxModel = CPbkFieldListBoxModel::NewL(params);
CleanupStack::PopAndDestroy(timeFormat);
listBoxModel->SetClipper(*this);
// insert TEXT_NO_DEFAULT as the last item to the array
CPbkFieldListBoxRow* row = CPbkFieldListBoxRow::NewL();
CleanupStack::PushL(row);
TBuf<KMaxIntLength> iconBuffer;
_LIT(KIcon, "%d");
iconBuffer.Format(KIcon, iconArray->FindIcon(EPbkqgn_prop_nrtyp_empty));
row->AppendColumnL(iconBuffer);
HBufC* text = StringLoader::LoadLC(R_QTN_PHOB_SETI_NO_DEFAULT); // LC
row->AppendColumnL(*text);
CleanupStack::PopAndDestroy(text);
row->AppendColumnL(KNullDesC); // empty data field
listBoxModel->AppendRowL(row);
CleanupStack::Pop(row);
iListBox->Model()->SetItemTextArray(listBoxModel);
iListBox->Model()->SetOwnershipType(ELbmOwnsItemArray);
iListBox->Reset();
// show popuplist dialog
TInt index = -1;
TBool res = EFalse;
CleanupStack::Pop(); // popupList
iPopupList = popupList;
TRAPD(err, res = iPopupList->ExecuteLD());
// Reset iPopupList member
if (!thisDestroyed)
{
iPopupList = NULL;
}
// Rethrow any error
if (err != KErrNone)
{
User::Leave(err);
}
if (thisDestroyed)
{
// this object has been destroyed
index = KErrNotFound;
CleanupStack::Pop(); // this
}
else
{
if (res)
{
index = iListBox->CurrentItemIndex();
}
CleanupStack::PopAndDestroy(); // this
}
return index;
}
CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg::
~CPbkMemoryEntryDefaultAssignDlg()
{
if (iDestroyedPtr)
{
*iDestroyedPtr = ETrue;
}
if (iPopupList)
{
iPopupList->CancelPopup();
}
delete iListBox;
}
TBool CPbkMemoryEntryDefaultsDlg::CPbkMemoryEntryDefaultAssignDlg::
ClipFromBeginning (TDes& aBuffer, TInt aItemIndex,
TInt aSubCellNumber)
{
return AknTextUtils::ClipToFit
(aBuffer, AknTextUtils::EClipFromBeginning, iListBox,
aItemIndex, aSubCellNumber);
}
TBool CPbkMemoryEntryDefaultsDlg::IsSupported(TInt aDefaults) const
{
TBool ret(ETrue);
// Skip the line if MMS field not supported
if ( aDefaults == EPbkMmsDefault &&
!FeatureManager::FeatureSupported(KFeatureIdMMS))
{
ret = EFalse;
}
// Skip the line if Email field not supported
else if ( aDefaults == EPbkEmailDefault &&
!FeatureManager::FeatureSupported(KFeatureIdEmailUi))
{
ret = EFalse;
}
// Do not add video fields if they are not enabled
else if ( aDefaults == EPbkVideoDefault &&
!iEngine.Constants()->LocallyVariatedFeatureEnabled
(EPbkLVAddVideoTelephonyFields))
{
ret = EFalse;
}
// Do not add Voip fields if they are not enabled
else if ( aDefaults == EPbkVoipDefault &&
!FeatureManager::FeatureSupported(KFeatureIdCommonVoip) )
{
ret = EFalse;
}
// Do not add POC fields if they are not enabled
else if ( aDefaults == EPbkPocDefault &&
!iEngine.Constants()->LocallyVariatedFeatureEnabled(EPbkLVPOC) )
{
ret = EFalse;
}
return ret;
}
/**
* This method corrects the given focus index to map with TDefaults enum.
*/
inline TInt CPbkMemoryEntryDefaultsDlg::FixIndex(TInt aIndex) const
{
__ASSERT_DEBUG(aIndex < KPbkNumberOfDefaults,
Panic(EPanicPreCond_FixIndex));
TInt ret = aIndex;
for (TInt i=0; i <= ret; ++i)
{
// If the default in question is not supported,
// add one to the index, since there was a missing row
if (!IsSupported(i))
{
++ret;
}
}
return ret;
}
// End of File