author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Wed, 13 Oct 2010 14:15:33 +0300 | |
branch | RCL_3 |
changeset 85 | 38bb213f60ba |
parent 68 | 9da50d567e3c |
permissions | -rw-r--r-- |
63 | 1 |
/* |
2 |
* Copyright (c) 2005-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: Phonebook 2 address selection. |
|
15 |
* |
|
16 |
*/ |
|
17 |
||
18 |
||
19 |
#include <CPbk2AddressSelect.h> |
|
20 |
||
21 |
// Phonebook 2 |
|
22 |
#include "CPbk2SelectFieldDlg.h" |
|
23 |
#include "MPbk2ControlKeyObserver.h" |
|
24 |
#include <MPbk2ContactNameFormatter.h> |
|
25 |
#include <CPbk2FieldPropertyArray.h> |
|
26 |
#include <TPbk2AddressSelectParams.h> |
|
27 |
#include <MPbk2ApplicationServices.h> |
|
28 |
#include <MPbk2ApplicationServices2.h> |
|
29 |
#include <CPbk2ServiceManager.h> |
|
30 |
#include <MPbk2AppUi.h> |
|
85
38bb213f60ba
Revision: 201039
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
68
diff
changeset
|
31 |
#include <Pbk2UIControls.rsg> |
38bb213f60ba
Revision: 201039
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
68
diff
changeset
|
32 |
#include <Pbk2Commands.rsg> |
63 | 33 |
#include <CPbk2ApplicationServices.h> |
34 |
#include <TPbk2StoreContactAnalyzer.h> |
|
35 |
||
36 |
// Virtual Phonebook |
|
37 |
#include <CVPbkFieldFilter.h> |
|
38 |
#include <MVPbkStoreContactField.h> |
|
39 |
#include <MVPbkStoreContact.h> |
|
40 |
#include <CVPbkFieldTypeSelector.h> |
|
41 |
#include <MVPbkContactFieldData.h> |
|
42 |
#include <MVPbkStoreContactFieldCollection.h> |
|
43 |
#include <CVPbkContactManager.h> |
|
44 |
#include <CVPbkDefaultAttribute.h> |
|
45 |
#include <MVPbkFieldType.h> |
|
46 |
#include <TVPbkFieldVersitProperty.h> |
|
47 |
||
48 |
// System includes |
|
49 |
#include <avkon.hrh> |
|
50 |
#include <aknnotewrappers.h> |
|
51 |
#include <StringLoader.h> |
|
52 |
||
53 |
//SpSettings |
|
54 |
#include <spsettings.h> |
|
55 |
#include <spentry.h> |
|
56 |
#include <spproperty.h> |
|
57 |
#include <spsettingsvoiputils.h> |
|
58 |
||
59 |
/// Unnamed namespace for local definitions |
|
60 |
namespace { |
|
61 |
||
62 |
#ifdef _DEBUG |
|
63 |
enum TPanicCode |
|
64 |
{ |
|
65 |
EPanicPostCond_Constructor = 1, |
|
66 |
EPanicPreCond_ExecuteLD |
|
67 |
}; |
|
68 |
||
69 |
static void Panic(TPanicCode aReason) |
|
70 |
{ |
|
71 |
_LIT(KPanicText, "CPbk2AddressSelect"); |
|
72 |
User::Panic(KPanicText, aReason); |
|
73 |
} |
|
74 |
#endif // _DEBUG |
|
75 |
||
76 |
#define KOneVOIPServiceAvailable 1 |
|
77 |
||
78 |
const TInt KFirstField = 0; |
|
79 |
const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator; |
|
80 |
||
81 |
/** |
|
82 |
* Returns index of given field in store contact field collection. |
|
83 |
* |
|
84 |
* @param aCollection Store contact field collection. |
|
85 |
* @param aField Store contact field to search for. |
|
86 |
* @return Index of the given field. |
|
87 |
*/ |
|
88 |
inline TInt IndexOfField( |
|
89 |
const MVPbkStoreContactFieldCollection& aCollection, |
|
90 |
const MVPbkStoreContactField& aField ) |
|
91 |
{ |
|
92 |
TInt ret = KErrNotFound; |
|
93 |
const TInt count = aCollection.FieldCount(); |
|
94 |
||
95 |
for ( TInt i = 0; i < count; ++i ) |
|
96 |
{ |
|
97 |
MVPbkStoreContactField* field = aCollection.FieldAtLC( i ); |
|
98 |
if ( aField.IsSame( *field ) ) |
|
99 |
{ |
|
100 |
ret = i; |
|
101 |
CleanupStack::PopAndDestroy(); // field |
|
102 |
break; |
|
103 |
} |
|
104 |
CleanupStack::PopAndDestroy(); // field |
|
105 |
} |
|
106 |
||
107 |
return ret; |
|
108 |
} |
|
109 |
||
110 |
} /// namespace |
|
111 |
||
112 |
// MODULE DATA STRUCTURES |
|
113 |
||
114 |
/** |
|
115 |
* Special field selection dialog class for CPbk2AddressSelect. |
|
116 |
* The main purpose of this class is to |
|
117 |
* get #include of MPbk2ControlKeyObserver |
|
118 |
* away from public header CPbk2AddressSelect.h. |
|
119 |
*/ |
|
120 |
NONSHARABLE_CLASS(CPbk2AddressSelect::CSelectFieldDlg) : |
|
121 |
public CPbk2SelectFieldDlg, |
|
122 |
private MPbk2ControlKeyObserver |
|
123 |
{ |
|
124 |
public: // Construction |
|
125 |
||
126 |
/** |
|
127 |
* Constructor. |
|
128 |
* |
|
129 |
* @param aParent Parent. |
|
130 |
*/ |
|
131 |
CSelectFieldDlg( CPbk2AddressSelect& aParent ) : |
|
132 |
iParent( aParent ) |
|
133 |
{ |
|
134 |
SetObserver( this ); |
|
135 |
} |
|
136 |
||
137 |
private: // From MPbk2ControlKeyObserver |
|
138 |
TKeyResponse Pbk2ControlKeyEventL |
|
139 |
( const TKeyEvent& aKeyEvent, TEventCode aType ); |
|
140 |
||
141 |
private: // Data |
|
142 |
/// Ref: Parent |
|
143 |
CPbk2AddressSelect& iParent; |
|
144 |
}; |
|
145 |
||
146 |
||
147 |
// -------------------------------------------------------------------------- |
|
148 |
// CPbk2AddressSelect::CSelectFieldDlg::Pbk2ControlKeyEventL |
|
149 |
// -------------------------------------------------------------------------- |
|
150 |
// |
|
151 |
TKeyResponse CPbk2AddressSelect::CSelectFieldDlg::Pbk2ControlKeyEventL |
|
152 |
( const TKeyEvent& aKeyEvent, TEventCode aType ) |
|
153 |
{ |
|
154 |
// Forward call to virtual function in CPbk2AddressSelect interface |
|
155 |
return iParent.Pbk2ControlKeyEventL( aKeyEvent,aType ); |
|
156 |
} |
|
157 |
||
158 |
// -------------------------------------------------------------------------- |
|
159 |
// CPbk2AddressSelect::CPbk2AddressSelect |
|
160 |
// -------------------------------------------------------------------------- |
|
161 |
// |
|
162 |
CPbk2AddressSelect::CPbk2AddressSelect( |
|
163 |
TPbk2AddressSelectParams& aParams, |
|
164 |
const TArray<MVPbkStoreContact*>* aStoreContactsArray, |
|
165 |
const TArray<CPbk2PresenceIconInfo*>* aPresenceIconsArray ): |
|
166 |
iParams( aParams ), |
|
167 |
iStoreContactsArray( aStoreContactsArray ), |
|
168 |
iPresenceIconsArray( aPresenceIconsArray ) |
|
169 |
{ |
|
170 |
__ASSERT_DEBUG |
|
171 |
( !iFieldDlg && !iDestroyedPtr, |
|
172 |
Panic( EPanicPostCond_Constructor ) ); |
|
173 |
} |
|
174 |
||
175 |
// -------------------------------------------------------------------------- |
|
176 |
// CPbk2AddressSelect::~CPbk2AddressSelect |
|
177 |
// -------------------------------------------------------------------------- |
|
178 |
// |
|
179 |
EXPORT_C CPbk2AddressSelect::~CPbk2AddressSelect() |
|
180 |
{ |
|
181 |
// Tell ExecuteLD this object is already destroyed |
|
182 |
if (iDestroyedPtr) |
|
183 |
{ |
|
184 |
*iDestroyedPtr = ETrue; |
|
185 |
} |
|
186 |
||
187 |
// Set eliminator pointer to NULL |
|
188 |
if ( iSelfPtr ) |
|
189 |
{ |
|
190 |
*iSelfPtr = NULL; |
|
191 |
} |
|
192 |
||
193 |
delete iFieldDlg; |
|
194 |
delete iFieldFilter; |
|
195 |
delete iFieldTypeSelector; |
|
196 |
iFieldFilterArray.ResetAndDestroy(); |
|
197 |
} |
|
198 |
||
199 |
// -------------------------------------------------------------------------- |
|
200 |
// CPbk2AddressSelect::NewL |
|
201 |
// -------------------------------------------------------------------------- |
|
202 |
// |
|
203 |
EXPORT_C CPbk2AddressSelect* CPbk2AddressSelect::NewL |
|
204 |
( TPbk2AddressSelectParams& aParams ) |
|
205 |
{ |
|
206 |
CPbk2AddressSelect* self = new ( ELeave ) CPbk2AddressSelect( |
|
207 |
aParams, NULL, NULL ); |
|
208 |
CleanupStack::PushL( self ); |
|
209 |
self->ConstructL( NULL ); |
|
210 |
CleanupStack::Pop( self ); |
|
211 |
return self; |
|
212 |
} |
|
213 |
||
214 |
// -------------------------------------------------------------------------- |
|
215 |
// CPbk2AddressSelect::NewL |
|
216 |
// -------------------------------------------------------------------------- |
|
217 |
// |
|
218 |
EXPORT_C CPbk2AddressSelect* CPbk2AddressSelect::NewL |
|
219 |
( TPbk2AddressSelectParams& aParams, |
|
220 |
CVPbkFieldTypeSelector& aFieldTypeSelector, |
|
221 |
const TArray<MVPbkStoreContact*>* aStoreContactsArray, |
|
222 |
const TArray<CPbk2PresenceIconInfo*>* aPresenceIconsArray ) |
|
223 |
{ |
|
224 |
CPbk2AddressSelect* self = new ( ELeave ) CPbk2AddressSelect( aParams, |
|
225 |
aStoreContactsArray, aPresenceIconsArray ); |
|
226 |
CleanupStack::PushL( self ); |
|
227 |
self->ConstructL( &aFieldTypeSelector ); |
|
228 |
CleanupStack::Pop( self ); |
|
229 |
return self; |
|
230 |
} |
|
231 |
||
232 |
// -------------------------------------------------------------------------- |
|
233 |
// CPbk2AddressSelect::ConstructL |
|
234 |
// -------------------------------------------------------------------------- |
|
235 |
// |
|
236 |
void CPbk2AddressSelect::ConstructL( |
|
237 |
CVPbkFieldTypeSelector* aFieldTypeSelector ) |
|
238 |
{ |
|
239 |
// Read the resource referenced in address select resource struct |
|
240 |
const TInt fieldTypeSelectorRes = iParams.iResReader.ReadInt32(); |
|
241 |
TResourceReader selectorReader; |
|
242 |
CCoeEnv::Static()->CreateResourceReaderLC |
|
243 |
( selectorReader, fieldTypeSelectorRes ); |
|
244 |
if ( aFieldTypeSelector == NULL ) |
|
245 |
{ |
|
246 |
// Give that resource reader to the field type selector |
|
247 |
iFieldTypeSelector = CVPbkFieldTypeSelector::NewL |
|
248 |
( selectorReader, iParams.iContactManager.FieldTypes() ); |
|
249 |
} |
|
250 |
else |
|
251 |
{ |
|
252 |
iFieldTypeSelector = CVPbkFieldTypeSelector::NewL( |
|
253 |
*aFieldTypeSelector ); |
|
254 |
} |
|
255 |
CleanupStack::PopAndDestroy(); // selectorReader |
|
256 |
||
257 |
iNoAddressesForNamePromptResource = iParams.iResReader.ReadInt32(); |
|
258 |
iNoAddressesPromptResource = iParams.iResReader.ReadInt32(); |
|
259 |
iSoftKeyResource = iParams.iResReader.ReadInt32(); |
|
260 |
||
261 |
const CVPbkFieldFilter::TConfig config |
|
262 |
( const_cast<MVPbkStoreContactFieldCollection&> |
|
263 |
( iParams.iContact.Fields() ), |
|
264 |
iFieldTypeSelector, NULL ); |
|
265 |
||
266 |
iFieldFilter = CVPbkFieldFilter::NewL( config ); |
|
267 |
||
268 |
if ( iStoreContactsArray != NULL && iStoreContactsArray->Count() != 0 ) |
|
269 |
{ |
|
270 |
TInt count = iStoreContactsArray->Count(); |
|
271 |
for ( TInt i = 0; i < count; i++ ) |
|
272 |
{ |
|
273 |
const CVPbkFieldFilter::TConfig conf |
|
274 |
( const_cast<MVPbkStoreContactFieldCollection&> |
|
275 |
( iStoreContactsArray->operator[](i)->Fields() ), |
|
276 |
iFieldTypeSelector, NULL ); |
|
277 |
CVPbkFieldFilter* fieldFilter = CVPbkFieldFilter::NewL( conf ); |
|
278 |
CleanupStack::PushL( fieldFilter ); |
|
279 |
iFieldFilterArray.AppendL( fieldFilter ); |
|
280 |
CleanupStack::Pop(); //fieldfilter |
|
281 |
} |
|
282 |
} |
|
283 |
||
284 |
CPbk2ApplicationServices* appServices = |
|
285 |
CPbk2ApplicationServices::InstanceLC(); |
|
286 |
iAttributeManager = |
|
287 |
&appServices->ContactManager().ContactAttributeManagerL(); |
|
288 |
CleanupStack::PopAndDestroy(); // appServices |
|
289 |
} |
|
290 |
||
291 |
// -------------------------------------------------------------------------- |
|
292 |
// CPbk2AddressSelect::ExecuteLD |
|
293 |
// -------------------------------------------------------------------------- |
|
294 |
// |
|
295 |
EXPORT_C MVPbkStoreContactField* CPbk2AddressSelect::ExecuteLD() |
|
296 |
{ |
|
297 |
__ASSERT_DEBUG( !iFieldDlg, Panic( EPanicPreCond_ExecuteLD ) ); |
|
298 |
||
299 |
// "D" function semantics |
|
300 |
CleanupStack::PushL( this ); |
|
301 |
TBool thisDestroyed = EFalse; |
|
302 |
// Ensure that thisDestroyed will be ETrue if this object is destroyed. |
|
303 |
// See in destructor how this is done. |
|
304 |
iDestroyedPtr = &thisDestroyed; |
|
305 |
||
306 |
SelectFieldL(); |
|
307 |
||
308 |
MVPbkStoreContactField* returnedField = NULL; |
|
309 |
if ( iSelectedField ) |
|
310 |
{ |
|
311 |
// We cannot return iSelectedField directly since if its NULL, |
|
312 |
// it's value changes to 0xdedede before it is returned. |
|
313 |
// Therefore we must test iSelectedField before assigning it |
|
314 |
// to returnedField. |
|
315 |
returnedField = iSelectedField; |
|
316 |
} |
|
317 |
||
318 |
if ( thisDestroyed ) |
|
319 |
{ |
|
320 |
// This object has already been destroyed |
|
321 |
CleanupStack::Pop( this ); |
|
322 |
returnedField = NULL; |
|
323 |
} |
|
324 |
else |
|
325 |
{ |
|
326 |
CleanupStack::PopAndDestroy( this ); |
|
327 |
} |
|
328 |
||
329 |
return returnedField; |
|
330 |
} |
|
331 |
||
332 |
// -------------------------------------------------------------------------- |
|
333 |
// CPbk2AddressSelect::AttemptExitL |
|
334 |
// -------------------------------------------------------------------------- |
|
335 |
// |
|
336 |
EXPORT_C void CPbk2AddressSelect::AttemptExitL( TBool aAccept ) |
|
337 |
{ |
|
338 |
if ( iFieldDlg ) |
|
339 |
{ |
|
340 |
iFieldDlg->AttemptExitL( aAccept ); |
|
341 |
} |
|
342 |
} |
|
343 |
||
344 |
// -------------------------------------------------------------------------- |
|
345 |
// CPbk2AddressSelect::Pbk2ControlKeyEventL |
|
346 |
// -------------------------------------------------------------------------- |
|
347 |
// |
|
348 |
EXPORT_C TKeyResponse CPbk2AddressSelect::Pbk2ControlKeyEventL |
|
349 |
( const TKeyEvent& aKeyEvent, TEventCode aType ) |
|
350 |
{ |
|
351 |
TKeyResponse ret = EKeyWasNotConsumed; |
|
352 |
||
353 |
if ( aType == EEventKey && aKeyEvent.iCode == EKeyPhoneSend ) |
|
354 |
{ |
|
355 |
// Event is Send key, tell field selection dialog to accept |
|
356 |
// current selection |
|
357 |
AttemptExitL( ETrue ); |
|
358 |
ret = EKeyWasConsumed; |
|
359 |
} |
|
360 |
||
361 |
return ret; |
|
362 |
} |
|
363 |
||
364 |
// -------------------------------------------------------------------------- |
|
365 |
// CPbk2AddressSelect::SetCba |
|
366 |
// -------------------------------------------------------------------------- |
|
367 |
// |
|
368 |
EXPORT_C void CPbk2AddressSelect::SetCba( TInt aCbaResourceId ) |
|
369 |
{ |
|
370 |
iSoftKeyResource = aCbaResourceId; |
|
371 |
} |
|
372 |
||
373 |
// -------------------------------------------------------------------------- |
|
374 |
// CPbk2AddressSelect::RequestExitL |
|
375 |
// -------------------------------------------------------------------------- |
|
376 |
// |
|
377 |
void CPbk2AddressSelect::RequestExitL( TInt aCommandId ) |
|
378 |
{ |
|
379 |
if ( aCommandId == EEikBidCancel ) |
|
380 |
{ |
|
381 |
AttemptExitL( EFalse ); |
|
382 |
} |
|
383 |
else if ( aCommandId == EEikBidOk ) |
|
384 |
{ |
|
385 |
AttemptExitL( ETrue ); |
|
386 |
} |
|
387 |
} |
|
388 |
||
389 |
// -------------------------------------------------------------------------- |
|
390 |
// CPbk2AddressSelect::ForceExit |
|
391 |
// -------------------------------------------------------------------------- |
|
392 |
// |
|
393 |
void CPbk2AddressSelect::ForceExit() |
|
394 |
{ |
|
395 |
TRAPD( err, AttemptExitL( EFalse ) ); |
|
396 |
if ( err != KErrNone ) |
|
397 |
{ |
|
398 |
// If not nicely then use the force |
|
399 |
delete this; |
|
400 |
} |
|
401 |
} |
|
402 |
||
403 |
// -------------------------------------------------------------------------- |
|
404 |
// CPbk2AddressSelect::ResetWhenDestroyed |
|
405 |
// -------------------------------------------------------------------------- |
|
406 |
// |
|
407 |
void CPbk2AddressSelect::ResetWhenDestroyed( |
|
408 |
MPbk2DialogEliminator** aSelfPtr ) |
|
409 |
{ |
|
410 |
iSelfPtr = aSelfPtr; |
|
411 |
} |
|
412 |
||
413 |
// -------------------------------------------------------------------------- |
|
414 |
// CPbk2AddressSelect::AddressField |
|
415 |
// Returns true if aField is an applicable address field. |
|
416 |
// -------------------------------------------------------------------------- |
|
417 |
// |
|
418 |
TBool CPbk2AddressSelect::AddressField |
|
419 |
( const MVPbkStoreContactField& aField ) const |
|
420 |
{ |
|
421 |
TBool ret = EFalse; |
|
422 |
||
423 |
// Return true if field belongs to the selector |
|
424 |
ret = ( iFieldFilter->FindField( aField ) == |
|
425 |
KErrNotFound ) ? EFalse : ETrue; |
|
426 |
||
427 |
return ret; |
|
428 |
} |
|
429 |
||
430 |
// -------------------------------------------------------------------------- |
|
431 |
// CPbk2AddressSelect::NoAddressesL |
|
432 |
// Called if there are no applicable address fields in a contact passed |
|
433 |
// to ExecuteLD. |
|
434 |
// -------------------------------------------------------------------------- |
|
435 |
// |
|
436 |
void CPbk2AddressSelect::NoAddressesL |
|
437 |
( TPbk2AddressSelectParams aParams ) const |
|
438 |
{ |
|
439 |
if ( !aParams.iSuppressWarnings ) |
|
440 |
{ |
|
441 |
HBufC* prompt = NULL; |
|
442 |
HBufC* name = aParams.iNameFormatter.GetContactTitleOrNullL |
|
443 |
( iParams.iContact.Fields(), KDefaultTitleFormat ); |
|
444 |
||
445 |
if ( name ) |
|
446 |
{ |
|
447 |
CleanupStack::PushL(name); |
|
448 |
prompt = StringLoader::LoadL |
|
449 |
( iNoAddressesForNamePromptResource, *name ); |
|
450 |
CleanupStack::PopAndDestroy(); // name |
|
451 |
} |
|
452 |
else |
|
453 |
{ |
|
454 |
prompt = StringLoader::LoadL( iNoAddressesPromptResource ); |
|
455 |
} |
|
456 |
||
457 |
if ( prompt ) |
|
458 |
{ |
|
459 |
CleanupStack::PushL( prompt ); |
|
460 |
// This is a waiting dialog because the address select might be |
|
461 |
// used from the application server and the information note will |
|
462 |
// disappear if the application server closes before the |
|
463 |
// note timeout has expired, thus causing blinking |
|
464 |
CAknInformationNote* noteDlg = |
|
465 |
new ( ELeave ) CAknInformationNote( ETrue ); |
|
466 |
noteDlg->ExecuteLD( *prompt ); |
|
467 |
CleanupStack::PopAndDestroy(); // prompt |
|
468 |
} |
|
469 |
} |
|
470 |
} |
|
471 |
||
472 |
// -------------------------------------------------------------------------- |
|
473 |
// CPbk2AddressSelect::SelectFieldL |
|
474 |
// -------------------------------------------------------------------------- |
|
475 |
// |
|
476 |
inline void CPbk2AddressSelect::SelectFieldL() |
|
477 |
{ |
|
478 |
// If currently focused field is an applicable field |
|
479 |
if ( iParams.iFocusedField && AddressField( *iParams.iFocusedField ) ) |
|
480 |
{ |
|
481 |
// Applicable field was focused -> return field |
|
482 |
SetSelectedFieldL( iParams.iFocusedField ); |
|
483 |
} |
|
484 |
else |
|
485 |
{ |
|
486 |
TBool found = EFalse; |
|
487 |
// Focus is in on some other field, first check default field |
|
488 |
if ( iParams.iDefaultPriorities && |
|
489 |
iParams.iUseDefaultDirectly && |
|
490 |
iParams.iDefaultPriorities->Count() > 0 ) |
|
491 |
{ |
|
492 |
found = SelectFromDefaultFieldsL(); |
|
493 |
} |
|
494 |
||
495 |
if ( !found ) |
|
496 |
{ |
|
497 |
// No direct call to focused or default number, we have to |
|
498 |
// select from applicable fields |
|
499 |
SelectFromApplicableFieldsL(); |
|
500 |
} |
|
501 |
} |
|
502 |
} |
|
503 |
||
504 |
// -------------------------------------------------------------------------- |
|
505 |
// CPbk2AddressSelect::SelectFromApplicableFieldsL |
|
506 |
// -------------------------------------------------------------------------- |
|
507 |
// |
|
508 |
inline void CPbk2AddressSelect::SelectFromApplicableFieldsL() |
|
509 |
{ |
|
510 |
TInt indexOfDefault = IndexOfDefaultFieldL(); |
|
511 |
TInt fieldCount = iFieldFilter->FieldCount(); |
|
512 |
||
513 |
// check also addiotnal contacts |
|
514 |
if ( iFieldFilterArray.Count() > 0 ) |
|
515 |
{ |
|
516 |
TInt count = iFieldFilterArray.Count(); |
|
517 |
for ( TInt i = 0; i < count; i++ ) |
|
518 |
{ |
|
519 |
fieldCount += iFieldFilterArray[i]->FieldCount(); |
|
520 |
} |
|
521 |
} |
|
522 |
||
523 |
// Different actions for different number of applicable fields found |
|
524 |
if ( fieldCount == 0 ) |
|
525 |
{ |
|
526 |
// No applicable addresses found |
|
527 |
NoAddressesL( iParams ); |
|
528 |
} |
|
529 |
else if ( fieldCount == 1 && !iParams.iQueryAlways ) |
|
530 |
{ |
|
531 |
// Exactly one applicable address found, just return it |
|
532 |
if ( iFieldFilter->FieldCount() != 0 ) |
|
533 |
{ |
|
534 |
SetSelectedFieldL( &iFieldFilter->FieldAt( KFirstField ) ); |
|
535 |
} |
|
536 |
else |
|
537 |
{ |
|
538 |
SetSelectedFieldL( &iFieldFilterArray[0]->FieldAt( KFirstField ) ); |
|
539 |
} |
|
540 |
} |
|
541 |
else if (fieldCount > 1 || iParams.iQueryAlways ) |
|
542 |
{ |
|
543 |
HBufC* title = LoadDialogTitleL(); |
|
544 |
||
545 |
// Run the address selection dialog |
|
546 |
CleanupStack::PushL( title ); |
|
547 |
iFieldDlg = new ( ELeave ) CSelectFieldDlg( *this ); |
|
548 |
iFieldDlg->ResetWhenDestroyed( &iFieldDlg ); |
|
549 |
const MVPbkStoreContactField* field = NULL; |
|
550 |
field = iFieldDlg->ExecuteLCD |
|
551 |
( *iFieldFilter, |
|
552 |
iFieldFilterArray, |
|
553 |
iPresenceIconsArray, |
|
554 |
iParams.iContactManager, |
|
555 |
iParams.iFieldPropertyArray, |
|
556 |
iSoftKeyResource, |
|
557 |
iParams.iCommMethod, |
|
558 |
*title, |
|
559 |
indexOfDefault ); |
|
560 |
||
561 |
SetSelectedFieldL( field ); |
|
562 |
||
563 |
CleanupStack::PopAndDestroy( 2 ); // field, title |
|
564 |
} |
|
565 |
} |
|
566 |
||
567 |
// -------------------------------------------------------------------------- |
|
568 |
// CPbk2AddressSelect::IndexOfDefaultFieldL |
|
569 |
// -------------------------------------------------------------------------- |
|
570 |
// |
|
571 |
inline TInt CPbk2AddressSelect::IndexOfDefaultFieldL() |
|
572 |
{ |
|
573 |
TInt ret = KErrNotFound; |
|
574 |
||
575 |
const MVPbkStoreContactField* field = FindDefaultFieldLC(); |
|
576 |
if ( field ) |
|
577 |
{ |
|
578 |
ret = iFieldFilter->FindField( *field ); |
|
579 |
} |
|
580 |
CleanupStack::PopAndDestroy(); // field |
|
581 |
||
582 |
return ret; |
|
583 |
} |
|
584 |
||
585 |
// -------------------------------------------------------------------------- |
|
586 |
// CPbk2AddressSelect::SelectFromDefaultFieldsL |
|
587 |
// -------------------------------------------------------------------------- |
|
588 |
// |
|
589 |
inline TBool CPbk2AddressSelect::SelectFromDefaultFieldsL() |
|
590 |
{ |
|
591 |
TBool found = EFalse; |
|
592 |
||
593 |
const MVPbkStoreContactField* field = FindDefaultFieldLC(); |
|
594 |
if ( field ) |
|
595 |
{ |
|
596 |
SetSelectedFieldL( field ); |
|
597 |
found = ETrue; |
|
598 |
} |
|
599 |
CleanupStack::PopAndDestroy(); // field |
|
600 |
||
601 |
return found; |
|
602 |
} |
|
603 |
||
604 |
// -------------------------------------------------------------------------- |
|
605 |
// CPbk2AddressSelect::FindDefaultFieldLC |
|
606 |
// -------------------------------------------------------------------------- |
|
607 |
// |
|
608 |
MVPbkStoreContactField* CPbk2AddressSelect::FindDefaultFieldLC() |
|
609 |
{ |
|
610 |
MVPbkStoreContactField* ret = NULL; |
|
611 |
||
612 |
// Go through the default priorities array, and |
|
613 |
// check does a specific default exist |
|
614 |
if ( iParams.iDefaultPriorities ) |
|
615 |
{ |
|
616 |
const TInt defaultCount = iParams.iDefaultPriorities->Count(); |
|
617 |
||
618 |
for (TInt i=0; i<defaultCount; ++i) |
|
619 |
{ |
|
620 |
TVPbkDefaultType defaultType = |
|
621 |
(TVPbkDefaultType) iParams.iDefaultPriorities->At(i); |
|
622 |
||
623 |
// Create an attribute prototype out of the attribute identifier |
|
624 |
CVPbkDefaultAttribute* attr = |
|
625 |
CVPbkDefaultAttribute::NewL( defaultType ); |
|
626 |
CleanupStack::PushL( attr ); |
|
627 |
||
628 |
if ( iAttributeManager->HasContactAttributeL |
|
629 |
( *attr, iParams.iContact ) ) |
|
630 |
{ |
|
631 |
const MVPbkStoreContactFieldCollection& fields = |
|
632 |
iParams.iContact.Fields(); |
|
633 |
||
634 |
// Get the field with attribute |
|
635 |
const TInt fieldCount = fields.FieldCount(); |
|
636 |
for ( TInt j = 0; j < fieldCount; ++j ) |
|
637 |
{ |
|
638 |
if ( iAttributeManager->HasFieldAttributeL |
|
639 |
( *attr, fields.FieldAt( j ) ) ) |
|
640 |
{ |
|
641 |
ret = fields.FieldAtLC( j ); |
|
642 |
CleanupStack::Pop(); // ret |
|
643 |
break; |
|
644 |
} |
|
645 |
} |
|
646 |
} |
|
647 |
||
648 |
CleanupStack::PopAndDestroy( attr ); |
|
649 |
} |
|
650 |
} |
|
651 |
||
652 |
CleanupDeletePushL( ret ); |
|
653 |
return ret; |
|
654 |
} |
|
655 |
||
656 |
// -------------------------------------------------------------------------- |
|
657 |
// CPbk2AddressSelect::SetSelectedFieldL |
|
658 |
// -------------------------------------------------------------------------- |
|
659 |
// |
|
660 |
inline void CPbk2AddressSelect::SetSelectedFieldL |
|
661 |
( const MVPbkStoreContactField* aField ) |
|
662 |
{ |
|
663 |
if ( aField ) |
|
664 |
{ |
|
665 |
const MVPbkStoreContactFieldCollection& fields = |
|
666 |
iParams.iContact.Fields(); |
|
667 |
TInt index = IndexOfField( fields, *aField ); |
|
668 |
if ( index >= 0 ) |
|
669 |
{ |
|
670 |
// field from main contact |
|
671 |
iSelectedField = fields.FieldAtLC( index ); |
|
672 |
CleanupStack::Pop(); |
|
673 |
} |
|
674 |
else if ( iStoreContactsArray != NULL && |
|
675 |
iStoreContactsArray->Count() > 0 ) |
|
676 |
{ |
|
677 |
// field from additional contact |
|
678 |
TInt count = iStoreContactsArray->Count(); |
|
679 |
for( TInt i = 0; i < count; i++ ) |
|
680 |
{ |
|
681 |
const MVPbkStoreContactFieldCollection& xspFields = |
|
682 |
iStoreContactsArray->operator[](i)->Fields(); |
|
683 |
index = IndexOfField( xspFields, *aField ); |
|
684 |
if ( index >= 0 ) |
|
685 |
{ |
|
686 |
iSelectedField = xspFields.FieldAtLC( index ); |
|
687 |
CleanupStack::Pop(); |
|
688 |
break; |
|
689 |
} |
|
690 |
} |
|
691 |
} |
|
692 |
} |
|
693 |
} |
|
694 |
||
695 |
// -------------------------------------------------------------------------- |
|
696 |
// CPbk2AddressSelect::IsVoiceCallExistL |
|
697 |
// -------------------------------------------------------------------------- |
|
698 |
// |
|
699 |
inline TBool CPbk2AddressSelect::IsVoiceCallExistL() |
|
700 |
{ |
|
701 |
TInt countFields = iParams.iContact.Fields().FieldCount(); |
|
702 |
TPbk2StoreContactAnalyzer analyzer( iParams.iContactManager, NULL ); |
|
703 |
||
704 |
for ( TInt i = 0; i < countFields; i++ ) |
|
705 |
{ |
|
706 |
const MVPbkStoreContactField& field = |
|
707 |
iParams.iContact.Fields().FieldAt( i ); |
|
708 |
||
709 |
// If the field is voice call, then return ETrue. |
|
710 |
if ( analyzer.IsFieldTypeIncludedL( field, R_PHONEBOOK2_PHONENUMBER_SELECTOR ) ) |
|
711 |
{ |
|
712 |
return ETrue; |
|
713 |
} |
|
714 |
} |
|
715 |
||
716 |
// No voice call filed, return EFalse. |
|
717 |
return EFalse; |
|
718 |
} |
|
719 |
||
720 |
// -------------------------------------------------------------------------- |
|
721 |
// CPbk2AddressSelect::GetVoiceAndVOIPCallDialogTitleL |
|
722 |
// -------------------------------------------------------------------------- |
|
723 |
// |
|
724 |
inline HBufC* CPbk2AddressSelect::GetVoiceAndVOIPCallDialogTitleL() |
|
725 |
{ |
|
726 |
HBufC* title (NULL); |
|
727 |
||
728 |
// If the popped up dialog is started in namelist view. |
|
729 |
// Then, the title of the dialog should obey such rules: |
|
730 |
// 1. When there are only VoIP addresses for contact or if VoIP is preferred. |
|
731 |
// Then show "Internet call:" |
|
732 |
// 2. In other cases show "Call:". This would be shown when: |
|
733 |
// 2.1 VoIP is not preferred and there's at least one Voice call number for the contact |
|
734 |
// 2.2 So even in case when there's only voice call numbers. |
|
735 |
// The title should be "Call:" instead of "Voice call:" |
|
736 |
if ( iParams.iTitleResId == R_QTN_PHOB_QTL_CALL_TO_NAME ) |
|
737 |
{ |
|
738 |
// Check whether VoIP is preferred. |
|
739 |
CSPSettingsVoIPUtils* sPSettings = CSPSettingsVoIPUtils::NewLC(); |
|
740 |
if ( sPSettings->IsPreferredTelephonyVoIP() || |
|
741 |
!IsVoiceCallExistL() ) |
|
742 |
{ |
|
743 |
title = GetVOIPDialogTitleL(); |
|
744 |
} |
|
745 |
else |
|
746 |
{ |
|
747 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_CALL ); |
|
748 |
} |
|
749 |
CleanupStack::PopAndDestroy( sPSettings ); |
|
750 |
} |
|
751 |
else if ( iParams.iCommMethod == VPbkFieldTypeSelectorFactory::EVoiceCallSelector ) |
|
752 |
{ |
|
753 |
title = StringLoader::LoadL( R_QTN_CCA_POPUP_VOICE_CALL ); |
|
754 |
} |
|
755 |
else if ( iParams.iCommMethod == VPbkFieldTypeSelectorFactory::EVOIPCallSelector ) |
|
756 |
{ |
|
757 |
title = GetVOIPDialogTitleL(); |
|
758 |
} |
|
759 |
return title; |
|
760 |
} |
|
761 |
||
762 |
// -------------------------------------------------------------------------- |
|
763 |
// CPbk2AddressSelect::LoadDialogTitleL |
|
764 |
// -------------------------------------------------------------------------- |
|
765 |
// |
|
766 |
inline HBufC* CPbk2AddressSelect::LoadDialogTitleL() |
|
767 |
{ |
|
768 |
HBufC* title = NULL; |
|
769 |
switch( iParams.iCommMethod ) |
|
770 |
{ |
|
771 |
case VPbkFieldTypeSelectorFactory::EVoiceCallSelector: |
|
772 |
case VPbkFieldTypeSelectorFactory::EVOIPCallSelector: |
|
773 |
{ |
|
774 |
title = GetVoiceAndVOIPCallDialogTitleL(); |
|
775 |
break; |
|
776 |
} |
|
777 |
||
778 |
case VPbkFieldTypeSelectorFactory::EUniEditorSelector: |
|
779 |
{ |
|
780 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_MESSAGE ); |
|
781 |
break; |
|
782 |
} |
|
783 |
case VPbkFieldTypeSelectorFactory::EEmailEditorSelector: |
|
784 |
{ |
|
785 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_EMAIL ); |
|
786 |
break; |
|
787 |
} |
|
788 |
case VPbkFieldTypeSelectorFactory::EInstantMessagingSelector: |
|
789 |
{ |
|
790 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_CHAT ); |
|
791 |
break; |
|
792 |
} |
|
793 |
case VPbkFieldTypeSelectorFactory::EURLSelector: |
|
794 |
{ |
|
795 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_URL ); |
|
796 |
break; |
|
797 |
} |
|
798 |
case VPbkFieldTypeSelectorFactory::EVideoCallSelector: |
|
799 |
{ |
|
800 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VIDEO_CALL ); |
|
801 |
break; |
|
802 |
} |
|
803 |
case VPbkFieldTypeSelectorFactory::EFindOnMapSelector: |
|
804 |
{ |
|
805 |
if ( AreGeoFieldsForAddressesL() ) |
|
806 |
{ |
|
807 |
title = StringLoader::LoadL( R_QTN_CCA_POPUP_SHOW_ON_MAP ); |
|
808 |
} |
|
809 |
else |
|
810 |
{ |
|
811 |
title = StringLoader::LoadL( R_QTN_CCA_POPUP_FIND_ON_MAP ); |
|
812 |
} |
|
813 |
break; |
|
814 |
} |
|
815 |
case VPbkFieldTypeSelectorFactory::EAssignFromMapSelector: |
|
816 |
{ |
|
817 |
title = StringLoader::LoadL( R_QTN_CCA_POPUP_ASSIGN_FROM_MAP ); |
|
818 |
break; |
|
819 |
} |
|
820 |
case VPbkFieldTypeSelectorFactory::EPocSelector: |
|
821 |
{ |
|
822 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_PUSH_TO_TALK ); |
|
823 |
break; |
|
824 |
} |
|
825 |
default: |
|
826 |
{ |
|
827 |
HBufC* entryTitle = iParams.iNameFormatter.GetContactTitleL |
|
828 |
( iParams.iContact.Fields(), KDefaultTitleFormat ); |
|
829 |
CleanupStack::PushL( entryTitle ); |
|
830 |
||
831 |
if ( iParams.iTitleResId ) |
|
832 |
{ |
|
833 |
if ( iParams.iIncludeContactNameInPrompt ) |
|
834 |
{ |
|
835 |
title = StringLoader::LoadL |
|
836 |
( iParams.iTitleResId, *entryTitle ); |
|
837 |
} |
|
838 |
else |
|
839 |
{ |
|
840 |
title = StringLoader::LoadL |
|
841 |
( iParams.iTitleResId ); |
|
842 |
} |
|
843 |
CleanupStack::PopAndDestroy( entryTitle ); |
|
844 |
} |
|
845 |
else |
|
846 |
{ |
|
847 |
title = entryTitle; // takes ownership of entryTitle |
|
848 |
CleanupStack::Pop( entryTitle ); |
|
849 |
entryTitle = NULL; |
|
850 |
} |
|
851 |
break; |
|
852 |
} |
|
853 |
} |
|
854 |
||
855 |
return title; |
|
856 |
} |
|
857 |
||
858 |
// -------------------------------------------------------------------------- |
|
859 |
// CPbk2AddressSelect::AreGeoFieldsForAddressesL |
|
860 |
// -------------------------------------------------------------------------- |
|
861 |
// |
|
862 |
TBool CPbk2AddressSelect::AreGeoFieldsForAddressesL() |
|
863 |
{ |
|
864 |
TBool result = EFalse; |
|
865 |
TBool generalAddress = ETrue; |
|
866 |
TBool homeAddress = ETrue; |
|
867 |
TBool workAddress = ETrue; |
|
868 |
TInt startIndex = 0; |
|
869 |
||
870 |
TPbk2StoreContactAnalyzer analyzer( iParams.iContactManager, NULL ); |
|
871 |
||
872 |
TInt countFields = iParams.iContact.Fields().FieldCount(); |
|
873 |
for ( TInt i = 0; i < countFields; i++ ) |
|
874 |
{ |
|
875 |
const MVPbkStoreContactField& field = |
|
876 |
iParams.iContact.Fields().FieldAt( i ); |
|
877 |
TInt countProps = |
|
878 |
field.BestMatchingFieldType()->VersitProperties().Count(); |
|
879 |
TArray<TVPbkFieldVersitProperty> props = |
|
880 |
field.BestMatchingFieldType()->VersitProperties(); |
|
881 |
for ( TInt ii = 0; ii < countProps; ii++ ) |
|
882 |
{ |
|
883 |
if ( props[ ii ].Name() == EVPbkVersitNameADR ) |
|
884 |
{ |
|
885 |
if ( props[ ii ].Parameters().Contains( |
|
886 |
EVPbkVersitParamHOME ) ) |
|
887 |
{ |
|
888 |
homeAddress = EFalse; |
|
889 |
} |
|
890 |
else if ( props[ ii ].Parameters().Contains( |
|
891 |
EVPbkVersitParamWORK ) ) |
|
892 |
{ |
|
893 |
workAddress = EFalse; |
|
894 |
} |
|
895 |
else |
|
896 |
{ |
|
897 |
generalAddress = EFalse; |
|
898 |
} |
|
899 |
} |
|
900 |
} |
|
901 |
} |
|
902 |
||
903 |
if ( !homeAddress ) |
|
904 |
{ |
|
905 |
if ( analyzer.HasFieldL( R_PHONEBOOK2_HOME_GEO_SELECTOR, |
|
906 |
startIndex, &iParams.iContact ) != KErrNotFound ) |
|
907 |
{ |
|
908 |
homeAddress = ETrue; |
|
909 |
} |
|
910 |
} |
|
911 |
if ( !workAddress ) |
|
912 |
{ |
|
913 |
if ( analyzer.HasFieldL( R_PHONEBOOK2_WORK_GEO_SELECTOR, |
|
914 |
startIndex, &iParams.iContact ) != KErrNotFound ) |
|
915 |
{ |
|
916 |
workAddress = ETrue; |
|
917 |
} |
|
918 |
} |
|
919 |
if ( !generalAddress ) |
|
920 |
{ |
|
921 |
if ( analyzer.HasFieldL( R_PHONEBOOK2_GENERAL_GEO_SELECTOR, |
|
922 |
startIndex, &iParams.iContact ) != KErrNotFound ) |
|
923 |
{ |
|
924 |
generalAddress = ETrue; |
|
925 |
} |
|
926 |
} |
|
927 |
||
928 |
if ( generalAddress && homeAddress && workAddress ) |
|
929 |
{ |
|
930 |
result = ETrue; |
|
931 |
} |
|
932 |
else |
|
933 |
{ |
|
934 |
result = EFalse; |
|
935 |
} |
|
936 |
||
937 |
return result; |
|
938 |
} |
|
939 |
||
940 |
// -------------------------------------------------------------------------- |
|
941 |
// CPbk2AddressSelect::GetVOIPDialogTitleL |
|
942 |
// -------------------------------------------------------------------------- |
|
943 |
// |
|
944 |
inline HBufC* CPbk2AddressSelect::GetVOIPDialogTitleL() |
|
945 |
{ |
|
946 |
//Usecase : If we have only one voip service, the voip(Internet Call) |
|
947 |
//dialog title must be "ServiceName" appended with "call:". |
|
948 |
//eg : If we have a service named SKYPE installed in the Phone |
|
949 |
//and if SKYPE supports VOIP, dialog title should be |
|
950 |
//"SKYPE call:". |
|
951 |
//If we have more than one voip service, then the VOIP dialog title must be |
|
952 |
//should be R_QTN_PHOB_TITLE_POPUP_VOIP_CALL |
|
953 |
//as defined in the rss |
|
954 |
||
955 |
//Check whether we have more than one voip service configured |
|
956 |
//in the Phone |
|
957 |
HBufC* title (NULL); |
|
958 |
TPtrC tempTitle; |
|
959 |
RIdArray idArray; |
|
960 |
CleanupClosePushL(idArray); |
|
961 |
CSPSettings* settings = CSPSettings::NewLC(); |
|
962 |
TInt numServSupportInternetCall (0); //Num of Service that support InternetCall |
|
963 |
TServiceId serviceId (0); //Stores the last found Service Id of VOIP Service |
|
964 |
TInt findResult = settings->FindServiceIdsL(idArray); |
|
965 |
if ( findResult == KErrNone ) |
|
966 |
{ |
|
967 |
for (TInt i = 0; i < idArray.Count(); ++i) |
|
968 |
{ |
|
969 |
TBool supported( EFalse ); |
|
970 |
CSPEntry* entry = CSPEntry::NewLC(); |
|
971 |
TServiceId id = idArray[i]; |
|
972 |
User::LeaveIfError( settings->FindEntryL(id, *entry) ); |
|
973 |
const CSPProperty* property = NULL; |
|
974 |
||
975 |
//Mandatory Settings for VOIP |
|
976 |
if (entry->GetProperty(property, EPropertyServiceAttributeMask) == KErrNone) |
|
977 |
{ |
|
978 |
TInt value = 0; |
|
979 |
property->GetValue(value); |
|
980 |
if ( value & ESupportsInternetCall ) |
|
981 |
{ |
|
982 |
serviceId = id; |
|
983 |
numServSupportInternetCall++; |
|
984 |
} |
|
985 |
} |
|
986 |
CleanupStack::PopAndDestroy(); // entry |
|
987 |
} |
|
988 |
CleanupStack::PopAndDestroy(2); // settings, idArray |
|
989 |
||
990 |
if ( KOneVOIPServiceAvailable == numServSupportInternetCall ) |
|
991 |
{ |
|
992 |
// get the XSP ServiceName |
|
993 |
// CPbk2ServiceManager stores all the brandinfo |
|
994 |
// related to the services configured to the phone |
|
995 |
// use this to show uniform icon & name throughout PhoneBook |
|
996 |
MPbk2ApplicationServices2* servicesExtension = |
|
997 |
reinterpret_cast<MPbk2ApplicationServices2*> |
|
998 |
( Phonebook2::Pbk2AppUi()->ApplicationServices(). |
|
999 |
MPbk2ApplicationServicesExtension( |
|
1000 |
KMPbk2ApplicationServicesExtension2Uid ) ); |
|
1001 |
CPbk2ServiceManager& servMan = servicesExtension->ServiceManager(); |
|
1002 |
const CPbk2ServiceManager::RServicesArray& services = servMan.Services(); |
|
1003 |
for ( TInt i = 0; i < services.Count(); i++ ) |
|
1004 |
{ |
|
1005 |
const CPbk2ServiceManager::TService& service = services[i]; |
|
1006 |
//Found the appropriate service info |
|
1007 |
if ( service.iServiceId == serviceId ) |
|
1008 |
{ |
|
1009 |
tempTitle.Set( service.iDisplayName ); |
|
1010 |
break; |
|
1011 |
} |
|
1012 |
} |
|
1013 |
} |
|
1014 |
} |
|
1015 |
if ( tempTitle.Length() ) |
|
1016 |
{ |
|
1017 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VOIP_CALL_SINGLE_SERVICE, |
|
1018 |
tempTitle); |
|
1019 |
} |
|
1020 |
else |
|
1021 |
{ |
|
1022 |
title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VOIP_CALL ); |
|
1023 |
} |
|
1024 |
||
1025 |
return title; |
|
1026 |
} |
|
1027 |
||
1028 |
// End of File |