|
1 /* |
|
2 * Copyright (c) 2002 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: |
|
15 * Phonebook contact Sort order manager. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "CPbkSortOrderManager.h" |
|
22 #include <featmgr.h> |
|
23 #include <bldvariant.hrh> |
|
24 #include <CPbkContactEngine.h> |
|
25 #include <StringLoader.h> |
|
26 #include <PbkEng.rsg> |
|
27 #include <barsread.h> // TResourceReader |
|
28 #include <PbkGlobalSettingFactory.h> |
|
29 #include <MPbkGlobalSetting.h> |
|
30 #include "PbkUID.h" |
|
31 #include <PbkEngUtils.h> |
|
32 #include "PbkEng.hrh" |
|
33 /// Unnamed namespace for local definitions |
|
34 namespace { |
|
35 |
|
36 // CONSTANTS |
|
37 |
|
38 // Name order setting value for First Name Last Name |
|
39 // This value comes from phonebook specification (see |
|
40 // qtn_phob_name_order) and it's opposite compared to |
|
41 // TPbkNameOrder that is used in CenRep. |
|
42 _LIT(KPbkFirstLastNameEnabled, "0"); |
|
43 // Value when name separator is used |
|
44 _LIT(KPbkNameSeparatorUsed, "1"); |
|
45 // Dec value for space character |
|
46 const TInt KPbkSpaceDecValue = 32; |
|
47 |
|
48 // Separator string length is set to 4. |
|
49 // Separator should be only one character long, |
|
50 // but sometimes localized string or cenrep initial value |
|
51 // may contain additional space characters at the end of string. |
|
52 const TInt KPbkSeparatorMaxLength = 4; |
|
53 |
|
54 #ifdef _DEBUG |
|
55 // CONSTANTS |
|
56 enum TPanicCode |
|
57 { |
|
58 EPanicPreCond_SetNameDisplayOrderL = 1 |
|
59 }; |
|
60 |
|
61 // LOCAL FUNCTIONS |
|
62 void Panic(TPanicCode aReason) |
|
63 { |
|
64 _LIT(KPanicText, "CPbkSortOrderManager"); |
|
65 User::Panic(KPanicText, aReason); |
|
66 } |
|
67 #endif // _DEBUG |
|
68 |
|
69 // Conversion function is used because old functions |
|
70 // SetNameSeparatorL() and NameSeparator() are supported. |
|
71 // In old format 0 means that space character is used and in |
|
72 // new format 23 stands for space character |
|
73 inline TChar ConvertSeparatorCharacterToOld(TChar aFrom) |
|
74 { |
|
75 // Convert space value to 0 value. |
|
76 return (TUint(aFrom)==KPbkSpaceDecValue)? TChar(0) : aFrom; |
|
77 } |
|
78 |
|
79 inline TChar ConvertSeparatorCharacterToNew(TChar aFrom) |
|
80 { |
|
81 // Convert 0 value to space value. |
|
82 return TUint(aFrom)==0? TChar(KPbkSpaceDecValue) : aFrom; |
|
83 } |
|
84 |
|
85 } // namespace |
|
86 |
|
87 // ==================== MEMBER FUNCTIONS ==================== |
|
88 |
|
89 inline CPbkSortOrderManager::CPbkSortOrderManager(RFs& aFs, TBool aSettingsVisible): |
|
90 iFs(aFs), iSettingsVisible(aSettingsVisible) |
|
91 { |
|
92 } |
|
93 |
|
94 inline void CPbkSortOrderManager::ConstructL() |
|
95 { |
|
96 iPersistentSetting = PbkGlobalSettingFactory::CreatePersistentSettingL(); |
|
97 iPersistentSetting->ConnectL(MPbkGlobalSetting::EGeneralSettingCategory); |
|
98 |
|
99 // construct name sort order |
|
100 RContactViewSortOrder sortOrder = |
|
101 DoCreateSortOrderL(PersistentNameDisplayOrderL(), iSettingsVisible); |
|
102 iSortOrder = sortOrder; |
|
103 iNameSeparator = |
|
104 ConvertSeparatorCharacterToOld(PersistentNameSeparatorCharL()); |
|
105 iPersistentSetting->RegisterObserverL(this); |
|
106 } |
|
107 |
|
108 inline void CPbkSortOrderManager::SetPersistentNameDisplayOrderL |
|
109 (CPbkContactEngine::TPbkNameOrder aNameOrder) |
|
110 { |
|
111 __ASSERT_DEBUG( |
|
112 aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName || |
|
113 aNameOrder == CPbkContactEngine::EPbkNameOrderFirstNameLastName, |
|
114 Panic(EPanicPreCond_SetNameDisplayOrderL)); |
|
115 |
|
116 User::LeaveIfError(iPersistentSetting->Set( |
|
117 MPbkGlobalSetting::ENameOrdering, TInt(aNameOrder))); |
|
118 } |
|
119 |
|
120 inline void CPbkSortOrderManager:: |
|
121 SetPersistentNameSeparatorCharL(TChar aNameSeparatorChar) |
|
122 { |
|
123 // 1 character is appended. |
|
124 TBuf<1> string; |
|
125 string.Append(aNameSeparatorChar); |
|
126 User::LeaveIfError(iPersistentSetting->Set( |
|
127 MPbkGlobalSetting::ENameSeparatorChar, string)); |
|
128 } |
|
129 |
|
130 |
|
131 CPbkSortOrderManager* CPbkSortOrderManager::NewL(RFs& aFs, TBool aSettingsVisible) |
|
132 { |
|
133 CPbkSortOrderManager* self = new(ELeave) CPbkSortOrderManager(aFs, aSettingsVisible); |
|
134 CleanupStack::PushL(self); |
|
135 self->ConstructL(); |
|
136 CleanupStack::Pop(self); |
|
137 return self; |
|
138 } |
|
139 |
|
140 CPbkSortOrderManager::~CPbkSortOrderManager() |
|
141 { |
|
142 if (iPersistentSetting) |
|
143 { |
|
144 iPersistentSetting->Close(); |
|
145 delete iPersistentSetting; |
|
146 } |
|
147 iSortOrder.Close(); |
|
148 delete iNameOrderSetting; |
|
149 delete iNameSeparatorUsed; |
|
150 delete iInitialNameSeparatorChar; |
|
151 } |
|
152 |
|
153 const RContactViewSortOrder& CPbkSortOrderManager::SortOrder() const |
|
154 { |
|
155 return iSortOrder; |
|
156 } |
|
157 |
|
158 void CPbkSortOrderManager::SetNameDisplayOrderL |
|
159 (CPbkContactEngine::TPbkNameOrder aNameOrder) |
|
160 { |
|
161 // create new view sort order from aNameOrder |
|
162 RContactViewSortOrder newSortOrder = DoCreateSortOrderL(aNameOrder, |
|
163 iSettingsVisible); |
|
164 CleanupClosePushL(newSortOrder); |
|
165 |
|
166 if (iContactView) |
|
167 { |
|
168 //retrieve the contact view sort order |
|
169 RContactViewSortOrder oldViewSortOrder; |
|
170 CleanupClosePushL(oldViewSortOrder); |
|
171 iContactView->GetSortOrderL(oldViewSortOrder); |
|
172 |
|
173 // try to change the contact view sort order |
|
174 iContactView->ChangeSortOrderL(newSortOrder); |
|
175 // Try to change the persistent key for name ordering |
|
176 TRAPD(err,SetPersistentNameDisplayOrderL(aNameOrder)); |
|
177 if (err) |
|
178 { |
|
179 // error occurred, restore view sort order |
|
180 iContactView->ChangeSortOrderL(oldViewSortOrder); |
|
181 CleanupStack::Pop(); // oldViewSortOrder |
|
182 } |
|
183 else |
|
184 { |
|
185 CleanupStack::PopAndDestroy(); // oldViewSortOrder |
|
186 iSortOrder.Close(); |
|
187 iSortOrder = newSortOrder; |
|
188 CleanupStack::Pop(); // newSortOrder |
|
189 } |
|
190 } |
|
191 else |
|
192 { |
|
193 CleanupStack::PopAndDestroy(); // newSortOrder |
|
194 } |
|
195 } |
|
196 |
|
197 CPbkContactEngine::TPbkNameOrder CPbkSortOrderManager::NameDisplayOrder() const |
|
198 { |
|
199 // return current name display order |
|
200 for (TInt i = 0; i < iSortOrder.Count(); ++i) |
|
201 { |
|
202 if (iSortOrder[i] == KUidContactFieldFamilyName) |
|
203 { |
|
204 return CPbkContactEngine::EPbkNameOrderLastNameFirstName; |
|
205 } |
|
206 else if (iSortOrder[i] == KUidContactFieldGivenName) |
|
207 { |
|
208 return CPbkContactEngine::EPbkNameOrderFirstNameLastName; |
|
209 } |
|
210 } |
|
211 return CPbkContactEngine::EPbkNameOrderLastNameFirstName; |
|
212 } |
|
213 |
|
214 void CPbkSortOrderManager::SetContactView |
|
215 (CContactNamedRemoteView& aContactView) |
|
216 { |
|
217 iContactView = &aContactView; |
|
218 } |
|
219 |
|
220 void CPbkSortOrderManager::SettingChangedL(MPbkGlobalSetting:: |
|
221 TPbkGlobalSetting aKey) |
|
222 { |
|
223 if (aKey == MPbkGlobalSetting::ENameOrdering || |
|
224 aKey == MPbkGlobalSetting::ENameSeparatorChar) |
|
225 { |
|
226 // Update sortorder and name separator char |
|
227 RContactViewSortOrder sortOrder = |
|
228 DoCreateSortOrderL(PersistentNameDisplayOrderL(), |
|
229 iSettingsVisible); |
|
230 iSortOrder.Close(); |
|
231 iSortOrder = sortOrder; |
|
232 |
|
233 iNameSeparator = |
|
234 ConvertSeparatorCharacterToOld(PersistentNameSeparatorCharL()); |
|
235 } |
|
236 } |
|
237 |
|
238 void CPbkSortOrderManager::SetNameSeparatorL(TChar aNameSeparator) |
|
239 { |
|
240 // 0 is converted to space character |
|
241 SetPersistentNameSeparatorCharL( |
|
242 ConvertSeparatorCharacterToNew(aNameSeparator)); |
|
243 iNameSeparator = aNameSeparator; |
|
244 } |
|
245 |
|
246 TChar CPbkSortOrderManager::NameSeparator() const |
|
247 { |
|
248 return iNameSeparator; |
|
249 } |
|
250 |
|
251 RContactViewSortOrder CPbkSortOrderManager::DoCreateSortOrderL |
|
252 (CPbkContactEngine::TPbkNameOrder aNameOrder, |
|
253 TBool aSettingVisible) |
|
254 { |
|
255 RContactViewSortOrder sortOrder; |
|
256 CleanupClosePushL(sortOrder); |
|
257 // engine creation will assign it to the views |
|
258 |
|
259 sortOrder.AppendL(TUid::Uid(KUidContactFieldTopContactValue)); |
|
260 |
|
261 if (FeatureManager::FeatureSupported(KFeatureIdChinese) && |
|
262 !aSettingVisible) |
|
263 { |
|
264 // Chinese sort ordering |
|
265 sortOrder.AppendL(KUidContactFieldFamilyName); |
|
266 sortOrder.AppendL(KUidContactFieldGivenName); |
|
267 sortOrder.AppendL(KUidContactFieldCompanyName); |
|
268 } |
|
269 else if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
270 { |
|
271 // japanese sort ordering |
|
272 if (aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName) |
|
273 { |
|
274 sortOrder.AppendL(KUidContactFieldFamilyNamePronunciation); |
|
275 sortOrder.AppendL(KUidContactFieldGivenNamePronunciation); |
|
276 sortOrder.AppendL(KUidContactFieldFamilyName); |
|
277 sortOrder.AppendL(KUidContactFieldGivenName); |
|
278 } |
|
279 else |
|
280 { |
|
281 sortOrder.AppendL(KUidContactFieldGivenNamePronunciation); |
|
282 sortOrder.AppendL(KUidContactFieldFamilyNamePronunciation); |
|
283 sortOrder.AppendL(KUidContactFieldGivenName); |
|
284 sortOrder.AppendL(KUidContactFieldFamilyName); |
|
285 } |
|
286 sortOrder.AppendL(KUidContactFieldCompanyName); |
|
287 } |
|
288 else |
|
289 { |
|
290 // default sort ordering |
|
291 if (aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName) |
|
292 { |
|
293 sortOrder.AppendL(KUidContactFieldFamilyName); |
|
294 sortOrder.AppendL(KUidContactFieldGivenName); |
|
295 } |
|
296 else |
|
297 { |
|
298 sortOrder.AppendL(KUidContactFieldGivenName); |
|
299 sortOrder.AppendL(KUidContactFieldFamilyName); |
|
300 } |
|
301 sortOrder.AppendL(KUidContactFieldCompanyName); |
|
302 } |
|
303 sortOrder.AppendL(KUidContactFieldTemplateLabel); |
|
304 |
|
305 CleanupStack::Pop(); // sortOrder |
|
306 return sortOrder; |
|
307 } |
|
308 |
|
309 CPbkContactEngine::TPbkNameOrder |
|
310 CPbkSortOrderManager::PersistentNameDisplayOrderL() |
|
311 { |
|
312 TInt nameOrder = KErrNotFound; |
|
313 User::LeaveIfError( |
|
314 iPersistentSetting->Get(MPbkGlobalSetting::ENameOrdering, nameOrder)); |
|
315 CPbkContactEngine::TPbkNameOrder pbkNameOrder = |
|
316 static_cast<CPbkContactEngine::TPbkNameOrder>(nameOrder); |
|
317 |
|
318 // Read phonebook contact name presentation order configuration |
|
319 // if order not defined. |
|
320 if (pbkNameOrder == CPbkContactEngine::EPbkNameOrderNotDefined) |
|
321 { |
|
322 RResourceFile pbkResFile; |
|
323 // Calls CleanupClosePushL for pbkResFile. |
|
324 PbkEngUtils::FindAndOpenDefaultResourceFileLC(iFs, pbkResFile); |
|
325 TResourceReader reader; |
|
326 |
|
327 if(!iNameOrderSetting) |
|
328 { |
|
329 // Value 0 is first name last name and value 1 is last name first name |
|
330 reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_ORDER)); |
|
331 iNameOrderSetting = reader.ReadHBufCL(); |
|
332 CleanupStack::PopAndDestroy(); // R_PBK_NAME_ORDER |
|
333 } |
|
334 |
|
335 if (!iNameOrderSetting->Compare(KPbkFirstLastNameEnabled)) |
|
336 { |
|
337 // Compare return 0 if setting order value in loaded resource is "0" |
|
338 // then first name last name order is used. |
|
339 pbkNameOrder = CPbkContactEngine::EPbkNameOrderFirstNameLastName; |
|
340 } |
|
341 else |
|
342 { |
|
343 pbkNameOrder = CPbkContactEngine::EPbkNameOrderLastNameFirstName; |
|
344 } |
|
345 CleanupStack::PopAndDestroy(1); // pbkResFile |
|
346 } |
|
347 return pbkNameOrder; |
|
348 } |
|
349 |
|
350 TChar CPbkSortOrderManager::PersistentNameSeparatorCharL() |
|
351 { |
|
352 TBuf<KPbkSeparatorMaxLength> string; |
|
353 string.SetLength(0); |
|
354 User::LeaveIfError(iPersistentSetting->Get( |
|
355 MPbkGlobalSetting::ENameSeparatorChar, string)); |
|
356 // NULL string is for undefined |
|
357 if (!string.Length() || string[0] == 0) |
|
358 { |
|
359 RResourceFile pbkResFile; |
|
360 // Calls CleanupClosePushL for pbkResFile. |
|
361 PbkEngUtils::FindAndOpenDefaultResourceFileLC(iFs, pbkResFile); |
|
362 TResourceReader reader; |
|
363 |
|
364 if(!iNameSeparatorUsed) |
|
365 { |
|
366 reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_SEPARATOR_USED)); |
|
367 iNameSeparatorUsed = reader.ReadHBufCL(); |
|
368 CleanupStack::PopAndDestroy(); // R_PBK_NAME_SEPARATOR_USED |
|
369 } |
|
370 if(!iNameSeparatorUsed->Compare(KPbkNameSeparatorUsed)) |
|
371 { |
|
372 // Separator is used, use initial value |
|
373 if(!iInitialNameSeparatorChar) |
|
374 { |
|
375 reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_SEPARATOR_CHAR)); |
|
376 iInitialNameSeparatorChar = reader.ReadHBufCL(); |
|
377 CleanupStack::PopAndDestroy(); // R_PBK_NAME_SEPARATOR_CHAR |
|
378 } |
|
379 string.SetLength(0); |
|
380 string.Append(*iInitialNameSeparatorChar); |
|
381 } |
|
382 else if (string.Length()<KPbkSeparatorMaxLength) |
|
383 { |
|
384 // Space is used if separator character is not defined by default. |
|
385 TChar space(KPbkSpaceDecValue); |
|
386 string.SetLength(0); |
|
387 string.Append(space); |
|
388 } |
|
389 CleanupStack::PopAndDestroy(1); // pbkResFile |
|
390 } |
|
391 |
|
392 return TChar(string[0]); |
|
393 } |
|
394 |
|
395 // End of File |