javaextensions/pim/framework/src.s60/cpimcontactitem.cpp
changeset 21 2a9601315dfc
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Contact item implementation.
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // CLASS HEADER
       
    20 #include "cpimcontactitem.h"
       
    21 
       
    22 // INTERNAL INCLUDES
       
    23 #include "cpimitemdata.h"
       
    24 #include "pimcontact.h"
       
    25 #include "mpimcontactadaptermanager.h"
       
    26 #include "mpimcontactlistadapter.h"
       
    27 #include "mpimadaptermanager.h"
       
    28 #include "mpimlistadapter.h"
       
    29 #include "cpimcontactvalidator.h"
       
    30 #include "cpimmanager.h"
       
    31 #include "pimpanics.h"
       
    32 #include "logger.h"
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // C++ constructor
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 CPIMContactItem::CPIMContactItem(const CPIMContactValidator& aContactValidator) :
       
    39         CPIMItem(aContactValidator)
       
    40 {
       
    41     JELOG2(EPim);
       
    42 }
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // CPIMContactItem::NewL
       
    46 // Default two-phase constructor
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CPIMContactItem* CPIMContactItem::NewL(
       
    50     const CPIMContactValidator& aContactValidator)
       
    51 {
       
    52     JELOG2(EPim);
       
    53     CPIMContactItem* self = CPIMContactItem::NewLC(aContactValidator);
       
    54     CleanupStack::Pop(self);
       
    55 
       
    56     return self;
       
    57 }
       
    58 
       
    59 // ---------------------------------------------------------------------------
       
    60 // CPIMContactItem::NewLC
       
    61 // Default two-phase constructor. Leaves the item to the cleanup stack
       
    62 // ---------------------------------------------------------------------------
       
    63 //
       
    64 CPIMContactItem* CPIMContactItem::NewLC(
       
    65     const CPIMContactValidator& aContactValidator)
       
    66 {
       
    67     JELOG2(EPim);
       
    68     CPIMContactItem* self = new(ELeave) CPIMContactItem(aContactValidator);
       
    69 
       
    70     CleanupStack::PushL(self);
       
    71     self->ConstructL();
       
    72 
       
    73     return self;
       
    74 }
       
    75 
       
    76 pimbaseitem* pimbaseitem::getContactItemInstance(pimbasemanager* aPimManager)
       
    77 {
       
    78     JELOG2(EPim);
       
    79     CPIMManager* pimManager = reinterpret_cast<CPIMManager*>(aPimManager);
       
    80     CPIMContactItem* contactItem = NULL;
       
    81     TInt error = 0;
       
    82     TRAP(error,
       
    83     {
       
    84         const CPIMContactValidator& contactValidator =
       
    85         pimManager->ContactValidator();
       
    86         contactItem = CPIMContactItem::NewL(contactValidator);
       
    87     }
       
    88         );
       
    89     if (error != KErrNone)
       
    90         throw KErrGeneral;
       
    91     return contactItem;
       
    92 }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // Destructor
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 CPIMContactItem::~CPIMContactItem()
       
    99 {
       
   100     JELOG2(EPim);
       
   101 }
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // CPIMContactItem::SetContactAdapterAssociation
       
   105 // (other items were commented in a header)
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 void CPIMContactItem::SetContactAdapterAssociation(
       
   109     MPIMContactAdapterManager* aContactAdapterManager,
       
   110     MPIMContactListAdapter* aContactListAdapter)
       
   111 {
       
   112     JELOG2(EPim);
       
   113     __ASSERT_DEBUG(aContactAdapterManager, User::Panic(KPIMPanicCategory,
       
   114                    EPIMPanicNullArgument));
       
   115 
       
   116     iContactAdapterManager = aContactAdapterManager;
       
   117     iContactListAdapter = aContactListAdapter;
       
   118 
       
   119     SetBaseAdapterAssociation(iContactAdapterManager->GetAdapterManager(),
       
   120                               iContactListAdapter ? iContactListAdapter->GetPimListAdapter(): NULL);
       
   121 }
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // CPIMContactItem::RemoveAdapterAssociation
       
   125 // (other items were commented in a header)
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 void CPIMContactItem::RemoveAdapterAssociation()
       
   129 {
       
   130     JELOG2(EPim);
       
   131     iContactAdapterManager = NULL;
       
   132     iContactListAdapter = NULL;
       
   133 
       
   134     CPIMItem::RemoveAdapterAssociation();
       
   135 }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // CPIMContactItem::ItemType
       
   139 // (other items were commented in a header)
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 TPIMListType CPIMContactItem::ItemType() const
       
   143 {
       
   144     JELOG2(EPim);
       
   145     return EPIMContactList;
       
   146 }
       
   147 
       
   148 // ---------------------------------------------------------------------------
       
   149 // CPIMContactItem::commit
       
   150 // (other items were commented in a header)
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 void CPIMContactItem::commit()
       
   154 {
       
   155     JELOG2(EPim);
       
   156     TInt error = KErrNone;
       
   157     TRAP(error,
       
   158     {
       
   159         if (iContactAdapterManager)
       
   160         {
       
   161             // The item is associated with a list
       
   162             if (iContactListAdapter)
       
   163             {
       
   164                 // The list is open
       
   165                 if (iItemID->Compare(KPIMNullItemID) == 0)
       
   166                 {
       
   167                     // The item does not have database entry
       
   168                     iContactListAdapter->CreateContactItemL(*this);
       
   169                 }
       
   170                 else
       
   171                 {
       
   172                     // Make sure that the item is fully loaded from the native
       
   173                     // database before committing the changes to it. Note that
       
   174                     // already modified fields must not be overwritten by the
       
   175                     // responsible list adapter
       
   176                     CPIMItem::LoadFullItemL();
       
   177                     iContactListAdapter->WriteContactItemL(*this);
       
   178                 }
       
   179 
       
   180                 SetModified(EFalse);
       
   181                 UpdateUidFieldL(EPIMContactUid, iItemID->Des());   // codescanner::leave
       
   182             }
       
   183             else
       
   184             {
       
   185                 // The associated list is closed
       
   186                 User::Leave(KErrDisconnected);   // codescanner::leave
       
   187             }
       
   188         }
       
   189         else
       
   190         {
       
   191             // The item is not associated with a list
       
   192             User::Leave(KErrDisMounted);   // codescanner::leave
       
   193         }
       
   194     }
       
   195         );
       
   196     if (error != KErrNone)
       
   197         throw error;
       
   198 }
       
   199 
       
   200 // ---------------------------------------------------------------------------
       
   201 // CPIMContactItem::ListClosed
       
   202 // (other items were commented in a header)
       
   203 // ---------------------------------------------------------------------------
       
   204 //
       
   205 void CPIMContactItem::ListClosed()
       
   206 {
       
   207     JELOG2(EPim);
       
   208     iContactListAdapter = NULL;
       
   209     CPIMItem::ListClosed();
       
   210 }
       
   211 
       
   212 // ---------------------------------------------------------------------------
       
   213 // CPIMContactItem::SetPreferredIndexStringL
       
   214 // (other items were commented in a header)
       
   215 // ---------------------------------------------------------------------------
       
   216 //
       
   217 void CPIMContactItem::SetPreferredIndexStringL(const TPIMField& aField,
       
   218         const TInt& aIndex, TPIMAttribute aAttribute)
       
   219 {
       
   220     JELOG2(EPim);
       
   221     const TInt numValues = iItemData->CountValues(aField);
       
   222 
       
   223     // Clear "preferred index" attribute from all values of the field
       
   224     for (TInt i = 0; i < numValues; i++)
       
   225     {
       
   226         TPIMAttribute attributes = iItemData->AttributesL(aField, i);
       
   227         // Clear attributes
       
   228         attributes &= ~aAttribute;
       
   229         iItemData->SetAttributesL(aField, i, attributes);
       
   230     }
       
   231 
       
   232     // Set "preferred index" attribute to the given value of the field
       
   233     TPIMAttribute preferredIndexAttributes = iItemData->AttributesL(
       
   234                 aField, aIndex);
       
   235     // Add preferred index attribute to this attribute set
       
   236     preferredIndexAttributes |= aAttribute;
       
   237     iItemData->SetAttributesL(aField, aIndex, preferredIndexAttributes);
       
   238 }
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // CPIMContactItem::AddStringL
       
   242 // (other items were commented in a header)
       
   243 // ---------------------------------------------------------------------------
       
   244 //
       
   245 void CPIMContactItem::AddStringL(TPIMField aField,
       
   246                                  TPIMAttribute aAttributes, HBufC* aValue)
       
   247 {
       
   248     JELOG2(EPim);
       
   249     CPIMItem::AddStringL(aField, aAttributes, aValue);
       
   250 
       
   251     // If we got this far without leaving, the last value in the field is the
       
   252     // new one. Let's see if it has the preferred index set, and clear the
       
   253     // preferred index from any other values.
       
   254 
       
   255     const TInt lastValueIndex = iItemData->CountValues(aField) - 1;
       
   256     TPIMAttribute lastValueAttributes = iItemData->AttributesL(aField,
       
   257                                         lastValueIndex);
       
   258 
       
   259     // Set preferred attribute
       
   260     if (lastValueAttributes & EPIMContactAttrPreferred)
       
   261     {
       
   262         SetPreferredIndexStringL(aField, lastValueIndex,
       
   263                                  EPIMContactAttrPreferred);
       
   264     }
       
   265     // Set preferred SMS attribute
       
   266     if (lastValueAttributes & EPIMContactAttrSms)
       
   267     {
       
   268         SetPreferredIndexStringL(aField, lastValueIndex,
       
   269                                  EPIMContactAttrSms);
       
   270     }
       
   271 }
       
   272 
       
   273 // ---------------------------------------------------------------------------
       
   274 // CPIMContactItem::SetStringL
       
   275 // (other items were commented in a header)
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 void CPIMContactItem::SetStringL(TPIMField aField, TInt aIndex,
       
   279                                  TPIMAttribute aAttributes, HBufC* aValue)
       
   280 {
       
   281     JELOG2(EPim);
       
   282     CPIMItem::SetStringL(aField, aIndex, aAttributes, aValue);
       
   283 
       
   284     // If we got this far without leaving, the freshly set value in the field
       
   285     // might have preferred index set. If so, we clear the preferred index
       
   286     // from any other values.
       
   287 
       
   288     TPIMAttribute realValueAttributes = iItemData->AttributesL(aField,
       
   289                                         aIndex);
       
   290 
       
   291     // Set preferred attribute
       
   292     if (realValueAttributes & EPIMContactAttrPreferred)
       
   293     {
       
   294         SetPreferredIndexStringL(aField, aIndex,
       
   295                                  EPIMContactAttrPreferred);
       
   296     }
       
   297     // Set preferred SMS attribute
       
   298     if (realValueAttributes & EPIMContactAttrSms)
       
   299     {
       
   300         SetPreferredIndexStringL(aField, aIndex, EPIMContactAttrSms);
       
   301     }
       
   302 }
       
   303 
       
   304 // ---------------------------------------------------------------------------
       
   305 // CPIMContactItem::SetContactItemIdL
       
   306 // (other items were commented in a header)
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 void CPIMContactItem::SetContactItemIdL(
       
   310     const TPIMItemID& aContactItemId)
       
   311 {
       
   312     JELOG2(EPim);
       
   313     // Set item id for the base class
       
   314     CPIMItem::SetIdL(aContactItemId);
       
   315 
       
   316     // Update UID field if it is supported by this contact item
       
   317     if (iAdapterManager && iAdapterManager->IsSupportedField(
       
   318                 EPIMContactUid))
       
   319     {
       
   320         UpdateUidFieldL(EPIMContactUid, aContactItemId);
       
   321     }
       
   322 }
       
   323 
       
   324 // ---------------------------------------------------------------------------
       
   325 // CPIMContactItem::SetContactItemIdL
       
   326 // (other items were commented in a header)
       
   327 // ---------------------------------------------------------------------------
       
   328 //
       
   329 void CPIMContactItem::SetContactItemIdL(const TUint aContactItemId)
       
   330 {
       
   331     JELOG2(EPim);
       
   332     TBuf8<KPIMItemIdDesSize> entryId;
       
   333     entryId.Num(static_cast<TUint>(aContactItemId));
       
   334 
       
   335     // Set item id for the base class
       
   336     CPIMItem::SetIdL(entryId);
       
   337 
       
   338     // Update UID field if it is supported by this contact item
       
   339     if (iAdapterManager && iAdapterManager->IsSupportedField(
       
   340                 EPIMContactUid))
       
   341     {
       
   342         UpdateUidFieldL(EPIMContactUid, entryId);
       
   343     }
       
   344 }
       
   345 
       
   346 // ---------------------------------------------------------------------------
       
   347 // CPIMContactItem::ContactItemId
       
   348 // (other items were commented in a header)
       
   349 // ---------------------------------------------------------------------------
       
   350 //
       
   351 TUint CPIMContactItem::ContactItemIdL() const
       
   352 {
       
   353     JELOG2(EPim);
       
   354     // Return zero if there is no contact item id
       
   355     if (CPIMItem::GetId() == KPIMNullItemID)
       
   356     {
       
   357         return 0;
       
   358     }
       
   359     // Convert PIM item id to contact database
       
   360     // item id, so it is easier to use
       
   361     TUint id(0);
       
   362     TLex8 lex(iItemID->Des());
       
   363     TInt status = lex.Val(id);
       
   364     User::LeaveIfError(status);
       
   365 
       
   366     return id;
       
   367 }
       
   368 
       
   369 // ---------------------------------------------------------------------------
       
   370 // CPIMContactItem::SetLastModifiedL
       
   371 // (other items were commented in a header)
       
   372 // ---------------------------------------------------------------------------
       
   373 //
       
   374 void CPIMContactItem::SetLastModifiedL(TPIMDate aLastModified)
       
   375 {
       
   376     JELOG2(EPim);
       
   377     CPIMItem::SetLastModifiedL(aLastModified);
       
   378     // Update revision field if it is supported
       
   379     if (iAdapterManager && iAdapterManager->IsSupportedField(
       
   380                 EPIMContactRevision))
       
   381     {
       
   382         UpdateRevisionFieldL(EPIMContactRevision, LastModified());
       
   383     }
       
   384 }
       
   385 
       
   386 // ---------------------------------------------------------------------------
       
   387 // CPIMContactItem::PrepareForLoadL
       
   388 // (other items were commented in a header)
       
   389 // ---------------------------------------------------------------------------
       
   390 //
       
   391 void CPIMContactItem::PrepareForLoadL()
       
   392 {
       
   393     JELOG2(EPim);
       
   394     // Prepare base class for loading from the database
       
   395     CPIMItem::PrepareForLoadL();
       
   396 }
       
   397 
       
   398 // ---------------------------------------------------------------------------
       
   399 // CPIMContactItem::IsReadOnly
       
   400 // (other items were commented in a header)
       
   401 // ---------------------------------------------------------------------------
       
   402 //
       
   403 TBool CPIMContactItem::IsReadOnly(const TPIMField& aField)
       
   404 {
       
   405     JELOG2(EPim);
       
   406     TBool retVal = EFalse;
       
   407 
       
   408     // UID and REVISION fields are read-only if the item
       
   409     // has been persisted
       
   410     if (aField == EPIMContactUid || aField == EPIMContactRevision)
       
   411     {
       
   412         retVal = (iItemID->Compare(KPIMNullItemID) != 0);
       
   413     }
       
   414 
       
   415     return retVal;
       
   416 }
       
   417 
       
   418 // ---------------------------------------------------------------------------
       
   419 // CPIMContactItem::DoLoadFullItemL
       
   420 // (other items were commented in a header)
       
   421 // ---------------------------------------------------------------------------
       
   422 //
       
   423 void CPIMContactItem::DoLoadFullItemL()
       
   424 {
       
   425     JELOG2(EPim);
       
   426     __ASSERT_DEBUG(iInitializedFields || iContactListAdapter,
       
   427                    User::Panic(KPIMPanicCategory, EPIMPanicInvalidState));
       
   428 
       
   429     // Read full contact item from the adapter. It means that all possible
       
   430     // fields are added to this item and the item becomes full.
       
   431     TRAPD(err, iContactListAdapter->ReadContactItemL(*this));
       
   432     // KErrNotFound indicates that item has been removed and we need to return
       
   433     // only those fields which are currently in the item
       
   434     __ASSERT_ALWAYS((err == KErrNone) || (err == KErrNotFound),
       
   435                     User::Leave(err));
       
   436     // Reset initialized field to mark that the item is fully loaded
       
   437     delete iInitializedFields;
       
   438     iInitializedFields = NULL;
       
   439 }
       
   440 
       
   441 // ---------------------------------------------------------------------------
       
   442 // CPIMContactItem::DoLoadFieldL
       
   443 // (other items were commented in a header)
       
   444 // ---------------------------------------------------------------------------
       
   445 //
       
   446 void CPIMContactItem::DoLoadFieldL(const TPIMField aField)
       
   447 {
       
   448     JELOG2(EPim);
       
   449     __ASSERT_DEBUG(iInitializedFields || iContactListAdapter,
       
   450                    User::Panic(KPIMPanicCategory, EPIMPanicInvalidState));
       
   451 
       
   452     // Note that revision and uid can not be loaded separately. Those fields
       
   453     // will be added to the item when it is generated and associated with a list
       
   454     if (aField != EPIMContactRevision && aField != EPIMContactUid)
       
   455     {
       
   456         iContactListAdapter->ReadContactFieldL(*this,
       
   457                                                static_cast<TPIMContactField>(aField));
       
   458     }
       
   459 
       
   460     // The field is now read form the adapter, so we add it to the list
       
   461     // because there is no need to load this field anymore
       
   462     iInitializedFields->AppendL(aField);
       
   463 }
       
   464 
       
   465 // ---------------------------------------------------------------------------
       
   466 // CPIMContactItem::GetItemData
       
   467 // (other items were commented in a header)
       
   468 // ---------------------------------------------------------------------------
       
   469 //
       
   470 MPIMItemData& CPIMContactItem::ItemData()
       
   471 {
       
   472     JELOG2(EPim);
       
   473     return *iItemData;
       
   474 }
       
   475 
       
   476 // ---------------------------------------------------------------------------
       
   477 // CPIMContactItem::GetItemData
       
   478 // (other items were commented in a header)
       
   479 // ---------------------------------------------------------------------------
       
   480 //
       
   481 const MPIMItemData& CPIMContactItem::ItemData() const
       
   482 {
       
   483     JELOG2(EPim);
       
   484     return *iItemData;
       
   485 }
       
   486 
       
   487 // ---------------------------------------------------------------------------
       
   488 // CPIMContactItem::GetPreferredIndex
       
   489 // (other items were commented in a header)
       
   490 // ---------------------------------------------------------------------------
       
   491 //
       
   492 
       
   493 int CPIMContactItem::getPreferredIndex(TPIMField aField) const
       
   494 {
       
   495     JELOG2(EPim);
       
   496     TInt error = KErrNone;
       
   497     int retVal = 0;
       
   498     TRAP(error,
       
   499     {
       
   500         LeaveIfInvalidOrUnsupportedFieldL(aField);
       
   501         retVal = DoGetPreferredIndexL(aField);
       
   502     });
       
   503     if (error != KErrNone)
       
   504         throw error;
       
   505     return retVal;
       
   506 }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // CPIMContactItem::DoGetPreferredIndexL
       
   510 // (other items were commented in a header)
       
   511 // ---------------------------------------------------------------------------
       
   512 //
       
   513 TInt CPIMContactItem::DoGetPreferredIndexL(const TPIMField& aField) const
       
   514 {
       
   515     JELOG2(EPim);
       
   516     const TPIMFieldDataType fieldType = fieldDataType(aField);
       
   517 
       
   518     // Check that the field is valid
       
   519     if (EPIMFieldInvalid == fieldType)
       
   520     {
       
   521         User::Leave(KErrArgument);
       
   522     }
       
   523 
       
   524     // The field is valid. If it is not a string field, it cannot have
       
   525     // preferred index (in the Nokia implementation).
       
   526     switch (fieldType)
       
   527     {
       
   528     case EPIMFieldString:
       
   529     {
       
   530         // Search through values of the field
       
   531         TInt count = iItemData->CountValues(aField);
       
   532 
       
   533         for (TInt i = 0; i < count; i++)
       
   534         {
       
   535             TPIMAttribute attributes = iItemData->AttributesL(
       
   536                                            aField, i);
       
   537             if ((attributes & EPIMContactAttrPreferred) != 0)
       
   538             {
       
   539                 return i;
       
   540             }
       
   541         }
       
   542         return KPIMNoPreferredIndex;
       
   543     }
       
   544     default:
       
   545     {
       
   546         // Not supported.
       
   547         // We must not leave, but just ignore the query and return
       
   548         // "not set".
       
   549         return KPIMNoPreferredIndex;
       
   550     }
       
   551     }
       
   552 }
       
   553 
       
   554 //  End of File