|
1 // Copyright (c) 2002-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 |
|
18 #include <barsread.h> // TResourceReader |
|
19 #include <bautils.h> // BaflUtils |
|
20 #include "textresolver.h" |
|
21 #include <errorres.rsg> |
|
22 #include <uikon/eikdefconst.h> |
|
23 |
|
24 |
|
25 const TInt KUnknownError( 0 ); |
|
26 const TInt KBlankError( -2 ); |
|
27 |
|
28 const TInt KRIMask(0x00000fff); |
|
29 _LIT(KErrorResResourceFileName, "z:\\resource\\errors\\ERRORRES.RSC"); |
|
30 _LIT(KRDSupport, "c:\\resource\\ErrRD"); |
|
31 _LIT(KTextResolverPanic, "TextResolver"); |
|
32 |
|
33 |
|
34 GLDEF_C void Panic(TInt aPanic) |
|
35 { |
|
36 User::Panic(KTextResolverPanic, aPanic); |
|
37 } |
|
38 |
|
39 |
|
40 CTextResolver::CTextResolver() |
|
41 { |
|
42 } |
|
43 |
|
44 CTextResolver::CTextResolver(CCoeEnv& aEnv) |
|
45 :iCoe(&aEnv) |
|
46 { |
|
47 } |
|
48 /** |
|
49 * Two-phase constructor method that is used to create a new instance |
|
50 * of the CTextResolver class. The implementation uses the passed |
|
51 * CCoeEnv instance to access the resource files. |
|
52 * |
|
53 * @param aEnv the CCoeEnv instance to be used to access the resource |
|
54 * files. |
|
55 * @return a pointer to a new instance of the CTextResolver class. |
|
56 */ |
|
57 EXPORT_C CTextResolver* CTextResolver::NewL(CCoeEnv& aEnv) |
|
58 { |
|
59 CTextResolver* self = CTextResolver::NewLC(aEnv); |
|
60 CleanupStack::Pop(self); |
|
61 return self; |
|
62 } |
|
63 |
|
64 /** |
|
65 * Constructor creates a new instance of CTextResolver. The |
|
66 * implementation uses the passed CCoeEnv instance to access the |
|
67 * resource files. Leaves the object on the cleanup stack. |
|
68 * |
|
69 * @param aEnv the CCoeEnv instance to be used to access the resource |
|
70 * files. |
|
71 * @return a pointer to a new instance of the CTextResolver class. |
|
72 */ |
|
73 EXPORT_C CTextResolver* CTextResolver::NewLC(CCoeEnv& aEnv) |
|
74 { |
|
75 CTextResolver* self = new (ELeave) CTextResolver(aEnv); |
|
76 CleanupStack::PushL(self); |
|
77 self->ConstructL(); |
|
78 return self; |
|
79 } |
|
80 |
|
81 /** |
|
82 * Constructor creates a new instance of CTextResolver. Resource files |
|
83 * are accessed through the RResourceFile API. |
|
84 * |
|
85 * @return a pointer to a new instance of the CTextResolver class. |
|
86 */ |
|
87 EXPORT_C CTextResolver* CTextResolver::NewL() |
|
88 { |
|
89 CTextResolver* self = CTextResolver::NewLC(); |
|
90 CleanupStack::Pop(self); |
|
91 return self; |
|
92 } |
|
93 |
|
94 /** |
|
95 * Constructor creates a new instance of CTextResolver.Resource files |
|
96 * are accessed through the RResourceFile API. Leaves the object on |
|
97 * the cleanup stack. |
|
98 * |
|
99 * @return a pointer to a new instance of the CTextResolver class. |
|
100 */ |
|
101 EXPORT_C CTextResolver* CTextResolver::NewLC() |
|
102 { |
|
103 CTextResolver* self = new (ELeave) CTextResolver(); |
|
104 CleanupStack::PushL(self); |
|
105 self->ConstructL(); |
|
106 return self; |
|
107 } |
|
108 |
|
109 // |
|
110 // --------------------------------------------------------- |
|
111 // CTextResolver::ConstructL |
|
112 // |
|
113 // Symbian OS default constructor, initializes variables and cache |
|
114 // --------------------------------------------------------- |
|
115 // |
|
116 void CTextResolver::ConstructL() |
|
117 { |
|
118 // if no coe is present, connect new filesession. |
|
119 if (!iCoe) |
|
120 { |
|
121 User::LeaveIfError(iFs.Connect()); |
|
122 |
|
123 TFileName resFile(KErrorResResourceFileName); |
|
124 BaflUtils::NearestLanguageFile(iFs, resFile); |
|
125 iResFile.OpenL(iFs, resFile); |
|
126 } |
|
127 |
|
128 iRDSupport = BaflUtils::FileExists(iCoe ? iCoe->FsSession() : iFs, KRDSupport); |
|
129 } |
|
130 |
|
131 /** |
|
132 * Destructor |
|
133 */ |
|
134 EXPORT_C CTextResolver::~CTextResolver() |
|
135 { |
|
136 Reset(); |
|
137 iResFile.Close(); |
|
138 |
|
139 // if no coe is present, close filesession. |
|
140 if (!iCoe) |
|
141 iFs.Close(); |
|
142 |
|
143 delete iTitleText; |
|
144 delete iTextBuffer; |
|
145 delete iContextSeparator; |
|
146 } |
|
147 |
|
148 /** |
|
149 * Resolves the given error code and returns the error text for the |
|
150 * resolved error. Resolved text can be of any length. This version |
|
151 * is for "normal" use. |
|
152 * |
|
153 * @param aError The error code to be resolved. |
|
154 * @param aContext Optional context for error numbers. If the aContext |
|
155 * parameter is not passed to the function, it uses the default value |
|
156 * ECtxAutomatic. |
|
157 * @return the error text for the resolved error. "System error" (in |
|
158 * English localisation) is returned when error code is not known. For |
|
159 * unknown errors blank error flag (flags are defined in |
|
160 * textresolver.hrh) is also set to hide errors without proper |
|
161 * explanation. There is no limit on how long the resolved string |
|
162 * can be. |
|
163 */ |
|
164 EXPORT_C const TDesC& CTextResolver::ResolveErrorString(TInt aError, TErrorContext aContext) |
|
165 { |
|
166 TUint flags(0); |
|
167 TInt id(0); |
|
168 return ResolveErrorString(aError,id,flags,aContext); |
|
169 } |
|
170 |
|
171 /** |
|
172 * Resolves the given error code and returns the error text for the |
|
173 * resolved error. Resolved text can be of any length. This version |
|
174 * is for advanced use |
|
175 * |
|
176 * @param aError The error code to be resolved. |
|
177 * @param aTextId ID of the returned text. |
|
178 * @param aFlags The priority of the returned error. The priority is |
|
179 * defined by the this module! Flags are defined in textresolver.hrh. |
|
180 * @param aContext Optional context for error numbers. If the aContext |
|
181 * parameter is not passed to the function, it uses the default value |
|
182 * ECtxAutomatic. |
|
183 * @return the error text for the resolved error. "System error" (in |
|
184 * English localisation) is returned when error code is not known. For |
|
185 * unknown errors blank error flag (flags are defined in |
|
186 * textresolver.hrh) is also set to hide errors without proper |
|
187 * explanation. There is no limit on how long the resolved string |
|
188 * can be. |
|
189 */ |
|
190 EXPORT_C const TDesC& CTextResolver::ResolveErrorString(TInt aError, TInt& aTextId, TUint& aFlags, TErrorContext aContext) |
|
191 { |
|
192 aFlags = 0; |
|
193 if (iCoe) // Use the resource loaded using the CCoeEnv to read the resource file |
|
194 { |
|
195 TRAPD(err, DoResolveErrorStringL(aError, aTextId, aFlags)); |
|
196 if (err) |
|
197 { |
|
198 if ((!AddContextAndSeparator(aContext))) |
|
199 { |
|
200 // Even the resource file opening failed, return OOM flag |
|
201 aFlags |= EErrorResOOMFlag; |
|
202 return KNullDesC; |
|
203 } |
|
204 return *iTextBuffer; |
|
205 } |
|
206 |
|
207 if(aFlags&ETextResolverUnknownErrorFlag) // Error code not supported. No error text found. |
|
208 { |
|
209 // Error is not recognised |
|
210 aTextId = R_ERROR_RES_GENERAL; // Read and return an "unknown error" text from the |
|
211 // Nokia-specific version of the errorres.rss file |
|
212 TPtr appTextPtr = iTitleText->Des(); |
|
213 TPtr textPtr = iTextBuffer->Des(); |
|
214 iCoe->ReadResource(appTextPtr, R_BASE); |
|
215 iCoe->ReadResource(textPtr, R_ERROR_RES_GENERAL); |
|
216 } |
|
217 } |
|
218 else // No CCoeEnv available |
|
219 { |
|
220 aTextId = 0; |
|
221 TRAPD(err, DoRawReadOfSystemErrorResourcesToArraysL(aError, aTextId)); |
|
222 if(err) |
|
223 { |
|
224 // Cleaning needed since object not destroyed |
|
225 Reset(); |
|
226 |
|
227 if (aTextId != R_ERROR_RES_NO_MEMORY || !AddContextAndSeparator(aContext)) |
|
228 { |
|
229 // Even the resource file opening failed, return OOM flag |
|
230 aFlags |= EErrorResOOMFlag; |
|
231 return KNullDesC; |
|
232 } |
|
233 |
|
234 return *iTextBuffer; |
|
235 } |
|
236 |
|
237 aTextId = ResourceForError(aError); |
|
238 switch (aTextId) |
|
239 { |
|
240 case KBlankError: |
|
241 { |
|
242 aFlags |= ETextResolverBlankErrorFlag; |
|
243 break; |
|
244 } |
|
245 case KUnknownError: |
|
246 { |
|
247 // Error is not recognised |
|
248 aTextId = R_ERROR_RES_GENERAL; |
|
249 |
|
250 delete iTitleText; |
|
251 iTitleText = AllocReadUnicodeString(iResFile, R_BASE); |
|
252 aFlags |= ETextResolverUnknownErrorFlag; |
|
253 // No break here; Fall through to default case to resolve text for the general error |
|
254 } |
|
255 default: |
|
256 { |
|
257 // --- Error recognised by the resolver, so get the text --- |
|
258 delete iTextBuffer; |
|
259 iTextBuffer = AllocReadUnicodeString(iResFile, aTextId); |
|
260 break; |
|
261 } |
|
262 }; |
|
263 } |
|
264 |
|
265 if(aFlags&ETextResolverBlankErrorFlag) // Error code supported, but no error text found. |
|
266 { |
|
267 delete iTextBuffer; |
|
268 iTextBuffer = NULL; // Return no error text at all |
|
269 } |
|
270 |
|
271 if (!AddContextAndSeparator(aContext)) |
|
272 { |
|
273 aFlags |= EErrorResOOMFlag; |
|
274 return KNullDesC; |
|
275 } |
|
276 |
|
277 if (iRDSupport && iTextBuffer) |
|
278 { |
|
279 HBufC* tempBuffer = iTextBuffer->ReAlloc(iTextBuffer->Length()+14); |
|
280 |
|
281 // if allocation succeeds, append error id. Otherwise iTextBuffer stays as it is |
|
282 if (tempBuffer) |
|
283 { |
|
284 iTextBuffer = tempBuffer; |
|
285 iTextBuffer->Des().Append(' '); |
|
286 iTextBuffer->Des().Append('('); |
|
287 iTextBuffer->Des().AppendNum(aError); |
|
288 iTextBuffer->Des().Append(')'); |
|
289 } |
|
290 } |
|
291 else if (aFlags & ETextResolverUnknownErrorFlag) |
|
292 { // We hide the errors we cannot give proper explanation, |
|
293 //i.e. "System Error" will not be shown. |
|
294 aFlags |= ETextResolverBlankErrorFlag; |
|
295 } |
|
296 |
|
297 if (iTextBuffer) |
|
298 return *iTextBuffer; |
|
299 else |
|
300 return KNullDesC; |
|
301 } |
|
302 |
|
303 TInt CTextResolver::ResourceForError(TInt aError) |
|
304 { |
|
305 ASSERT(!iCoe); |
|
306 const TInt errorCount = iStartError->Count(); |
|
307 |
|
308 delete iTitleText; |
|
309 iTitleText = NULL; |
|
310 |
|
311 for (TInt cc = 0; cc < errorCount; ++cc) |
|
312 { |
|
313 const TInt starterror = (*iStartError)[cc]; |
|
314 const TInt endError = starterror-(*iErrorTexts)[cc]->Count()+1; |
|
315 |
|
316 if (aError >= endError && aError <= starterror) |
|
317 { |
|
318 ASSERT(!iTitleText); |
|
319 iTitleText = AllocReadUnicodeString(iResFile, (*iAppTexts)[cc]); |
|
320 |
|
321 const TInt errorIndex = -(aError-starterror); |
|
322 const TInt flags = (*iFlags)[cc]->At(errorIndex); |
|
323 |
|
324 if (flags & ETextResolverPanicErrorFlag) |
|
325 { |
|
326 // --- Some errors are never meant to get to the UI level --- |
|
327 // --- Those of them that do, result in a panic --- |
|
328 Panic(aError); |
|
329 } |
|
330 |
|
331 else if (flags & ETextResolverBlankErrorFlag) |
|
332 { |
|
333 // --- Error code can be ignored from the users' perspective --- |
|
334 // --- Return blank error text --- |
|
335 return KBlankError; |
|
336 } |
|
337 |
|
338 else if (flags & ETextResolverUnknownErrorFlag) |
|
339 { |
|
340 // --- Error not recognised by TextResolver --- |
|
341 // --- Will be passed on to UIKON for interpretation --- |
|
342 return KUnknownError; |
|
343 } |
|
344 |
|
345 return (*iErrorTexts)[cc]->At(errorIndex); |
|
346 } |
|
347 } |
|
348 |
|
349 return KUnknownError; |
|
350 } |
|
351 |
|
352 |
|
353 /** |
|
354 Read the system error texts from errorres.rss only, without using the Uikon CEikErrorResolver. |
|
355 This will not pick up any appliation specific errors. |
|
356 */ |
|
357 void CTextResolver::DoRawReadOfSystemErrorResourcesToArraysL(TInt& aError, TInt& aTextId) |
|
358 { |
|
359 ASSERT(!iCoe); |
|
360 TResourceReader reader; |
|
361 ReadLocalizedSeparatorCharacterFromResourceAndPrepareResourceReaderLC(reader); |
|
362 |
|
363 // Lets handle KErrNoMemory as a special case, this this way we can maybe avoid extra "Resolving Errors" |
|
364 if (aError == KErrNoMemory) |
|
365 { |
|
366 ASSERT(!iTextBuffer && !iTitleText); |
|
367 aTextId = R_ERROR_RES_NO_MEMORY; |
|
368 iTextBuffer = AllocReadUnicodeString(iResFile, aTextId); |
|
369 iTitleText = AllocReadUnicodeString(iResFile, R_BASE); |
|
370 User::Leave(KErrNoMemory); |
|
371 } |
|
372 |
|
373 if(iStartError && iErrorTexts && iFlags && iAppTexts) |
|
374 { |
|
375 CleanupStack::PopAndDestroy(); // rBuffer |
|
376 return; // Already all done |
|
377 } |
|
378 |
|
379 // The resource data is used differenciate between the old and new resource formats |
|
380 // (i.e, resources using title text and one's without using title text) |
|
381 // This API only support the new format, so just check that it is on the new format |
|
382 const TInt dummy = reader.ReadInt16(); |
|
383 const TInt version = reader.ReadInt16(); |
|
384 __ASSERT_ALWAYS(dummy == 0 && version == 2, User::Leave(KErrNotSupported)); |
|
385 |
|
386 // Read into the error arrays |
|
387 const TInt arrayCount = reader.ReadInt16(); |
|
388 |
|
389 ASSERT(!iStartError && !iErrorTexts && !iFlags && !iAppTexts); |
|
390 iStartError = new(ELeave) CArrayFixFlat<TInt>(arrayCount); |
|
391 iErrorTexts = new(ELeave) CArrayPtrSeg<CErrorResourceIdArray>(arrayCount); |
|
392 iFlags = new(ELeave) CArrayPtrSeg<CErrorResourceFlagArray>(arrayCount); |
|
393 iAppTexts = new(ELeave) CArrayFixFlat<TInt>(arrayCount); |
|
394 |
|
395 for (TInt cc = 0; cc < arrayCount; ++cc) |
|
396 { |
|
397 // Read in error array |
|
398 iAppTexts->AppendL(reader.ReadInt32()); // Application indicators |
|
399 iStartError->AppendL(reader.ReadInt32()); |
|
400 |
|
401 const TInt listId = reader.ReadInt32(); |
|
402 |
|
403 TResourceReader reader2; |
|
404 HBufC8* rBuffer = iResFile.AllocReadL(listId & KRIMask); // Remove offset from id |
|
405 reader2.SetBuffer(rBuffer); |
|
406 CleanupStack::PushL(rBuffer); |
|
407 |
|
408 const TInt count = reader2.ReadInt16(); |
|
409 CArrayFixFlat<TInt>* array = new(ELeave) CErrorResourceIdArray(count); |
|
410 CleanupStack::PushL(array); |
|
411 |
|
412 CArrayFixFlat<TInt>* flagarray = new(ELeave) CErrorResourceFlagArray(count); |
|
413 CleanupStack::PushL(flagarray); |
|
414 |
|
415 for (TInt dd = 0; dd < count; ++dd) |
|
416 { |
|
417 const TInt flags = reader2.ReadInt8(); |
|
418 flagarray->AppendL(flags); |
|
419 // Append resource id for this error text |
|
420 array->AppendL(reader2.ReadInt32()); |
|
421 } |
|
422 |
|
423 iFlags->AppendL(flagarray); |
|
424 CleanupStack::Pop(flagarray); |
|
425 |
|
426 iErrorTexts->AppendL(array); |
|
427 CleanupStack::Pop(array); |
|
428 |
|
429 CleanupStack::PopAndDestroy(rBuffer); |
|
430 } |
|
431 |
|
432 CleanupStack::PopAndDestroy(); // reader's rBuffer |
|
433 } |
|
434 |
|
435 // --------------------------------------------------------- |
|
436 // CTextResolver::Reset() |
|
437 // |
|
438 // Reset the member variables |
|
439 // --------------------------------------------------------- |
|
440 // |
|
441 void CTextResolver::Reset() |
|
442 { |
|
443 if (iBaseResourceFileOffset) |
|
444 { |
|
445 iCoe->DeleteResourceFile(iBaseResourceFileOffset); |
|
446 iBaseResourceFileOffset = 0; |
|
447 } |
|
448 |
|
449 if (iErrorTexts) |
|
450 { |
|
451 iErrorTexts->ResetAndDestroy(); |
|
452 delete iErrorTexts; |
|
453 iErrorTexts = NULL; |
|
454 } |
|
455 |
|
456 if (iFlags) |
|
457 { |
|
458 iFlags->ResetAndDestroy(); |
|
459 delete iFlags; |
|
460 iFlags = NULL; |
|
461 } |
|
462 |
|
463 delete iStartError; |
|
464 iStartError = NULL; |
|
465 |
|
466 delete iAppTexts; |
|
467 iAppTexts = NULL; |
|
468 } |
|
469 |
|
470 /** |
|
471 ErrorResolver resource files in the ?:/resource/errors/ folder must always begin with |
|
472 an array of error texts. The Nokia-specific version of the errorres.rss file also |
|
473 contains the localized titel/text separator character at the end of the file. |
|
474 This method reads the separator character from file using the CCoeEnv provided. |
|
475 */ |
|
476 void CTextResolver::ReadLocalizedSeparatorCharacterFromResourceL(CCoeEnv& aCoeEnv) |
|
477 { |
|
478 ASSERT(&aCoeEnv); |
|
479 |
|
480 if (!iBaseResourceFileOffset) |
|
481 { |
|
482 TFileName filename(KErrorResResourceFileName); |
|
483 BaflUtils::NearestLanguageFile(aCoeEnv.FsSession(), filename); |
|
484 |
|
485 iBaseResourceFileOffset = aCoeEnv.AddResourceFileL(filename); |
|
486 |
|
487 ASSERT(!iContextSeparator); |
|
488 iContextSeparator = aCoeEnv.AllocReadResourceL(R_LOCALIZED_CONTEXT_SEPARATOR); |
|
489 } |
|
490 } |
|
491 |
|
492 /** |
|
493 ErrorResolver resource files in the ?:/resource/errors/ folder must always begin with |
|
494 an array of error texts. The Nokia-specific version of the errorres.rss file also |
|
495 contains the localized titel/text separator character at the end of the file. |
|
496 This method reads the separator character from file WITHOUT using a CCoeEnv. |
|
497 */ |
|
498 void CTextResolver::ReadLocalizedSeparatorCharacterFromResourceAndPrepareResourceReaderLC(TResourceReader& aResReader) |
|
499 { |
|
500 ASSERT(!iCoe); |
|
501 ASSERT(!iBaseResourceFileOffset); |
|
502 |
|
503 HBufC8* rBuffer = iResFile.AllocReadL(R_ERROR_RES_BASE_LIST & KRIMask); // Remove offset from id |
|
504 aResReader.SetBuffer(rBuffer); |
|
505 CleanupStack::PushL(rBuffer); |
|
506 |
|
507 if(!iContextSeparator) |
|
508 iContextSeparator = AllocReadUnicodeString(iResFile, R_LOCALIZED_CONTEXT_SEPARATOR); |
|
509 |
|
510 // Leave rBuffer on CleanupStack |
|
511 } |
|
512 |
|
513 // returns NULL if out of memory |
|
514 HBufC* CTextResolver::AllocReadUnicodeString(RResourceFile& aResFile, TInt aTextId) |
|
515 { |
|
516 // Reading Unicode string w/o CCoe |
|
517 HBufC8* tempBuffer = NULL; |
|
518 HBufC* retBuffer = NULL; |
|
519 |
|
520 TRAPD(err, tempBuffer = aResFile.AllocReadL((KRIMask & aTextId))); // Remove offset from id |
|
521 if (!err) |
|
522 { |
|
523 __ASSERT_DEBUG((tempBuffer->Length()%2)==0,Panic(aTextId)); |
|
524 |
|
525 // do bitwise shift to halve the length for mapping the tempBuffer to unicode. |
|
526 TInt newLen = tempBuffer->Length()>>1; |
|
527 TPtrC tempPointer((TText*)tempBuffer->Ptr(), newLen); |
|
528 |
|
529 retBuffer = tempPointer.Alloc(); |
|
530 delete tempBuffer; |
|
531 } |
|
532 |
|
533 return retBuffer; |
|
534 } |
|
535 |
|
536 TBool CTextResolver::AddContextAndSeparator(TErrorContext aContext) |
|
537 { |
|
538 TBool retval(EFalse); |
|
539 |
|
540 if (iTextBuffer && iTitleText && iContextSeparator) // If we got all the parts we need... |
|
541 { |
|
542 //... then put them together according to the aContext argument |
|
543 |
|
544 // Context checked after validity of string buffers is checked, |
|
545 // because EFalse return value is required if any of those is NULL. |
|
546 if (aContext == ECtxNoCtxNoSeparator) |
|
547 retval = ETrue; |
|
548 else |
|
549 { |
|
550 HBufC* tempBuffer = iTextBuffer->ReAlloc(iTextBuffer->Length()+iContextSeparator->Length()+iTitleText->Length()+1); |
|
551 |
|
552 // If allocation succeeds, insert context. Otherwise iTextBuffer stays as it is. |
|
553 if (tempBuffer) |
|
554 { |
|
555 iTextBuffer = tempBuffer; |
|
556 |
|
557 // Add the title ("context") text and separator before the error text |
|
558 |
|
559 _LIT(KNewLineChar, "\n"); |
|
560 iTextBuffer->Des().Insert(0, KNewLineChar); |
|
561 iTextBuffer->Des().Insert(0, *iContextSeparator); |
|
562 |
|
563 if (aContext != ECtxNoCtx) |
|
564 iTextBuffer->Des().Insert(0,*iTitleText); |
|
565 |
|
566 retval = ETrue; |
|
567 } |
|
568 } |
|
569 } |
|
570 return retval; |
|
571 } |
|
572 |
|
573 void CTextResolver::AllocBuffersL() |
|
574 { |
|
575 delete iTitleText; |
|
576 iTitleText = NULL; |
|
577 delete iTextBuffer; |
|
578 iTextBuffer = NULL; |
|
579 |
|
580 iTitleText = HBufC::NewL(KEikErrorResolverMaxTextLength); |
|
581 iTextBuffer = HBufC::NewL(KEikErrorResolverMaxTextLength); |
|
582 } |
|
583 |
|
584 void CTextResolver::DoResolveErrorStringL(TInt aError, TInt& aTextId, TUint& aFlags) |
|
585 { |
|
586 ASSERT(iCoe); |
|
587 AllocBuffersL(); |
|
588 |
|
589 TPtr errTextPtr = iTextBuffer->Des(); |
|
590 TPtr errTitlePtr = iTitleText->Des(); |
|
591 |
|
592 CEikonEnv::TErrorValidity errValidity = static_cast<CEikonEnv*>(iCoe)->DoGetErrorTextAndTitle(errTextPtr, aError, aTextId, aFlags, errTitlePtr, ETrue); |
|
593 |
|
594 if (errValidity == CEikonEnv::EErrorNumInvalid) |
|
595 Panic(aError); |
|
596 |
|
597 // If either the iTextBuffer or iTitleText buffers were too small, |
|
598 // they will contain the required length coded as digits into the buffer |
|
599 TLex sizeRealloc(*iTextBuffer); |
|
600 TInt sizeRequiredForTextBuffer = 0; |
|
601 TInt sizeRequiredForTitleBuffer = 0; |
|
602 |
|
603 // Try reading the size required, if any |
|
604 sizeRealloc.Val(sizeRequiredForTextBuffer); |
|
605 sizeRealloc = *iTitleText; |
|
606 sizeRealloc.Val(sizeRequiredForTitleBuffer); |
|
607 |
|
608 // If sizes were found, realloc and get the error text again |
|
609 if (sizeRequiredForTextBuffer || sizeRequiredForTitleBuffer) |
|
610 { |
|
611 if (sizeRequiredForTextBuffer) |
|
612 { |
|
613 delete iTextBuffer; |
|
614 iTextBuffer = NULL; |
|
615 iTextBuffer = HBufC::NewL(sizeRequiredForTextBuffer); |
|
616 } |
|
617 |
|
618 if (sizeRequiredForTitleBuffer) |
|
619 { |
|
620 delete iTitleText; |
|
621 iTitleText = NULL; |
|
622 iTitleText = HBufC::NewL(sizeRequiredForTitleBuffer); |
|
623 } |
|
624 |
|
625 TPtr errTextPtr(iTextBuffer->Des()); |
|
626 TPtr errTitlePtr(iTitleText->Des()); |
|
627 errValidity = static_cast<CEikonEnv*>(iCoe)->DoGetErrorTextAndTitle(errTextPtr, aError, aTextId, aFlags, errTitlePtr, ETrue); |
|
628 if (!iTextBuffer->Length()) |
|
629 { |
|
630 delete iTextBuffer; |
|
631 iTextBuffer = NULL; |
|
632 } |
|
633 } |
|
634 |
|
635 ReadLocalizedSeparatorCharacterFromResourceL(*iCoe); |
|
636 } |
|
637 |
|
638 // End of File |
|
639 |
|
640 |