phonebookengines/contactsmodel/cntplsql/src/cntpplviewmanager.cpp
branchRCL_3
changeset 20 f4a778e096c2
parent 0 e686773b3f54
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19  @released
       
    20 */
       
    21 
       
    22 #include "cntpplviewmanager.h"
       
    23 #include "cntsqlprovider.h"
       
    24 #include "dbsqlconstants.h"
       
    25 #include "cntpersistenceutility.h"
       
    26 
       
    27 const TInt KViewSessionsGranularity = 4;
       
    28 
       
    29 
       
    30 /**
       
    31 Object factory method.
       
    32 */
       
    33 CCntPplViewManager* CCntPplViewManager::NewL(CPplContactsFile& aContactsFile, const CLplContactProperties& aContactProperties)
       
    34 	{
       
    35 	CCntPplViewManager* manager = new (ELeave) CCntPplViewManager(aContactsFile, aContactProperties);
       
    36 	CleanupStack::PushL(manager);
       
    37 	manager->ConstructL();
       
    38 	CleanupStack::Pop(manager);
       
    39 	return manager;
       
    40 	}
       
    41 
       
    42 	
       
    43 /**
       
    44 CCntPplViewManager first phase constructor.
       
    45 */
       
    46 CCntPplViewManager::CCntPplViewManager(CPplContactsFile& aContactsFile, const CLplContactProperties& aContactProperties)
       
    47 :  	iContactsFile(aContactsFile),
       
    48 	iContactProperties(aContactProperties),
       
    49 	iNextViewId(KPLViewSessionIdNull + 1),
       
    50 	iViewSessions(KViewSessionsGranularity)
       
    51 	{
       
    52 	}
       
    53 
       
    54 	
       
    55 /**
       
    56 CCntPplViewManager destructor.
       
    57 */
       
    58 CCntPplViewManager::~CCntPplViewManager()
       
    59 	{
       
    60 	iViewSessions.ResetAndDestroy();
       
    61 	delete iSelectFullFieldsStmt;
       
    62 	}
       
    63 
       
    64 
       
    65 /**
       
    66 CCntPplViewManager second phase constructor.
       
    67 */
       
    68 void CCntPplViewManager::ConstructL()
       
    69 	{
       
    70 	/* 
       
    71 	Construct select statement:
       
    72 	"SELECT contact_id, type_flags, first_name, last_name, company_name, firstname_prn, 
       
    73 			lastname_prn, companyname_prn, text_fields_header, text_fields 
       
    74      FROM contact WHERE contact_id == :SeekId"
       
    75 	*/
       
    76 	TCntSqlStatementType statementType(ESelect, KSqlContactTableName);
       
    77 	iSelectFullFieldsStmt = TSqlProvider::GetSqlStatementL(statementType);
       
    78 
       
    79 	// To select id, type flags, and all fast access fields.	
       
    80 	iSelectFullFieldsStmt->SetParamL(KContactId(), KSpace());
       
    81 	iSelectFullFieldsStmt->SetParamL(KContactTypeFlags(), KSpace());
       
    82 	iSelectFullFieldsStmt->SetParamL(KContactFirstName(), KSpace());
       
    83 	iSelectFullFieldsStmt->SetParamL(KContactLastName(), KSpace());
       
    84 	iSelectFullFieldsStmt->SetParamL(KContactCompanyName(), KSpace());
       
    85 	iSelectFullFieldsStmt->SetParamL(KContactFirstNamePrn(), KSpace());
       
    86 	iSelectFullFieldsStmt->SetParamL(KContactLastNamePrn(), KSpace());
       
    87 	iSelectFullFieldsStmt->SetParamL(KContactCompanyNamePrn(), KSpace());
       
    88 	
       
    89 	// Also select text header, and text blob
       
    90 	iSelectFullFieldsStmt->SetParamL(KContactTextFieldHeader(), KSpace());
       
    91 	iSelectFullFieldsStmt->SetParamL(KContactTextFields(), KSpace());
       
    92 	
       
    93 	// Add selecting condition
       
    94 	HBufC* condition = HBufC::NewLC(KSelectCondition_SearchForEqual().Length() + KContactId().Length());
       
    95 	TPtr ptrCondition = condition->Des();
       
    96 	ptrCondition.Format(KSelectCondition_SearchForEqual(), &KContactId);
       
    97 		
       
    98 	iSelectFullFieldsStmt->SetConditionL(ptrCondition);
       
    99 	
       
   100 	CleanupStack::PopAndDestroy(condition);
       
   101 	}
       
   102 
       
   103 	
       
   104 /**
       
   105 Create a new view session which is mapping to a local view.
       
   106 
       
   107 @param aTextDef the text definition for the view
       
   108 @param aViewPrefs the view preferences for the view.
       
   109 @return the view session id created for the local view.
       
   110 */
       
   111 TInt CCntPplViewManager::OpenViewL(const CContactTextDef& aTextDef, const TContactViewPreferences aViewPrefs)
       
   112 	{
       
   113 	CCntPplViewSession* viewSession = CCntPplViewSession::NewL(iContactsFile, 
       
   114 			iContactProperties, *iSelectFullFieldsStmt, iNextViewId, aTextDef, aViewPrefs);	
       
   115 	CleanupStack::PushL(viewSession);
       
   116 	iViewSessions.AppendL(viewSession);
       
   117 	CleanupStack::Pop(viewSession);
       
   118 
       
   119 	//there is no relationship between the iViewSessions index (subscript) and iNextViewId
       
   120 	return iNextViewId++;
       
   121 	}
       
   122 
       
   123 	
       
   124 /**
       
   125 Close a view session.
       
   126 
       
   127 @param aViewId the id of the view session to be closed
       
   128 */
       
   129 void CCntPplViewManager::CloseView(TInt aViewId)
       
   130 	{
       
   131 	TInt index = FindViewSessionIndexById(aViewId);
       
   132 	if(index != KErrNotFound)
       
   133 		{
       
   134 		CCntPplViewSession* viewSession = iViewSessions[index];
       
   135 		iViewSessions.Remove(index);
       
   136 		delete viewSession;	
       
   137 		}
       
   138 	}
       
   139 
       
   140 
       
   141 /**
       
   142 Change a sort order for a view session.
       
   143 
       
   144 @param aViewId the id of the view session
       
   145 @param aTextDef the new sort order/text definition.
       
   146 */
       
   147 void CCntPplViewManager::ChangeSortOrderL(TInt aViewId, const CContactTextDef& aTextDef)
       
   148 	{
       
   149 	FindViewSessionByIdL(aViewId)->ChangeSortOrderL(aTextDef);
       
   150 	}
       
   151 	
       
   152 	
       
   153 /**
       
   154 Start iteration in a view session.
       
   155 
       
   156 @param aViewId the id of the view session
       
   157 */
       
   158 void CCntPplViewManager::BeginIterateL(TInt aViewId)
       
   159 	{
       
   160 	FindViewSessionByIdL(aViewId)->BeginIterateL();
       
   161 	}
       
   162 
       
   163 	
       
   164 /**
       
   165 End iteration in a view session.
       
   166 
       
   167 @param aViewId the id of the view session
       
   168 */
       
   169 void CCntPplViewManager::EndIterateL(TInt aViewId)
       
   170 	{
       
   171 	FindViewSessionByIdL(aViewId)->EndIterate();
       
   172 	}
       
   173 
       
   174 	
       
   175 /**
       
   176 Get next view item in a view session.
       
   177 
       
   178 @param aViewId the id of the view session
       
   179 @return the view item got from the database
       
   180 @leave KErrNotFound if iterator reachs the end of rows.
       
   181 */
       
   182 CViewContact* CCntPplViewManager::NextItemL(TInt aViewId, TContactViewPreferences aViewPrefs)
       
   183 	{
       
   184 	return FindViewSessionByIdL(aViewId)->NextItemL(aViewPrefs);
       
   185 	}
       
   186 
       
   187 	
       
   188 /**
       
   189 Get view item by given contact id in a view session.
       
   190 
       
   191 @param aViewId the id of the view session
       
   192 @return the view item got from the database
       
   193 @leave KErrNotFound if there is not the row.
       
   194 */
       
   195 CViewContact* CCntPplViewManager::ItemAtL(TContactItemId aContactId, TInt aViewId)
       
   196 	{
       
   197 	return FindViewSessionByIdL(aViewId)->ItemAtL(aContactId);
       
   198 	}
       
   199 
       
   200 	
       
   201 /**
       
   202 Find a view session by given view session id.
       
   203 
       
   204 @param aViewId the id of the view session
       
   205 @return the view session
       
   206 @leave KErrArgument if there is not such a view session.
       
   207 */
       
   208 CCntPplViewSession* CCntPplViewManager::FindViewSessionByIdL(TInt aViewId) const
       
   209 	{
       
   210 	ASSERT(aViewId >= 0);
       
   211 	TInt index = FindViewSessionIndexById(aViewId);
       
   212 	if(index == KErrNotFound)
       
   213 	    {
       
   214 		User::Leave(KErrNotFound);
       
   215 	    }
       
   216 	    
       
   217 	return iViewSessions[index];
       
   218 	}	
       
   219 
       
   220 	
       
   221 /**
       
   222 Find a view session by given view session id.
       
   223 
       
   224 @param aViewId the id of the view session
       
   225 @return the index of view session stored in view session array
       
   226         KNotFoundIndex if there is not such a view session.
       
   227 */
       
   228 TInt CCntPplViewManager::FindViewSessionIndexById(TInt aViewId) const 
       
   229 	{
       
   230 	TInt index = KErrNotFound;
       
   231 	TInt count = iViewSessions.Count();
       
   232 	for(TInt i = 0; i < count; ++i)
       
   233 		{
       
   234 		ASSERT(iViewSessions[i] != NULL);
       
   235 		if(aViewId == iViewSessions[i]->ViewId())
       
   236 			{		
       
   237 			index = i;
       
   238 			break;
       
   239 			}
       
   240 		}
       
   241 	return index;	
       
   242 	}	
       
   243 
       
   244 
       
   245 /**
       
   246 CContactDatabase::ReadContactTextDefL() uses a text definition - a way of 
       
   247 grouping fields to form a string which represents a contact item - to
       
   248 build up a string from a contact item.
       
   249 
       
   250 When creating the string, the contact item is searched for fields whose type 
       
   251 matches one of the fields specified in the text definition.
       
   252 
       
   253 The contents of the first matching field of each type found in the
       
   254 item are read into the string.
       
   255 
       
   256 These strings may be separated using a field separator, which is also specified 
       
   257 in the text definition.  A separator is not appended to the last field used to 
       
   258 make up the string.  It is only inserted when there is a following non-empty
       
   259 field.
       
   260 
       
   261 @param aContactId The contact ID for which the text definition is required.
       
   262 @param aResult The string representing the contact item. 
       
   263 @param aTextDef The text definition which contains the fields that are read 
       
   264 and returned in the aResult string.
       
   265 
       
   266 @return the contact type uid for the specified contact.				  
       
   267 */
       
   268 TUid CCntPplViewManager::ReadContactTextDefL(TContactItemId aContactId, TDes &aResult,const CContactTextDef& aTextDef)
       
   269     {
       
   270     if (! iContactsFile.IsOpened())
       
   271     	{
       
   272     	User::Leave(KErrInUse);
       
   273     	}
       
   274     
       
   275 	RSqlStatement contactSqlStmt;
       
   276 	CleanupClosePushL(contactSqlStmt);
       
   277 	
       
   278 	/* we have to reload the row from SQL database to cache in text header and text blob */ 	
       
   279 	contactSqlStmt.PrepareL(iContactsFile.NamedDatabase(), iSelectFullFieldsStmt->SqlStringL());
       
   280 	User::LeaveIfError(contactSqlStmt.BindInt(KFirstIndex, aContactId)); //Bind item id into the condition.	
       
   281 	
       
   282 	TInt err = contactSqlStmt.Next();
       
   283 	if(err == KSqlAtEnd)
       
   284 		{
       
   285 		//couldn't find the contact
       
   286 		err = KErrNotFound;
       
   287 		}			
       
   288 		
       
   289 	User::LeaveIfError(err);
       
   290 	
       
   291 	TInt typeFlags = contactSqlStmt.ColumnInt(iSelectFullFieldsStmt->ParameterIndex(KContactTypeFlags()));
       
   292 	TUid contactTypeUid = TCntPersistenceUtility::TypeFlagsToContactTypeUid(typeFlags);
       
   293 	TInt attr = (typeFlags & EContactAttributes_Mask) >> EContactAttributes_Shift; 
       
   294 	
       
   295 	if((attr & EContactAttrsFlags_Deleted) == 0) 
       
   296 		{
       
   297 		//Only read text def for not deleted contact.
       
   298     	TBuf<KMaxContactTextSeperator> nextSeperator;
       
   299     	TContactTextDefItem textDefItem;
       
   300     	
       
   301     	// Mark the first iteration in the loop.
       
   302     	TBool firstText = ETrue;
       
   303 
       
   304     	TInt max = aTextDef.Count();
       
   305      	for(TInt i=0; i<max; ++i)
       
   306     		{
       
   307     		// Recreate the TTextFieldMinimal on each iteration.
       
   308     		CContactDatabase::TTextFieldMinimal textFieldMin;
       
   309     		textDefItem = aTextDef[i];
       
   310     		// Populate the TTextFieldMinimal.
       
   311     		CCntPplViewSession::TextFieldL(contactSqlStmt, *iSelectFullFieldsStmt, iContactProperties.SystemTemplateL(), textDefItem.iFieldType, textFieldMin);
       
   312     		// Append the returned text.
       
   313     		if (textFieldMin.Length() > 0)
       
   314     			{
       
   315     			// Only add a seperator after the first text has been appended.
       
   316     			if ((firstText == EFalse) && (aResult.MaxLength() > aResult.Length()))
       
   317     				{
       
   318     				aResult.Append(nextSeperator.Left(Min(aResult.MaxLength() - aResult.Length(), nextSeperator.Length())));	
       
   319     				}
       
   320     			aResult.Append(textFieldMin.Left(Min(aResult.MaxLength() - aResult.Length(),textFieldMin.Length())));
       
   321     			firstText = EFalse; 
       
   322     			}
       
   323     		nextSeperator = textDefItem.iSeperator;
       
   324     		}
       
   325     	
       
   326     	// Add the best match if it was requested.
       
   327     	if(aResult.Length() == 0 && const_cast<CContactTextDef&>(aTextDef).ExactMatchOnly() == EFalse)
       
   328     		{
       
   329     		CContactDatabase::TTextFieldMinimal textFieldMin;
       
   330     		if (aTextDef.FallbackField() != KUidContactFieldNone) 
       
   331     			{
       
   332     			CCntPplViewSession::TextFieldL(contactSqlStmt, *iSelectFullFieldsStmt, iContactProperties.SystemTemplateL(), aTextDef.FallbackField(), textFieldMin);
       
   333     			}
       
   334     		if(textFieldMin.Length() == 0) // No results from call to TextFieldL()?
       
   335     			{
       
   336     			CCntPplViewSession::TextFieldL(contactSqlStmt, *iSelectFullFieldsStmt, iContactProperties.SystemTemplateL(), KUidContactFieldMatchAll, textFieldMin);
       
   337     			}
       
   338     		aResult.Append(textFieldMin.Left(Min(aResult.MaxLength(),textFieldMin.Length())));
       
   339     		}
       
   340 		} //if((attr & EContactAttrsFlags_Deleted) != 0) 
       
   341 	
       
   342 	CleanupStack::PopAndDestroy(&contactSqlStmt);
       
   343 	
       
   344 	return contactTypeUid;
       
   345     }
       
   346 
       
   347 
       
   348 /** 
       
   349 Retrieve the field text for the given field type and contact item ID.
       
   350 
       
   351 The behaviour differs when a specific field type is not given i.e. when
       
   352 aFieldType is KUidContactFieldMatchAll:
       
   353 
       
   354 - First tries to find an email for the given contact item ID.
       
   355 - If there is no email then it retrieves the first entry in Fast Access fields
       
   356 for the given contact item ID.
       
   357 - If there is no Fast Access fields then it retrieves the first entry in the
       
   358 text fields blob for the given contact item ID.
       
   359 
       
   360 Text for all other field types are retrieved from the text fields blob.
       
   361 
       
   362 The caller must determine that the given contact item ID exists before calling
       
   363 this method.
       
   364 
       
   365 @param aContactId The contact ID for which the field text is required.
       
   366 @param aFieldType the field type to determine what kind of text client required. 
       
   367 @param aText the reference to the buffer of final found field text.
       
   368 */
       
   369 void CCntPplViewManager::TextFieldL(TInt aContactId, TFieldType aFieldType, TDes& aText)
       
   370     {
       
   371     if (! iContactsFile.IsOpened())
       
   372     	{
       
   373     	User::Leave(KErrInUse);
       
   374     	}
       
   375     
       
   376 	RSqlStatement contactSqlStmt;
       
   377 	CleanupClosePushL(contactSqlStmt);
       
   378 	
       
   379 	/* we have to reload the row from SQL database to cache in text header and text blob */ 	
       
   380 	contactSqlStmt.PrepareL(iContactsFile.NamedDatabase(), iSelectFullFieldsStmt->SqlStringL());
       
   381 	User::LeaveIfError(contactSqlStmt.BindInt(KFirstIndex, aContactId)); //Bind item id into the condition.	
       
   382 	
       
   383 	TInt err = contactSqlStmt.Next();
       
   384 	if(err == KSqlAtEnd)
       
   385 		{
       
   386 		//couldn't find the contact
       
   387 		err = KErrNotFound;
       
   388 		}			
       
   389 		
       
   390 	User::LeaveIfError(err);
       
   391 	
       
   392     CCntPplViewSession::TextFieldL(contactSqlStmt, *iSelectFullFieldsStmt, iContactProperties.SystemTemplateL(), aFieldType, aText);    
       
   393     
       
   394 	CleanupStack::PopAndDestroy(&contactSqlStmt);
       
   395     }
       
   396