|
1 /* |
|
2 * Copyright (c) 2004-2007 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: The virtual phonebook field factory |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDES |
|
20 |
|
21 // From VirtualPhonebook |
|
22 #include "CFieldFactory.h" |
|
23 #include "CFieldTypeMap.h" |
|
24 #include "CFieldInfo.h" |
|
25 #include <TVPbkFieldVersitProperty.h> |
|
26 #include <MVPbkFieldType.h> |
|
27 #include <RLocalizedResourceFile.h> |
|
28 #include <VPbkDataCaging.hrh> |
|
29 #include <VPbkCntModelRes.rsg> |
|
30 |
|
31 // System includes |
|
32 #include <cntdef.hrh> |
|
33 #include <cntitem.h> |
|
34 #include <barsread.h> |
|
35 |
|
36 namespace { |
|
37 |
|
38 // CONSTANTS |
|
39 _LIT(KCntExtResFile, "VPbkCntModelRes.rsc"); |
|
40 } |
|
41 |
|
42 namespace VPbkCntModel { |
|
43 |
|
44 TBool ContainsField( CFieldsInfo& aFieldsInfo, |
|
45 const CContactItemField& aField ) |
|
46 { |
|
47 const TInt count = aFieldsInfo.Count(); |
|
48 for ( TInt i = 0; i < count; ++i ) |
|
49 { |
|
50 if ( aFieldsInfo[i]->IsEqualType( aField ) ) |
|
51 { |
|
52 return ETrue; |
|
53 } |
|
54 } |
|
55 return EFalse; |
|
56 } |
|
57 |
|
58 /** |
|
59 * Maps a Versit type to a Contact Model field. |
|
60 */ |
|
61 NONSHARABLE_CLASS(CFieldFactory::TFieldAndTypeTuple) |
|
62 { |
|
63 public: |
|
64 TFieldAndTypeTuple(const MVPbkFieldType& aFieldType, |
|
65 const CContactItemField& aNativeField); |
|
66 public: |
|
67 const MVPbkFieldType& iFieldType; |
|
68 const CContactItemField& iNativeField; |
|
69 }; |
|
70 |
|
71 CFieldFactory::TFieldAndTypeTuple::TFieldAndTypeTuple |
|
72 (const MVPbkFieldType& aFieldType, |
|
73 const CContactItemField& aNativeField) : |
|
74 iFieldType(aFieldType), |
|
75 iNativeField(aNativeField) |
|
76 { |
|
77 } |
|
78 |
|
79 // CFieldFactory implementation |
|
80 CFieldFactory::CFieldFactory() |
|
81 { |
|
82 } |
|
83 |
|
84 inline void CFieldFactory::ConstructL( |
|
85 const CFieldTypeMap& aFieldTypeMap, |
|
86 const CContactItem& aSystemTemplate, |
|
87 const MVPbkFieldTypeList& aMasterFieldTypeList, |
|
88 RFs& aFs ) |
|
89 { |
|
90 // open the golden template extension resource file |
|
91 // for filtering some fields that are not allowed to create. |
|
92 VPbkEngUtils::RLocalizedResourceFile resFile; |
|
93 resFile.OpenLC(aFs, KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, |
|
94 KCntExtResFile ); |
|
95 |
|
96 // Create fields infos that are not allowed to create from the factory |
|
97 TResourceReader reader; |
|
98 reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_NON_CREATABLE_FIELD_DEFNS )); |
|
99 CFieldsInfo* fieldsInfo = CFieldsInfo::NewL( reader ); |
|
100 CleanupStack::PopAndDestroy(); // reader buffer |
|
101 CleanupStack::PushL( fieldsInfo ); |
|
102 |
|
103 const CContactItemFieldSet& fieldSet = aSystemTemplate.CardFields(); |
|
104 const TInt fieldCount = fieldSet.Count(); |
|
105 |
|
106 for (TInt i = 0; i < fieldCount; ++i) |
|
107 { |
|
108 const CContactItemField& nativeField = fieldSet[i]; |
|
109 |
|
110 if ( !ContainsField( *fieldsInfo, nativeField ) ) |
|
111 { |
|
112 DoInsertMappingTupleL(aMasterFieldTypeList, |
|
113 aFieldTypeMap, nativeField); |
|
114 } |
|
115 } |
|
116 CleanupStack::PopAndDestroy( fieldsInfo ); |
|
117 iMaxMatchPriority = aMasterFieldTypeList.MaxMatchPriority(); |
|
118 |
|
119 // add field and type mappings that are not in the system template |
|
120 reader.SetBuffer( resFile.AllocReadLC( |
|
121 R_CNTUI_NON_SYSTEM_TEMPLATE_FIELD_DEFNS )); |
|
122 CFieldsInfo* nonSystemTemplatefieldsInfo = CFieldsInfo::NewL( reader ); |
|
123 CleanupStack::PopAndDestroy(2); // reader buffer, resFile |
|
124 CleanupStack::PushL( nonSystemTemplatefieldsInfo ); |
|
125 |
|
126 for (TInt j = 0; j < nonSystemTemplatefieldsInfo->Count() ; ++j ) |
|
127 { |
|
128 const CFieldInfo* fieldInfo = (*nonSystemTemplatefieldsInfo)[j]; |
|
129 CContactItemField* field = fieldInfo->CreateFieldL(); |
|
130 CleanupStack::PushL(field); |
|
131 |
|
132 DoInsertMappingTupleL(aMasterFieldTypeList, |
|
133 aFieldTypeMap, *field); |
|
134 // append field to array of non system template fields |
|
135 iNonSystemTemplateFields.AppendL(field); |
|
136 CleanupStack::Pop(field); |
|
137 } |
|
138 CleanupStack::PopAndDestroy( nonSystemTemplatefieldsInfo ); |
|
139 } |
|
140 |
|
141 CFieldFactory* CFieldFactory::NewL( |
|
142 const CFieldTypeMap& aFieldTypeMap, |
|
143 CContactItem* aSystemTemplate, |
|
144 const MVPbkFieldTypeList& aMasterFieldTypeList, |
|
145 RFs& aFs ) |
|
146 { |
|
147 CFieldFactory* self = new(ELeave) CFieldFactory; |
|
148 CleanupStack::PushL(self); |
|
149 self->ConstructL(aFieldTypeMap, *aSystemTemplate, aMasterFieldTypeList, |
|
150 aFs ); |
|
151 CleanupStack::Pop(self); |
|
152 // Take ownership after all initialisation that can leave is done |
|
153 self->iSystemTemplate = aSystemTemplate; |
|
154 return self; |
|
155 } |
|
156 |
|
157 CFieldFactory::~CFieldFactory() |
|
158 { |
|
159 iFieldAndTypeMapping.Close(); |
|
160 iNonSystemTemplateFields.ResetAndDestroy(); |
|
161 delete iSystemTemplate; |
|
162 } |
|
163 |
|
164 CContactItemField* CFieldFactory::CreateFieldLC |
|
165 (const MVPbkFieldType& aFieldType) const |
|
166 { |
|
167 CContactItemField* result = NULL; |
|
168 const CContactItemField* field = FindField(aFieldType); |
|
169 if (field) |
|
170 { |
|
171 result = CContactItemField::NewLC(*field); |
|
172 } |
|
173 return result; |
|
174 } |
|
175 |
|
176 const CContactItemField* CFieldFactory::FindField(const MVPbkFieldType& aFieldType) const |
|
177 { |
|
178 const CContactItemField* contactItemField = NULL; |
|
179 |
|
180 const TInt count = iFieldAndTypeMapping.Count(); |
|
181 for (TInt i = 0; i < count; ++i) |
|
182 { |
|
183 if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType)) |
|
184 { |
|
185 contactItemField = &iFieldAndTypeMapping[i].iNativeField; |
|
186 break; |
|
187 } |
|
188 } |
|
189 |
|
190 return contactItemField; |
|
191 } |
|
192 |
|
193 TInt CFieldFactory::FieldTypeCount() const |
|
194 { |
|
195 return iFieldAndTypeMapping.Count(); |
|
196 } |
|
197 |
|
198 const MVPbkFieldType& CFieldFactory::FieldTypeAt(TInt aIndex) const |
|
199 { |
|
200 return iFieldAndTypeMapping[aIndex].iFieldType; |
|
201 } |
|
202 |
|
203 TBool CFieldFactory::ContainsSame(const MVPbkFieldType& aFieldType) const |
|
204 { |
|
205 TBool result = EFalse; |
|
206 const TInt count = iFieldAndTypeMapping.Count(); |
|
207 for (TInt i = 0; i < count; ++i) |
|
208 { |
|
209 if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType)) |
|
210 { |
|
211 result = ETrue; |
|
212 break; |
|
213 } |
|
214 } |
|
215 return result; |
|
216 } |
|
217 |
|
218 TInt CFieldFactory::MaxMatchPriority() const |
|
219 { |
|
220 return iMaxMatchPriority; |
|
221 } |
|
222 |
|
223 const MVPbkFieldType* CFieldFactory::FindMatch( |
|
224 const TVPbkFieldVersitProperty& aMatchProperty, |
|
225 TInt aMatchPriority) const |
|
226 { |
|
227 const MVPbkFieldType* result = NULL; |
|
228 |
|
229 const TInt count = iFieldAndTypeMapping.Count(); |
|
230 for (TInt i = 0; i < count; ++i) |
|
231 { |
|
232 if (iFieldAndTypeMapping[i].iFieldType.Matches(aMatchProperty, aMatchPriority)) |
|
233 { |
|
234 result = &iFieldAndTypeMapping[i].iFieldType; |
|
235 break; |
|
236 } |
|
237 } |
|
238 return result; |
|
239 } |
|
240 |
|
241 const MVPbkFieldType* CFieldFactory::FindMatch |
|
242 (TVPbkNonVersitFieldType aNonVersitType) const |
|
243 { |
|
244 const MVPbkFieldType* result = NULL; |
|
245 |
|
246 const TInt count = iFieldAndTypeMapping.Count(); |
|
247 for (TInt i = 0; i < count; ++i) |
|
248 { |
|
249 if (iFieldAndTypeMapping[i].iFieldType.NonVersitType() == aNonVersitType) |
|
250 { |
|
251 result = &iFieldAndTypeMapping[i].iFieldType; |
|
252 } |
|
253 } |
|
254 return result; |
|
255 } |
|
256 |
|
257 const MVPbkFieldType* CFieldFactory::Find( |
|
258 TInt aFieldTypeResId) const |
|
259 { |
|
260 const MVPbkFieldType* result = NULL; |
|
261 |
|
262 const TInt count = iFieldAndTypeMapping.Count(); |
|
263 for (TInt i = 0; i < count; ++i) |
|
264 { |
|
265 if (iFieldAndTypeMapping[i].iFieldType.FieldTypeResId() == aFieldTypeResId) |
|
266 { |
|
267 result = &iFieldAndTypeMapping[i].iFieldType; |
|
268 break; |
|
269 } |
|
270 } |
|
271 return result; |
|
272 } |
|
273 |
|
274 void CFieldFactory::InsertInMasterFieldTypeOrderL( TFieldAndTypeTuple& aMapping, |
|
275 const MVPbkFieldTypeList& aMasterFieldTypeList ) |
|
276 { |
|
277 // Insert field type mapping in the order defined in master field type |
|
278 // list. |
|
279 TInt newTypeIndex = IndexOfTypeInMasterList( aMapping.iFieldType, |
|
280 aMasterFieldTypeList ); |
|
281 const TInt count = iFieldAndTypeMapping.Count(); |
|
282 TBool mappingInserted = EFalse; |
|
283 for ( TInt i = 0; i < count && !mappingInserted; ++i ) |
|
284 { |
|
285 TInt curTypeIndex = IndexOfTypeInMasterList |
|
286 ( iFieldAndTypeMapping[i].iFieldType, aMasterFieldTypeList ); |
|
287 if ( newTypeIndex < curTypeIndex ) |
|
288 { |
|
289 iFieldAndTypeMapping.InsertL( aMapping, i ); |
|
290 mappingInserted = ETrue; |
|
291 } |
|
292 } |
|
293 |
|
294 if ( !mappingInserted ) |
|
295 { |
|
296 iFieldAndTypeMapping.AppendL( aMapping ); |
|
297 } |
|
298 } |
|
299 |
|
300 TInt CFieldFactory::IndexOfTypeInMasterList( const MVPbkFieldType& aType, |
|
301 const MVPbkFieldTypeList& aMasterFieldTypeList ) |
|
302 { |
|
303 const TInt count = aMasterFieldTypeList.FieldTypeCount(); |
|
304 TInt result = KErrNotFound; |
|
305 for ( TInt i = 0; i < count && ( result == KErrNotFound ); ++i ) |
|
306 { |
|
307 if ( aMasterFieldTypeList.FieldTypeAt( i ).IsSame( aType ) ) |
|
308 { |
|
309 result = i; |
|
310 } |
|
311 } |
|
312 return result; |
|
313 } |
|
314 |
|
315 void CFieldFactory::DoInsertMappingTupleL( |
|
316 const MVPbkFieldTypeList& aMasterFieldTypeList, |
|
317 const CFieldTypeMap& aFieldTypeMap, |
|
318 const CContactItemField& aField) |
|
319 { |
|
320 const TInt maxMatchPriority = aMasterFieldTypeList.MaxMatchPriority(); |
|
321 for (TInt matchPriority = 0; matchPriority <= maxMatchPriority; |
|
322 ++matchPriority) |
|
323 { |
|
324 // retrieves the VPbk field type for this contact model field |
|
325 const MVPbkFieldType* genericType = aFieldTypeMap.GenericFieldType( |
|
326 aField, matchPriority); |
|
327 if (genericType) |
|
328 { |
|
329 // Field mappings must be in the correct order because this |
|
330 // class is also the supported field types of the store. |
|
331 // Field types are inserted into same order as in the master |
|
332 // field type list. This way FindMatch works correctly. |
|
333 TFieldAndTypeTuple fieldAndTypeTuple(*genericType, aField); |
|
334 InsertInMasterFieldTypeOrderL( fieldAndTypeTuple, |
|
335 aMasterFieldTypeList ); |
|
336 break; |
|
337 } |
|
338 } |
|
339 } |
|
340 |
|
341 } // namespace VPbkCntModel |
|
342 |
|
343 // end of file |