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: Implementation of the class CPbkxRclContactUpdater. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "emailtrace.h" |
|
20 #include <pbkxrclengine.rsg> |
|
21 #include <CPbkSingleEntryFetchDlg.h> |
|
22 #include <CPbkContactEngine.h> |
|
23 #include <CPbkMemoryEntryAddItemDlg.h> |
|
24 #include <StringLoader.h> |
|
25 #include <CPbkFieldInfo.h> |
|
26 #include <CPbkFieldsInfo.h> |
|
27 #include <aknnotedialog.h> |
|
28 #include <pbkxrclengine.rsg> |
|
29 #include <coemain.h> |
|
30 #include <data_caging_path_literals.hrh> |
|
31 #include <bautils.h> |
|
32 |
|
33 #include "cpbkxrclcontactupdater.h" |
|
34 #include "pbkxrclutils.h" |
|
35 #include "pbkxrclengineconstants.h" |
|
36 #include "pbkxremotecontactlookuppanic.h" |
|
37 |
|
38 // Local constants |
|
39 _LIT(KPbkRomFileDrive, "z:"); |
|
40 _LIT(KPbkViewResourceFile, "PbkView.rsc"); |
|
41 |
|
42 // ======== MEMBER FUNCTIONS ======== |
|
43 |
|
44 // --------------------------------------------------------------------------- |
|
45 // CPbkxRclContactUpdater::NewL |
|
46 // --------------------------------------------------------------------------- |
|
47 // |
|
48 CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewL( |
|
49 CPbkContactEngine& aEngine ) |
|
50 { |
|
51 FUNC_LOG; |
|
52 CPbkxRclContactUpdater* updater = CPbkxRclContactUpdater::NewLC( aEngine ); |
|
53 CleanupStack::Pop( updater ); |
|
54 return updater; |
|
55 } |
|
56 |
|
57 // --------------------------------------------------------------------------- |
|
58 // CPbkxRclContactUpdater::NewLC |
|
59 // --------------------------------------------------------------------------- |
|
60 // |
|
61 CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewLC( |
|
62 CPbkContactEngine& aEngine ) |
|
63 { |
|
64 FUNC_LOG; |
|
65 CPbkxRclContactUpdater* updater = |
|
66 new ( ELeave ) CPbkxRclContactUpdater( aEngine ); |
|
67 CleanupStack::PushL( updater ); |
|
68 updater->ConstructL(); |
|
69 return updater; |
|
70 } |
|
71 |
|
72 // --------------------------------------------------------------------------- |
|
73 // CPbkxRclContactUpdater::CPbkxRclContactUpdater |
|
74 // --------------------------------------------------------------------------- |
|
75 // |
|
76 CPbkxRclContactUpdater::CPbkxRclContactUpdater( CPbkContactEngine& aEngine ) : |
|
77 CBase(), iEngine( aEngine ) |
|
78 { |
|
79 FUNC_LOG; |
|
80 } |
|
81 |
|
82 // --------------------------------------------------------------------------- |
|
83 // CPbkxRclContactUpdater::~CPbkxRclContactUpdater |
|
84 // --------------------------------------------------------------------------- |
|
85 // |
|
86 CPbkxRclContactUpdater::~CPbkxRclContactUpdater() |
|
87 { |
|
88 FUNC_LOG; |
|
89 CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset ); |
|
90 } |
|
91 |
|
92 // --------------------------------------------------------------------------- |
|
93 // CPbkxRclContactUpdater::ConstructL |
|
94 // --------------------------------------------------------------------------- |
|
95 // |
|
96 void CPbkxRclContactUpdater::ConstructL() |
|
97 { |
|
98 FUNC_LOG; |
|
99 |
|
100 // First load Phonebook resource file so that dialog will find resources |
|
101 CCoeEnv* coeEnv = CCoeEnv::Static(); |
|
102 TFileName resourceFile; |
|
103 resourceFile.Copy( KPbkRomFileDrive ); |
|
104 resourceFile.Append( KDC_RESOURCE_FILES_DIR ); |
|
105 resourceFile.Append( KPbkViewResourceFile ); |
|
106 |
|
107 BaflUtils::NearestLanguageFile( coeEnv->FsSession(), resourceFile ); |
|
108 |
|
109 TRAPD( status, |
|
110 iResourceFileOffset = coeEnv->AddResourceFileL( resourceFile ) ); |
|
111 |
|
112 if( status != KErrNone ) |
|
113 { |
|
114 PbkxRclPanic( EPbkxRclPanicGeneral ); |
|
115 } |
|
116 else |
|
117 { |
|
118 } |
|
119 } |
|
120 |
|
121 // --------------------------------------------------------------------------- |
|
122 // CPbkxRclContactUpdater::UpdateContactL |
|
123 // --------------------------------------------------------------------------- |
|
124 // |
|
125 HBufC* CPbkxRclContactUpdater::UpdateContactL( TPbkContactItemField& aField ) |
|
126 { |
|
127 FUNC_LOG; |
|
128 |
|
129 // first ask user to select the contact in which the field is added |
|
130 CPbkSingleEntryFetchDlg::TParams params; |
|
131 params.iContactView = &iEngine.AllContactsView(); |
|
132 |
|
133 CPbkSingleEntryFetchDlg* fetchDlg = CPbkSingleEntryFetchDlg::NewL( params ); |
|
134 fetchDlg->ResetWhenDestroyed( &fetchDlg ); |
|
135 TInt res = 0; |
|
136 res = fetchDlg->ExecuteLD(); |
|
137 |
|
138 CPbkContactItem* contactItem = NULL; |
|
139 HBufC* text = NULL; |
|
140 if ( res != 0 && params.iSelectedEntry != KNullContactId ) |
|
141 { |
|
142 contactItem = iEngine.OpenContactL( params.iSelectedEntry ); |
|
143 CleanupStack::PushL( contactItem ); |
|
144 |
|
145 CPbkFieldInfo& fieldInfo = aField.FieldInfo(); |
|
146 TPbkContactItemField* field = NULL; |
|
147 if ( fieldInfo.Multiplicity() == EPbkFieldMultiplicityOne ) |
|
148 { |
|
149 // there can be only one field of this type. query user to select |
|
150 // a field in which data is to be saved |
|
151 field = SelectUpdatedFieldL( *contactItem, fieldInfo ); |
|
152 } |
|
153 else |
|
154 { |
|
155 // add new field to contact |
|
156 field = &( contactItem->AddFieldL( aField.FieldInfo() ) ); |
|
157 } |
|
158 |
|
159 if ( field != NULL ) |
|
160 { |
|
161 if ( field->StorageType() == KStorageTypeText ) |
|
162 { |
|
163 field->TextStorage()->SetTextL( aField.Text() ); |
|
164 } |
|
165 else if ( field->StorageType() == KStorageTypeDateTime ) |
|
166 { |
|
167 field->DateTimeStorage()->SetTime( aField.Time() ); |
|
168 } |
|
169 iEngine.CommitContactL( *contactItem ); |
|
170 // build string returned to the caller |
|
171 text = ConstructUpdatedTextL( *contactItem, *field ); |
|
172 } |
|
173 else |
|
174 { |
|
175 iEngine.CloseContactL( contactItem->Id() ); |
|
176 } |
|
177 |
|
178 CleanupStack::PopAndDestroy( contactItem ); |
|
179 } |
|
180 return text; |
|
181 } |
|
182 |
|
183 // --------------------------------------------------------------------------- |
|
184 // CPbkxRclContactUpdater::SelectUpdatedFieldL |
|
185 // --------------------------------------------------------------------------- |
|
186 // |
|
187 TPbkContactItemField* CPbkxRclContactUpdater::SelectUpdatedFieldL( |
|
188 CPbkContactItem& aContactItem, |
|
189 CPbkFieldInfo& aFieldInfo ) |
|
190 { |
|
191 FUNC_LOG; |
|
192 TPbkContactItemField* retField = NULL; |
|
193 TInt fieldCount = 0; |
|
194 CPbkFieldInfo* info = SelectFieldL( aFieldInfo, fieldCount ); |
|
195 while ( info != NULL && retField == NULL ) |
|
196 { |
|
197 retField = aContactItem.AddOrReturnUnusedFieldL( *info ); |
|
198 // iterate until user selects field or cancels |
|
199 if ( retField == NULL ) |
|
200 { |
|
201 // there is already given field. ask user if it is ok to replace |
|
202 // existing data |
|
203 HBufC* dlgText = StringLoader::LoadLC( |
|
204 R_QTN_RCL_REPLACE_EXISTING_DETAIL_NOTE, |
|
205 info->FieldName() ); |
|
206 CAknNoteDialog* dialog = new ( ELeave ) CAknNoteDialog(); |
|
207 dialog->PrepareLC( R_RCL_CONFIRMATION_NOTE_YES_CANCEL ); |
|
208 dialog->SetTextL( *dlgText ); |
|
209 |
|
210 if ( dialog->RunLD() ) |
|
211 { |
|
212 retField = aContactItem.FindField( *info ); |
|
213 } |
|
214 else |
|
215 { |
|
216 // user cancelled dialog |
|
217 if ( fieldCount > 1 ) |
|
218 { |
|
219 // show select field dialog again |
|
220 info = SelectFieldL( aFieldInfo, fieldCount ); |
|
221 } |
|
222 else |
|
223 { |
|
224 // exit the loop because user refused to update existing |
|
225 // field and there are no other choices for the fields |
|
226 // to be updated |
|
227 info = NULL; |
|
228 } |
|
229 } |
|
230 CleanupStack::PopAndDestroy( dlgText ); |
|
231 } |
|
232 } |
|
233 return retField; |
|
234 } |
|
235 |
|
236 // --------------------------------------------------------------------------- |
|
237 // CPbkxRclContactUpdater::ConstructUpdatedTextL |
|
238 // --------------------------------------------------------------------------- |
|
239 // |
|
240 HBufC* CPbkxRclContactUpdater::ConstructUpdatedTextL( |
|
241 CPbkContactItem& aContactItem, |
|
242 TPbkContactItemField& aField ) |
|
243 { |
|
244 FUNC_LOG; |
|
245 |
|
246 HBufC* firstName = PbkxRclUtils::FieldTextL( |
|
247 &aContactItem, |
|
248 EPbkFieldIdFirstName ); |
|
249 CleanupStack::PushL( firstName ); |
|
250 |
|
251 HBufC* lastName = PbkxRclUtils::FieldTextL( |
|
252 &aContactItem, |
|
253 EPbkFieldIdLastName ); |
|
254 CleanupStack::PushL( lastName ); |
|
255 |
|
256 RBuf name; |
|
257 CleanupClosePushL( name ); |
|
258 // +1 comes for the space in the format |
|
259 name.CreateL( firstName->Length() + lastName->Length() + 1 ); |
|
260 |
|
261 name.Format( KNameFormat, firstName, lastName ); |
|
262 |
|
263 CDesCArrayFlat* textArray = |
|
264 new ( ELeave ) CDesCArrayFlat( KArrayGranularity ); |
|
265 CleanupStack::PushL( textArray ); |
|
266 textArray->AppendL( aField.FieldInfo().FieldName() ); |
|
267 textArray->AppendL( name ); |
|
268 |
|
269 HBufC* text = StringLoader::LoadL( |
|
270 R_QTN_RCL_UPDATE_NOTE, |
|
271 *textArray ); |
|
272 |
|
273 CleanupStack::PopAndDestroy( textArray ); |
|
274 CleanupStack::PopAndDestroy( &name ); |
|
275 CleanupStack::PopAndDestroy( lastName ); |
|
276 CleanupStack::PopAndDestroy( firstName ); |
|
277 |
|
278 return text; |
|
279 } |
|
280 |
|
281 // --------------------------------------------------------------------------- |
|
282 // CPbkxRclContactUpdater::SelectFieldL |
|
283 // --------------------------------------------------------------------------- |
|
284 // |
|
285 CPbkFieldInfo* CPbkxRclContactUpdater::SelectFieldL( |
|
286 CPbkFieldInfo& aFieldInfo, |
|
287 TInt& aFieldCount ) |
|
288 { |
|
289 FUNC_LOG; |
|
290 // construct possible field types |
|
291 const CPbkFieldsInfo& fields = iEngine.FieldsInfo(); |
|
292 CArrayPtrFlat<CPbkFieldInfo>* fieldArray = |
|
293 new ( ELeave ) CArrayPtrFlat<CPbkFieldInfo>( KArrayGranularity ); |
|
294 CleanupStack::PushL( fieldArray ); |
|
295 |
|
296 TPbkFieldLocation locs[] = { |
|
297 EPbkFieldLocationNone, |
|
298 EPbkFieldLocationHome, |
|
299 EPbkFieldLocationWork }; |
|
300 |
|
301 TInt locCount = sizeof( locs ) / sizeof( TPbkFieldLocation ); |
|
302 |
|
303 for ( TInt i = 0; i < locCount; i++ ) |
|
304 { |
|
305 CPbkFieldInfo* field = fields.Find( aFieldInfo.FieldId(), locs[i] ); |
|
306 if ( field != NULL ) |
|
307 { |
|
308 fieldArray->AppendL( field ); |
|
309 } |
|
310 } |
|
311 |
|
312 aFieldCount = fieldArray->Count(); |
|
313 CPbkFieldInfo* retField = NULL; |
|
314 if ( fieldArray->Count() == 1 ) |
|
315 { |
|
316 retField = ( *fieldArray )[0]; |
|
317 } |
|
318 else |
|
319 { |
|
320 CPbkItemTypeSelectAddToExisting* selectionDlg = |
|
321 new ( ELeave ) CPbkItemTypeSelectAddToExisting(); |
|
322 retField = selectionDlg->ExecuteLD( *fieldArray ); |
|
323 } |
|
324 CleanupStack::PopAndDestroy( fieldArray ); |
|
325 return retField; |
|
326 } |
|
327 |
|