|
1 /* |
|
2 * Copyright (c) 2002-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: mmsclient implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <txtrich.h> |
|
22 #include <msvids.h> |
|
23 #include <badesca.h> |
|
24 #include <msvstore.h> |
|
25 #include <mtmuids.h> |
|
26 #include <mtclbase.h> |
|
27 #include <mtmdef.h> |
|
28 #include <logcli.h> |
|
29 #include <msvftext.h> // CMsvFindText |
|
30 #include <cmsvmimeheaders.h> |
|
31 #include <mmsvattachmentmanager.h> |
|
32 #include <mmsvattachmentmanagersync.h> |
|
33 #include <charconv.h> |
|
34 #include <msgtextutils.h> |
|
35 |
|
36 // mms headers |
|
37 #include "mmsheaders.h" |
|
38 #include "mmssettings.h" |
|
39 #include "mmsclient.h" |
|
40 #include "mmsmessageoperation.h" |
|
41 #include "mmsgenutils.h" |
|
42 #include "mmscmds.h" |
|
43 #include "mmsattachmenthandler.h" |
|
44 #include "mmssendingchain.h" |
|
45 #include "mmsattachmentwaiter.h" |
|
46 #include "mmssendmessageoperation.h" |
|
47 |
|
48 // EXTERNAL DATA STRUCTURES |
|
49 |
|
50 // EXTERNAL FUNCTION PROTOTYPES |
|
51 |
|
52 // CONSTANTS |
|
53 #ifdef _DEBUG |
|
54 #undef _NO_MMSC_LOGGING_ |
|
55 #endif |
|
56 |
|
57 _LIT( K1970, "19700000:000000.000000" ); // 1-Jan 1970 0:00:00 |
|
58 |
|
59 // MACROS |
|
60 |
|
61 // LOCAL CONSTANTS AND MACROS |
|
62 const TInt KMmsAttributeArrayGranularity = 8; |
|
63 |
|
64 // MODULE DATA STRUCTURES |
|
65 |
|
66 // LOCAL FUNCTION PROTOTYPES |
|
67 |
|
68 // ==================== LOCAL FUNCTIONS ==================== |
|
69 |
|
70 |
|
71 // ================= MEMBER FUNCTIONS ======================= |
|
72 |
|
73 // Factory function. |
|
74 EXPORT_C CMmsClientMtm* CMmsClientMtm::NewL( |
|
75 CRegisteredMtmDll& aRegisteredMtmDll, |
|
76 CMsvSession& aSession ) |
|
77 { |
|
78 CMmsClientMtm* self=new( ELeave ) CMmsClientMtm( |
|
79 aRegisteredMtmDll, aSession ); |
|
80 |
|
81 CleanupStack::PushL( self ); |
|
82 self->ConstructL(); |
|
83 CleanupStack::Pop( self ); |
|
84 |
|
85 return self; |
|
86 } |
|
87 |
|
88 |
|
89 // Constructor |
|
90 // Notice that CMmsNotificationClientMtm constructor calls this. |
|
91 CMmsClientMtm::CMmsClientMtm( |
|
92 CRegisteredMtmDll& aRegisteredMtmDll, |
|
93 CMsvSession& aSession ) |
|
94 : CBaseMtm( aRegisteredMtmDll, aSession ), |
|
95 iMmsSettings ( NULL ), |
|
96 iMmsHeaders ( NULL ), |
|
97 iServiceId ( KMsvNullIndexEntryId ), |
|
98 iFetchAll( EFalse ), |
|
99 iFetchOverride( ETrue ), |
|
100 iOwnSession( aSession ), |
|
101 iAttaWaiter( NULL ) |
|
102 { |
|
103 } |
|
104 |
|
105 |
|
106 // Destructor |
|
107 CMmsClientMtm::~CMmsClientMtm() |
|
108 { |
|
109 delete iAttaWaiter; |
|
110 // We created the settings, it is ours to delete |
|
111 delete iMmsSettings; |
|
112 delete iMmsHeaders; |
|
113 if ( iAttributes != 0 ) |
|
114 { |
|
115 iAttributes->Reset(); |
|
116 } |
|
117 delete iAttributes; |
|
118 } |
|
119 |
|
120 // --------------------------------------------------------- |
|
121 // CMmsClientMtm::CreateNewEntryL |
|
122 // --------------------------------------------------------- |
|
123 // |
|
124 CMsvOperation* CMmsClientMtm::CreateNewEntryL( |
|
125 TMsvId aDestination, |
|
126 TRequestStatus& aCompletionStatus) |
|
127 { |
|
128 |
|
129 return CMmsMessageOperation::CreateNewL( |
|
130 aCompletionStatus, |
|
131 Session(), |
|
132 aDestination, |
|
133 iServiceId ); |
|
134 } |
|
135 |
|
136 // DEPRECATED - TO BE REMOVED IN THE FUTURE |
|
137 // --------------------------------------------------------- |
|
138 // CMmsClientMtm::CreateServiceL |
|
139 // --------------------------------------------------------- |
|
140 // |
|
141 void CMmsClientMtm::CreateServiceL() |
|
142 { |
|
143 TMsvId service = KMsvNullIndexEntryId; |
|
144 // load settings in order to be sure the old ones are deleted |
|
145 iMmsSettings->LoadSettingsL(); |
|
146 // creates new service entry + new notification and mmbox folder entries |
|
147 iMmsSettings->CreateNewServiceL( Session() ); |
|
148 // save the new entry ids into cenrep immediatedly |
|
149 iMmsSettings->SaveSettingsL(); |
|
150 // Get the base values to detect changes |
|
151 // This function should not be idly called, so this should be safe. |
|
152 iHomeMode = iMmsSettings->ReceivingModeHome(); |
|
153 iRoamingMode = iMmsSettings->ReceivingModeForeign(); |
|
154 iAccessPointCount = iMmsSettings->AccessPointCount(); |
|
155 // service id must be returned |
|
156 service = iMmsSettings->Service(); |
|
157 |
|
158 if ( service == KMsvNullIndexEntryId ) |
|
159 { |
|
160 // No new entry created |
|
161 User::Leave( KErrNotSupported ); |
|
162 } |
|
163 SwitchCurrentEntryL( service ); |
|
164 } |
|
165 |
|
166 // --------------------------------------------------------- |
|
167 // CMmsClientMtm::MmsSettings() |
|
168 // --------------------------------------------------------- |
|
169 // |
|
170 const CMmsSettings& CMmsClientMtm::MmsSettings() |
|
171 { |
|
172 return *iMmsSettings; |
|
173 } |
|
174 |
|
175 // --------------------------------------------------------- |
|
176 // CMmsClientMtm::SetSettingsL |
|
177 // --------------------------------------------------------- |
|
178 // |
|
179 void CMmsClientMtm::SetSettingsL( const CMmsSettings& aSettings ) |
|
180 { |
|
181 // copy caller's settings to our member |
|
182 iMmsSettings->CopyL( aSettings ); |
|
183 } |
|
184 |
|
185 // --------------------------------------------------------- |
|
186 // CMmsClientMtm::StoreSettingsL() |
|
187 // --------------------------------------------------------- |
|
188 // |
|
189 void CMmsClientMtm::StoreSettingsL() |
|
190 { |
|
191 // Check that sufficient disk space available |
|
192 |
|
193 if ( iAccessPointCount < iMmsSettings->AccessPointCount() ) |
|
194 { |
|
195 // Disk space checked only if the file size increases. |
|
196 // And the file size increases only when access points are added. |
|
197 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
198 &Session().FileSession(), |
|
199 KMmsAccessPointDiskSpaceNeed, |
|
200 EDriveC ) ) |
|
201 { |
|
202 // we use standard error code here |
|
203 User::Leave( KErrDiskFull ); |
|
204 } |
|
205 } |
|
206 iMmsSettings->SaveSettingsL(); |
|
207 |
|
208 // if one of the receiving modes have changed to automatic, |
|
209 // start fetching deferred messages |
|
210 TInt homeMode = iMmsSettings->ReceivingModeHome(); |
|
211 TInt roamMode = iMmsSettings->ReceivingModeForeign(); |
|
212 |
|
213 if ( ( homeMode != iHomeMode && homeMode == EMmsReceivingAutomatic ) || |
|
214 ( roamMode != iRoamingMode && roamMode == EMmsReceivingAutomatic )) |
|
215 { |
|
216 // fetch all, but only if fetching mode allows it. |
|
217 iFetchAll = ETrue; |
|
218 iFetchOverride = EFalse; |
|
219 } |
|
220 else |
|
221 { |
|
222 iFetchAll = EFalse; |
|
223 iFetchOverride = ETrue; |
|
224 } |
|
225 |
|
226 // We don't leave the settings store function just because the automatic |
|
227 // fetch operation leaves. Some entry may be locked and cannot be fetched |
|
228 // or some other problem may prevent the fetch. |
|
229 // Settings are stored anyway. |
|
230 TInt error = KErrNone; |
|
231 TRAP( error, |
|
232 if ( iFetchAll ) |
|
233 { |
|
234 // Implicit fetch of messages, wrap asynch method to make it synch. |
|
235 CMsvOperation* myOperation; |
|
236 myOperation = NULL; |
|
237 CMsvOperationActiveSchedulerWait* wait = |
|
238 CMsvOperationActiveSchedulerWait::NewLC(); |
|
239 // FetchAllL only schedules notifications in mms folder |
|
240 myOperation = FetchAllL( wait->iStatus, iFetchOverride ); |
|
241 // temporary. |
|
242 CleanupStack::PushL( myOperation ); |
|
243 wait->Start(); |
|
244 CleanupStack::PopAndDestroy( myOperation ); |
|
245 CleanupStack::PopAndDestroy( wait ); |
|
246 // Then the notifications in inbox |
|
247 wait = CMsvOperationActiveSchedulerWait::NewLC(); |
|
248 wait->iStatus = KRequestPending; |
|
249 // FetchAllFromInboxL only schedules notifications in inbox |
|
250 myOperation = FetchAllFromInboxL( wait->iStatus, iFetchOverride ); |
|
251 CleanupStack::PushL( myOperation ); |
|
252 wait->Start(); |
|
253 |
|
254 CleanupStack::PopAndDestroy( myOperation ); |
|
255 CleanupStack::PopAndDestroy( wait ); |
|
256 iFetchAll = EFalse; // don't do this next time unless needed... |
|
257 } |
|
258 ); |
|
259 |
|
260 // Reset the remembered values |
|
261 iHomeMode = iMmsSettings->ReceivingModeHome(); |
|
262 iRoamingMode = iMmsSettings->ReceivingModeForeign(); |
|
263 iAccessPointCount = iMmsSettings->AccessPointCount(); |
|
264 } |
|
265 |
|
266 // --------------------------------------------------------- |
|
267 // CMmsClientMtm::RestoreSettingsL() |
|
268 // --------------------------------------------------------- |
|
269 // |
|
270 void CMmsClientMtm::RestoreSettingsL() |
|
271 { |
|
272 // The settings may have been changed without us knowing it. |
|
273 // We do not reset saved mode values here, because we try to |
|
274 // detect if receiving mode has change since we last checked |
|
275 // in StoreSettingsL() function. |
|
276 iMmsSettings->LoadSettingsL(); |
|
277 } |
|
278 |
|
279 |
|
280 // DEPRECATED - TO BE REMOVED IN THE FUTURE |
|
281 // --------------------------------------------------------- |
|
282 // CMmsClientMtm::RestoreFactorySettingsL |
|
283 // --------------------------------------------------------- |
|
284 // |
|
285 void CMmsClientMtm::RestoreFactorySettingsL( TMmsFactorySettingsLevel aLevel ) |
|
286 { |
|
287 iMmsSettings->LoadSettingsL(); |
|
288 iMmsSettings->RestoreFactorySettingsL( Session(), aLevel ); |
|
289 // StoreSettingsL triggers the fetching of messages if the receiving mode |
|
290 // has changed in a way that requires it. |
|
291 StoreSettingsL(); |
|
292 } |
|
293 |
|
294 |
|
295 //---------------------------------------------------------- |
|
296 // MMS HEADER HANDLING METHODS |
|
297 //---------------------------------------------------------- |
|
298 |
|
299 // --------------------------------------------------------- |
|
300 // CMmsClientMtm::SetSenderL |
|
301 // --------------------------------------------------------- |
|
302 // |
|
303 void CMmsClientMtm::SetSenderL( const TDesC& aAlias ) |
|
304 { |
|
305 iMmsHeaders->SetSenderL( aAlias ); |
|
306 } |
|
307 |
|
308 // --------------------------------------------------------- |
|
309 // CMmsClientMtm::Sender |
|
310 // --------------------------------------------------------- |
|
311 // |
|
312 const TPtrC CMmsClientMtm::Sender( ) const |
|
313 { |
|
314 return iMmsHeaders->Sender(); |
|
315 } |
|
316 |
|
317 // --------------------------------------------------------- |
|
318 // CMmsClientMtm::MessageClass |
|
319 // --------------------------------------------------------- |
|
320 // |
|
321 void CMmsClientMtm::SetMessageClass( TMmsMessageClass aMessageClass ) |
|
322 { |
|
323 iMmsHeaders->SetMessageClass( aMessageClass ); |
|
324 } |
|
325 |
|
326 // --------------------------------------------------------- |
|
327 // CMmsClientMtm::MessageClass |
|
328 // --------------------------------------------------------- |
|
329 // |
|
330 TInt CMmsClientMtm::MessageClass() const |
|
331 { |
|
332 return iMmsHeaders->MessageClass(); |
|
333 } |
|
334 |
|
335 // --------------------------------------------------------- |
|
336 // CMmsClientMtm::SetMessagePriority |
|
337 // --------------------------------------------------------- |
|
338 // |
|
339 void CMmsClientMtm::SetMessagePriority( TMmsMessagePriority aPriority ) |
|
340 { |
|
341 iMmsHeaders->SetMessagePriority(aPriority); |
|
342 } |
|
343 |
|
344 // --------------------------------------------------------- |
|
345 // CMmsClientMtm::MessagePriority |
|
346 // --------------------------------------------------------- |
|
347 // |
|
348 TInt CMmsClientMtm::MessagePriority() const |
|
349 { |
|
350 return iMmsHeaders->MessagePriority(); |
|
351 } |
|
352 |
|
353 // --------------------------------------------------------- |
|
354 // CMmsClientMtm::SetSenderVisibility |
|
355 // --------------------------------------------------------- |
|
356 // |
|
357 void CMmsClientMtm::SetSenderVisibility( TMmsMessageSenderVisibility aVisibility ) |
|
358 { |
|
359 iMmsHeaders->SetSenderVisibility(aVisibility); |
|
360 } |
|
361 |
|
362 // --------------------------------------------------------- |
|
363 // CMmsClientMtm::SenderVisibility |
|
364 // --------------------------------------------------------- |
|
365 // |
|
366 TInt CMmsClientMtm::SenderVisibility() const |
|
367 { |
|
368 return iMmsHeaders->SenderVisibility(); |
|
369 } |
|
370 |
|
371 // --------------------------------------------------------- |
|
372 // CMmsClientMtm::SetDeliveryReport |
|
373 // --------------------------------------------------------- |
|
374 // |
|
375 void CMmsClientMtm::SetDeliveryReport( TMmsMessageDeliveryReport aVisibility ) |
|
376 { |
|
377 iMmsHeaders->SetDeliveryReport(aVisibility); |
|
378 } |
|
379 |
|
380 // --------------------------------------------------------- |
|
381 // CMmsClientMtm::DeliveryReport |
|
382 // --------------------------------------------------------- |
|
383 // |
|
384 TInt CMmsClientMtm::DeliveryReport() const |
|
385 { |
|
386 return iMmsHeaders->DeliveryReport(); |
|
387 } |
|
388 |
|
389 // --------------------------------------------------------- |
|
390 // CMmsClientMtm::SetReadReply |
|
391 // --------------------------------------------------------- |
|
392 // |
|
393 void CMmsClientMtm::SetReadReply( TMmsMessageReadReply aRequest ) |
|
394 { |
|
395 iMmsHeaders->SetReadReply(aRequest); |
|
396 } |
|
397 |
|
398 // --------------------------------------------------------- |
|
399 // CMmsClientMtm::ReadReply |
|
400 // --------------------------------------------------------- |
|
401 // |
|
402 TInt CMmsClientMtm::ReadReply() const |
|
403 { |
|
404 return iMmsHeaders->ReadReply(); |
|
405 } |
|
406 |
|
407 // --------------------------------------------------------- |
|
408 // CMmsClientMtm::SetMessageRootL |
|
409 // --------------------------------------------------------- |
|
410 // |
|
411 |
|
412 void CMmsClientMtm::SetMessageRootL( const TMsvAttachmentId aId ) |
|
413 { |
|
414 // We cannot check if the attachent id is legal because Symbian |
|
415 // message server panics if the store is already open. |
|
416 // We must just trust the caller. |
|
417 iMmsHeaders->SetMessageRoot( aId ); |
|
418 } |
|
419 |
|
420 // --------------------------------------------------------- |
|
421 // CMmsClientMtm::MessageRootAttachment |
|
422 // --------------------------------------------------------- |
|
423 // |
|
424 TMsvAttachmentId CMmsClientMtm::MessageRootAttachment() const |
|
425 { |
|
426 // This function only returns what has been set earlier by the caller. |
|
427 // As the caller can manipulate the attachments without calling |
|
428 // MMS Client MTM, we cannot keep track of the presence of the root |
|
429 // attachment. It is up to the user to handle the case where the root |
|
430 // has been deleted. |
|
431 return iMmsHeaders->MessageRoot(); |
|
432 } |
|
433 |
|
434 // --------------------------------------------------------- |
|
435 // CMmsClientMtm::SendingDate |
|
436 // --------------------------------------------------------- |
|
437 // |
|
438 TTime CMmsClientMtm::SendingDate() const |
|
439 { |
|
440 |
|
441 TInt64 inSeconds = iMmsHeaders->Date(); |
|
442 |
|
443 TTime y1970( K1970 ); |
|
444 |
|
445 // 1970 presented as microseconds after January 1st, 0 AD Gregorian. |
|
446 TInt64 ms1970 = y1970.Int64(); |
|
447 |
|
448 // If not defined in message headers return 0 |
|
449 if ( inSeconds == 0 ) |
|
450 { |
|
451 return TTime( 0 ); |
|
452 } |
|
453 |
|
454 return TTime( ms1970 + ( inSeconds * KMmsMillion ) ); |
|
455 |
|
456 } |
|
457 |
|
458 // --------------------------------------------------------- |
|
459 // CMmsClientMtm::SetMaximumImage |
|
460 // --------------------------------------------------------- |
|
461 // |
|
462 void CMmsClientMtm::SetMaximumImage( TInt aHigh, TInt aWidth ) |
|
463 { |
|
464 iMmsHeaders->SetMaximumImage( aHigh, aWidth ); |
|
465 } |
|
466 |
|
467 // --------------------------------------------------------- |
|
468 // CMmsClientMtm::GetMaximumImage |
|
469 // --------------------------------------------------------- |
|
470 // |
|
471 void CMmsClientMtm::GetMaximumImage( TInt& aHeight, TInt& aWidth ) const |
|
472 { |
|
473 iMmsHeaders->GetMaximumImage( aHeight, aWidth ); |
|
474 } |
|
475 |
|
476 // --------------------------------------------------------- |
|
477 // CMmsClientMtm::SetExpiryInterval |
|
478 // --------------------------------------------------------- |
|
479 // |
|
480 void CMmsClientMtm::SetExpiryInterval( |
|
481 TTimeIntervalSeconds aInterval ) |
|
482 { |
|
483 iMmsHeaders->SetExpiryInterval(aInterval.Int()); |
|
484 } |
|
485 |
|
486 // --------------------------------------------------------- |
|
487 // CMmsClientMtm::ExpiryInterval |
|
488 // --------------------------------------------------------- |
|
489 // |
|
490 TTimeIntervalSeconds CMmsClientMtm::ExpiryInterval() const |
|
491 { |
|
492 TTimeIntervalSeconds seconds(iMmsHeaders->ExpiryInterval()); |
|
493 |
|
494 return seconds; |
|
495 } |
|
496 |
|
497 // --------------------------------------------------------- |
|
498 // CMmsClientMtm::SetExpiryDate |
|
499 // --------------------------------------------------------- |
|
500 // |
|
501 void CMmsClientMtm::SetExpiryDate( TTime aDate ) |
|
502 { |
|
503 |
|
504 TTime y1970( K1970 ); |
|
505 TTimeIntervalMicroSeconds interval; |
|
506 // we can't use "seconds from" as it only returns a |
|
507 // 32 bit signed integer. If fails in 2038. |
|
508 // "microseconds from" returns a 64 bit signed integer |
|
509 interval = aDate.MicroSecondsFrom( y1970 ); |
|
510 if ( interval.Int64() > 0 ) |
|
511 { |
|
512 // expiry date in iMmsHeaders() in seconds from 1.1.1970. |
|
513 iMmsHeaders->SetExpiryDate( ( interval.Int64() ) / KMmsMillion ); |
|
514 } |
|
515 } |
|
516 |
|
517 // --------------------------------------------------------- |
|
518 // CMmsClientMtm::ExpiryDate |
|
519 // --------------------------------------------------------- |
|
520 // |
|
521 TTime CMmsClientMtm::ExpiryDate() const |
|
522 { |
|
523 |
|
524 TTime y1970( K1970 ); |
|
525 |
|
526 // 1970 presented as microseconds after January 1st, 0 AD Gregorian. |
|
527 TInt64 ms1970 = y1970.Int64(); |
|
528 |
|
529 // Expiry in Seconds after 1.1. 1970 |
|
530 TInt64 sAfter1970 = iMmsHeaders->ExpiryDate(); |
|
531 |
|
532 // If not defined in message headers return 0 |
|
533 if ( sAfter1970 == 0 ) |
|
534 { |
|
535 return TTime(0); |
|
536 } |
|
537 |
|
538 // Expiry in microseconds after 1.1. 1970 |
|
539 TInt64 msAfter1970; |
|
540 msAfter1970 = sAfter1970; |
|
541 msAfter1970 *= KMmsMillion; |
|
542 |
|
543 return TTime( ms1970 + msAfter1970 ); |
|
544 |
|
545 } |
|
546 |
|
547 // --------------------------------------------------------- |
|
548 // CMmsClientMtm::SetDeliveryTimeInterval |
|
549 // --------------------------------------------------------- |
|
550 // |
|
551 void CMmsClientMtm::SetDeliveryTimeInterval( |
|
552 TTimeIntervalSeconds aInterval ) |
|
553 { |
|
554 iMmsHeaders->SetDeliveryTimeInterval( aInterval.Int() ); |
|
555 } |
|
556 |
|
557 // --------------------------------------------------------- |
|
558 // CMmsClientMtm::DeliveryTimeInterval |
|
559 // --------------------------------------------------------- |
|
560 // |
|
561 TTimeIntervalSeconds CMmsClientMtm::DeliveryTimeInterval() const |
|
562 { |
|
563 TTimeIntervalSeconds seconds( iMmsHeaders->DeliveryTimeInterval() ); |
|
564 return seconds; |
|
565 } |
|
566 |
|
567 // --------------------------------------------------------- |
|
568 // CMmsClientMtm::SetDeliveryDate |
|
569 // --------------------------------------------------------- |
|
570 // |
|
571 void CMmsClientMtm::SetDeliveryDate( TTime aDate ) |
|
572 { |
|
573 |
|
574 TTime y1970( K1970 ); |
|
575 TTimeIntervalMicroSeconds interval; |
|
576 // we can't use "seconds from" as it only returns a |
|
577 // 32 bit signed integer. If fails in 2038. |
|
578 // "microseconds from" returns a 64 bit signed integer |
|
579 interval = aDate.MicroSecondsFrom( y1970 ); |
|
580 if (interval.Int64() > 0 ) |
|
581 { |
|
582 // Delivery date in iMmsHeaders() in seconds from 1.1.1970. |
|
583 iMmsHeaders->SetDeliveryDate( (interval.Int64() ) / KMmsMillion ); |
|
584 } |
|
585 } |
|
586 |
|
587 // --------------------------------------------------------- |
|
588 // CMmsClientMtm::DeliveryDate |
|
589 // --------------------------------------------------------- |
|
590 // |
|
591 TTime CMmsClientMtm::DeliveryDate() const |
|
592 { |
|
593 |
|
594 TTime y1970( K1970 ); |
|
595 |
|
596 // 1970 presented as microseconds after January 1st, 0 AD Gregorian. |
|
597 TInt64 ms1970 = y1970.Int64(); |
|
598 |
|
599 // Expiry in Seconds after 1.1. 1970 |
|
600 TInt64 sAfter1970 = iMmsHeaders->DeliveryDate(); |
|
601 |
|
602 // If not defined in message headers return 0 |
|
603 if ( sAfter1970 == 0 ) |
|
604 { |
|
605 return TTime(0); |
|
606 } |
|
607 |
|
608 // Expiry in microseconds after 1.1. 1970 |
|
609 TInt64 msAfter1970; |
|
610 msAfter1970 = sAfter1970; |
|
611 msAfter1970 *= KMmsMillion; |
|
612 |
|
613 return TTime( ms1970 + msAfter1970 ); |
|
614 |
|
615 } |
|
616 |
|
617 // --------------------------------------------------------- |
|
618 // CMmsClientMtm::SendL |
|
619 // --------------------------------------------------------- |
|
620 // |
|
621 CMsvOperation* CMmsClientMtm::SendL( TRequestStatus& aCompletionStatus, |
|
622 const TTime aSendingTime /* = TTime( 0 ) */ ) |
|
623 { |
|
624 |
|
625 CMsvEntrySelection* selection = new( ELeave ) CMsvEntrySelection; |
|
626 CleanupStack::PushL( selection ); // *** |
|
627 |
|
628 // Current entry will be the one to send |
|
629 selection->AppendL( iMsvEntry->Entry().Id() ); |
|
630 |
|
631 // aSendingTime is passed on "as is". |
|
632 // SendL with selection makes the conversion if needed |
|
633 CMsvOperation* op = SendL( *selection, aCompletionStatus, aSendingTime ); |
|
634 |
|
635 CleanupStack::PopAndDestroy( selection ); |
|
636 |
|
637 return op; |
|
638 |
|
639 } |
|
640 |
|
641 // --------------------------------------------------------- |
|
642 // CMmsClientMtm::SendL |
|
643 // --------------------------------------------------------- |
|
644 // |
|
645 CMsvOperation* CMmsClientMtm::SendL( |
|
646 CMsvEntrySelection& aSelection, |
|
647 TRequestStatus& aCompletionStatus, |
|
648 TTime aSendingTime ) |
|
649 { |
|
650 |
|
651 if ( aSelection.Count() == 0 ) |
|
652 { |
|
653 User::Leave( KErrNotFound ); |
|
654 } |
|
655 |
|
656 CMsvEntrySelection* selection = new( ELeave ) CMsvEntrySelection; |
|
657 CleanupStack::PushL( selection ); // *** |
|
658 |
|
659 // Move the messages to OUTBOX synchronously |
|
660 // Parent should be the parent of the first entry in the selection |
|
661 CMsvEntry* cEntry = NULL; |
|
662 TMsvId currentParent = iMsvEntry->Entry().Parent(); |
|
663 cEntry = Session().GetEntryL( aSelection.At( 0 ) ); |
|
664 CleanupStack::PushL( cEntry ); |
|
665 currentParent = cEntry->Entry().Parent(); |
|
666 cEntry->SetEntryL( currentParent ); |
|
667 |
|
668 #ifndef _NO_MMSC_LOGGING_ |
|
669 _LIT( KMmsBefore, "MMSC: Entry parent before move 0x%08X"); |
|
670 TMmsGenUtils::Log( KMmsBefore, currentParent ); |
|
671 #endif |
|
672 if ( currentParent != KMsvGlobalOutBoxIndexEntryId ) |
|
673 { |
|
674 TMsvLocalOperationProgress progress; |
|
675 cEntry->MoveL( aSelection, KMsvGlobalOutBoxIndexEntryId, progress ); |
|
676 } |
|
677 |
|
678 #ifndef _NO_MMSC_LOGGING_ |
|
679 cEntry->SetEntryL( aSelection.At( 0 ) ); |
|
680 currentParent = cEntry->Entry().Parent(); |
|
681 _LIT( KMmsAfter, "MMSC: Entry parent after move 0x%08X"); |
|
682 TMmsGenUtils::Log( KMmsAfter, currentParent ); |
|
683 #endif |
|
684 CleanupStack::PopAndDestroy( cEntry ); |
|
685 |
|
686 selection->AppendL( aSelection.Back( 0 ), aSelection.Count() ); |
|
687 |
|
688 // Call Server MTM |
|
689 TCommandParameters parameters; // initialized to zero |
|
690 TTime now; |
|
691 // All times in message entries are now UTC time |
|
692 now.UniversalTime(); |
|
693 TInt error = KErrNone; |
|
694 if ( aSendingTime > now ) |
|
695 { |
|
696 error = aSendingTime.SecondsFrom( now, parameters.iInitialDelay ); |
|
697 } |
|
698 if ( error != KErrNone ) |
|
699 { |
|
700 User::Leave( error ); |
|
701 } |
|
702 |
|
703 TCommandParametersBuf paramPack( parameters ); |
|
704 |
|
705 CMsvOperation* op = InvokeAsyncFunctionL( |
|
706 EMmsScheduledSend, |
|
707 *selection, |
|
708 paramPack, |
|
709 aCompletionStatus ); |
|
710 |
|
711 CleanupStack::PopAndDestroy( selection ); |
|
712 |
|
713 return op; |
|
714 |
|
715 } |
|
716 |
|
717 |
|
718 // --------------------------------------------------------- |
|
719 // CMmsClientMtm::FetchAllL |
|
720 // --------------------------------------------------------- |
|
721 // |
|
722 CMsvOperation* CMmsClientMtm::FetchAllL( TRequestStatus& aCompletionStatus, |
|
723 TBool aForced ) |
|
724 { |
|
725 |
|
726 iFetchOverride = aForced; |
|
727 |
|
728 CMsvEntrySelection* selection = ListMmsFolderNotificationsL(); |
|
729 CleanupStack::PushL( selection ); |
|
730 |
|
731 if ( selection->Count() == 0 ) |
|
732 { |
|
733 CleanupStack::PopAndDestroy( selection ); |
|
734 TPckgC < TMsvId > progress = 0; |
|
735 aCompletionStatus = KRequestPending; |
|
736 return CMsvCompletedOperation::NewL( Session(), Type(), progress, |
|
737 KMsvLocalServiceIndexEntryId, aCompletionStatus ); |
|
738 } |
|
739 |
|
740 TCommandParameters parameters; // initialized to zero |
|
741 TCommandParametersBuf paramPack( parameters ); |
|
742 |
|
743 CMsvOperation* op = NULL; |
|
744 if ( iFetchOverride ) |
|
745 { |
|
746 op = InvokeAsyncFunctionL( |
|
747 EMmsScheduledReceiveForced, |
|
748 *selection, |
|
749 paramPack, |
|
750 aCompletionStatus ); |
|
751 } |
|
752 else |
|
753 { |
|
754 op = InvokeAsyncFunctionL( |
|
755 EMmsScheduledReceive, |
|
756 *selection, |
|
757 paramPack, |
|
758 aCompletionStatus ); |
|
759 // reset override to default value |
|
760 iFetchOverride = ETrue; |
|
761 } |
|
762 |
|
763 CleanupStack::PopAndDestroy( selection ); |
|
764 return op; |
|
765 } |
|
766 |
|
767 // --------------------------------------------------------- |
|
768 // CMmsClientMtm::SendReadReportL |
|
769 // --------------------------------------------------------- |
|
770 // |
|
771 CMsvOperation* CMmsClientMtm::SendReadReportL( TMsvId aReadMessageId, |
|
772 TRequestStatus& aCompletionStatus, |
|
773 TMmsReadStatus aReadStatus /*= EMmsReadStatusRead*/ ) |
|
774 { |
|
775 // Get the entry for which the report will be sent |
|
776 |
|
777 CMmsHeaders* reportHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() ); |
|
778 CleanupStack::PushL( reportHeaders ); |
|
779 CMmsHeaders* originalHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() ); |
|
780 CleanupStack::PushL( originalHeaders ); |
|
781 |
|
782 CMsvEntry* cEntry = NULL; |
|
783 CMsvStore* store = NULL; |
|
784 // Restore original headers. |
|
785 // If we are sending the report to current context, use our own entry |
|
786 if ( aReadMessageId == iMsvEntry->Entry().Id() && |
|
787 aReadMessageId != KMsvNullIndexEntryId ) |
|
788 { |
|
789 store = iMsvEntry->ReadStoreL(); |
|
790 CleanupStack::PushL( store ); |
|
791 originalHeaders->RestoreL( *store ); |
|
792 CleanupStack::PopAndDestroy( store ); |
|
793 store = NULL; |
|
794 } |
|
795 else |
|
796 { |
|
797 // If we cannot get the entry, the function leaves |
|
798 cEntry = Session().GetEntryL( aReadMessageId ); |
|
799 CleanupStack::PushL( cEntry ); |
|
800 store = cEntry->ReadStoreL(); |
|
801 CleanupStack::PushL( store ); |
|
802 originalHeaders->RestoreL( *store ); |
|
803 CleanupStack::PopAndDestroy( store ); |
|
804 store = NULL; |
|
805 CleanupStack::PopAndDestroy( cEntry ); |
|
806 cEntry = NULL; |
|
807 } |
|
808 |
|
809 if ( !iMmsSettings->ReadReplyReportSendingAllowed() || |
|
810 originalHeaders->ReadReply() != EMmsYes || |
|
811 originalHeaders->Sender().Length() == 0 || |
|
812 iMmsHeaders->MessageClass() == EMmsClassAuto ) |
|
813 { |
|
814 // We are not allowed to send a read reply, or the sender of the |
|
815 // original message has not requested a read reply - do not send one. |
|
816 // We are also not allowed to send a read report to automatic messages. |
|
817 CleanupStack::PopAndDestroy( originalHeaders ); |
|
818 originalHeaders = NULL; |
|
819 CleanupStack::PopAndDestroy( reportHeaders ); |
|
820 reportHeaders = NULL; |
|
821 |
|
822 TPckgC < TMsvId > progress = 0; |
|
823 return CMsvCompletedOperation::NewL( Session(), Type(), progress, |
|
824 KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrGeneral ); |
|
825 } |
|
826 |
|
827 // Now we have loaded the original headers and decided that a read |
|
828 // report really must be sent. |
|
829 // We create a new message entry in the MMS Notification folder to keep |
|
830 // it invisible. |
|
831 |
|
832 reportHeaders->SetMessageIdL( originalHeaders->MessageId() ); |
|
833 reportHeaders->SetMessageType( KMmsMessageTypeReadRecInd ); |
|
834 reportHeaders->AddTypedAddresseeL( TMmsGenUtils::PureAddress( originalHeaders->Sender() ), |
|
835 EMsvRecipientTo ); |
|
836 // sender must be insert-address-token because we don't know our own number |
|
837 // And if there are many recipients we cannot be sure which one is our own number |
|
838 |
|
839 // We are through with the original headers |
|
840 CleanupStack::PopAndDestroy( originalHeaders ); |
|
841 originalHeaders = NULL; |
|
842 |
|
843 TTime now; |
|
844 now.UniversalTime(); |
|
845 |
|
846 TTime y1970( K1970 ); |
|
847 TTimeIntervalMicroSeconds interval; |
|
848 // we can't use "seconds from" as it only returns a |
|
849 // 32 bit signed integer. If fails in 2038. |
|
850 // "microseconds from" returns a 64 bit signed integer |
|
851 interval = now.MicroSecondsFrom( y1970 ); |
|
852 // date in iMmsHeaders() in seconds from 1.1.1970. |
|
853 reportHeaders->SetDate( ( interval.Int64() ) / KMmsMillion ); |
|
854 reportHeaders->SetReadStatus( aReadStatus ); |
|
855 |
|
856 TMsvId mmsFolderId = iMmsSettings->NotificationFolder(); |
|
857 cEntry = Session().GetEntryL( mmsFolderId ); |
|
858 CleanupStack::PushL( cEntry ); |
|
859 |
|
860 // We create the entry immediately as complete because we store the data immediately |
|
861 // If the battery runs out at the wrong moment, garbage collection will throw the |
|
862 // extra entry away as it is marked as read rec ind. |
|
863 TMsvEntry entry; |
|
864 entry.iType = KUidMsvMessageEntry; |
|
865 entry.iMtm = KUidMsgTypeMultimedia; |
|
866 entry.SetVisible( ETrue ); |
|
867 entry.SetInPreparation( EFalse ); |
|
868 // We set the service as local service to get past the line |
|
869 // in case sending or receiving is ongoing |
|
870 entry.iServiceId = KMsvLocalServiceIndexEntryId; |
|
871 entry.iRelatedId = iServiceId; |
|
872 entry.iMtmData1 = KMmsMessageReadRecInd; |
|
873 cEntry->CreateL( entry ); |
|
874 |
|
875 TMsvId entryId = entry.Id(); |
|
876 |
|
877 cEntry->SetEntryL( entryId ); |
|
878 |
|
879 store = cEntry->EditStoreL(); |
|
880 CleanupStack::PushL( store ); |
|
881 reportHeaders->StoreL( *store ); |
|
882 store->CommitL(); |
|
883 CleanupStack::PopAndDestroy( store ); |
|
884 store = NULL; |
|
885 |
|
886 // These can go now. Our entry is ready to be sent |
|
887 CleanupStack::PopAndDestroy( cEntry ); |
|
888 cEntry = NULL; |
|
889 CleanupStack::PopAndDestroy( reportHeaders ); |
|
890 reportHeaders = NULL; |
|
891 |
|
892 CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; |
|
893 CleanupStack::PushL( selection ); |
|
894 selection->InsertL( 0, entryId ); |
|
895 |
|
896 CMsvOperation * op = NULL; |
|
897 TCommandParameters parameters; // initialized to zero |
|
898 TCommandParametersBuf paramPack( parameters ); |
|
899 |
|
900 op = Session().TransferCommandL( *selection, |
|
901 EMmsScheduledReadReport, |
|
902 paramPack, |
|
903 aCompletionStatus ); |
|
904 |
|
905 CleanupStack::PopAndDestroy( selection ); |
|
906 |
|
907 return op; |
|
908 } |
|
909 |
|
910 // --------------------------------------------------------- |
|
911 // CMmsClientMtm::ResponseText |
|
912 // --------------------------------------------------------- |
|
913 // |
|
914 TPtrC CMmsClientMtm::ResponseText() const |
|
915 { |
|
916 return iMmsHeaders->ResponseText( ); |
|
917 } |
|
918 |
|
919 // --------------------------------------------------------- |
|
920 // CMmsClientMtm::ResponseStatus |
|
921 // --------------------------------------------------------- |
|
922 // |
|
923 TInt CMmsClientMtm::ResponseStatus() const |
|
924 { |
|
925 return iMmsHeaders->ResponseStatus(); |
|
926 } |
|
927 |
|
928 // --------------------------------------------------------- |
|
929 // CMmsClientMtm::NumberOfPreviousSenders |
|
930 // --------------------------------------------------------- |
|
931 // |
|
932 TInt CMmsClientMtm::NumberOfPreviousSenders() const |
|
933 { |
|
934 return iMmsHeaders->PreviouslySentList().Count(); |
|
935 } |
|
936 |
|
937 // --------------------------------------------------------- |
|
938 // CMmsClientMtm:: |
|
939 // --------------------------------------------------------- |
|
940 // |
|
941 TPtrC CMmsClientMtm::PreviousSender( TInt aSequenceNumber ) const |
|
942 { |
|
943 if ( aSequenceNumber > iMmsHeaders->PreviouslySentList().Count() || |
|
944 aSequenceNumber < 1 ) |
|
945 { |
|
946 return TPtrC(); |
|
947 } |
|
948 return iMmsHeaders->PreviouslySentList()[aSequenceNumber - 1]->Sender(); |
|
949 } |
|
950 |
|
951 // --------------------------------------------------------- |
|
952 // CMmsClientMtm:: |
|
953 // --------------------------------------------------------- |
|
954 // |
|
955 TTime CMmsClientMtm::PreviousSendingDate( TInt aSequenceNumber ) const |
|
956 { |
|
957 if ( aSequenceNumber > iMmsHeaders->PreviouslySentList().Count() || |
|
958 aSequenceNumber < 1 ) |
|
959 { |
|
960 return TTime( 0 ); |
|
961 } |
|
962 |
|
963 TInt64 inSeconds; |
|
964 inSeconds = iMmsHeaders->PreviouslySentList()[aSequenceNumber - 1]->Date(); |
|
965 |
|
966 // If not defined in message headers return 0 |
|
967 if ( inSeconds == 0 ) |
|
968 { |
|
969 return TTime(0); |
|
970 } |
|
971 |
|
972 TTime y1970( K1970 ); |
|
973 // 1970 presented as microseconds after January 1st, 0 AD Gregorian. |
|
974 TInt64 ms1970 = y1970.Int64(); |
|
975 |
|
976 return TTime( ms1970 + ( KMmsMillion * inSeconds ) ); |
|
977 |
|
978 } |
|
979 |
|
980 // --------------------------------------------------------- |
|
981 // CMmsClientMtm::MessageReceiveTime |
|
982 // --------------------------------------------------------- |
|
983 // |
|
984 TTime CMmsClientMtm::MessageReceiveTime() const |
|
985 { |
|
986 return iMmsHeaders->ReceivingTime(); |
|
987 } |
|
988 |
|
989 // --------------------------------------------------------- |
|
990 // CMmsClientMtm::MessageTransferSize |
|
991 // --------------------------------------------------------- |
|
992 // |
|
993 TInt CMmsClientMtm::MessageTransferSize() const |
|
994 { |
|
995 return iMmsHeaders->MessageSize(); |
|
996 } |
|
997 |
|
998 // --------------------------------------------------------- |
|
999 // CMmsClientMtm::MessageContentLocation |
|
1000 // --------------------------------------------------------- |
|
1001 // |
|
1002 TPtrC8 CMmsClientMtm::MessageContentLocation() const |
|
1003 { |
|
1004 return iMmsHeaders->ContentLocation(); |
|
1005 } |
|
1006 |
|
1007 //---------------------------------------------------------- |
|
1008 // METHODS FROM BASE CLASS |
|
1009 //---------------------------------------------------------- |
|
1010 |
|
1011 // --------------------------------------------------------- |
|
1012 // CMmsClientMtm::SaveMessageL |
|
1013 // Stores the multimedia message |
|
1014 // --------------------------------------------------------- |
|
1015 // |
|
1016 void CMmsClientMtm::SaveMessageL() |
|
1017 { |
|
1018 // First we should assert that iMsvEntry is not NULL, and panic, if it is |
|
1019 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet )); |
|
1020 // SaveMessageL should only be supported for message entries. |
|
1021 __ASSERT_DEBUG( iMsvEntry->Entry().iType.iUid == KUidMsvMessageEntryValue, |
|
1022 gPanic( EMmsNotAMessageEntry ) ); |
|
1023 |
|
1024 TMsvEntry indexEntry = iMsvEntry->Entry(); |
|
1025 |
|
1026 // Store headers of a multimedia message |
|
1027 |
|
1028 // Because of the way the attachments are handled using the new |
|
1029 // attacment manager, the caller must store and commit the attachments |
|
1030 // either one by one or after all have been added. |
|
1031 // After saving all attachments the edit store used for that purpose |
|
1032 // must be freed. |
|
1033 // The store must be freed because all attachment info and MMS headers |
|
1034 // are saved in the actual message entry, there are no separate |
|
1035 // attachment entries anymore. |
|
1036 |
|
1037 // When a message is saved in client, the possible transaction ID is cleared |
|
1038 // because when the message is changed, it must get a new TID in MMS server |
|
1039 // when it is sent. |
|
1040 iMmsHeaders->SetTidL( TPtrC8() ); |
|
1041 |
|
1042 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
1043 CleanupStack::PushL( store ); |
|
1044 // Check that sufficient disk space available |
|
1045 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
1046 &Session().FileSession(), |
|
1047 iMmsHeaders->Size(), |
|
1048 iMessageDrive ) ) |
|
1049 { |
|
1050 User::Leave( KErrDiskFull ); |
|
1051 } |
|
1052 |
|
1053 // Note: Body text not supported. |
|
1054 |
|
1055 iMmsHeaders->StoreL( *store ); |
|
1056 |
|
1057 StoreAttributesL( *store ); |
|
1058 |
|
1059 // Commit the stream store |
|
1060 store->CommitL(); |
|
1061 CleanupStack::PopAndDestroy( store ); |
|
1062 |
|
1063 // Start to update index entry |
|
1064 // If the caller has not set the description, we set it to messge subject - |
|
1065 // if subject is available. |
|
1066 if ( indexEntry.iDescription.Length() == 0 ) |
|
1067 { |
|
1068 indexEntry.iDescription.Set( iMmsHeaders->Subject() ); |
|
1069 } |
|
1070 // The caller must set the message to complete and visible when it is ready: |
|
1071 /* |
|
1072 indexEntry.SetInPreparation( EFalse ); |
|
1073 indexEntry.SetVisible( ETrue ); |
|
1074 indexEntry.iDate.UniversalTime(); |
|
1075 */ |
|
1076 |
|
1077 // attachment size |
|
1078 TInt32 totalSizeOfAllAttachments = AttachmentsSizeL(); |
|
1079 indexEntry.iSize = iMmsHeaders->Size() + totalSizeOfAllAttachments; |
|
1080 |
|
1081 // If there are multiple recipients then set the flag |
|
1082 if (( iMmsHeaders->ToRecipients().Count() + |
|
1083 iMmsHeaders->CcRecipients().Count() + |
|
1084 iMmsHeaders->BccRecipients().Count() ) > 1 ) |
|
1085 { |
|
1086 indexEntry.SetMultipleRecipients( ETrue ); |
|
1087 } |
|
1088 else |
|
1089 { |
|
1090 // clear multiple recipients in case recipients have |
|
1091 // been deleted after the message was saved the last time |
|
1092 indexEntry.SetMultipleRecipients( EFalse ); |
|
1093 } |
|
1094 |
|
1095 // Set iDetails (recipient) |
|
1096 // Check that MT message's details not updated, |
|
1097 // although this should not be possible in UI. |
|
1098 if ( !( indexEntry.iMtmData1 & KMmsMessageMobileTerminated ) ) |
|
1099 { |
|
1100 TPtrC to; |
|
1101 if ( iMmsHeaders->ToRecipients().Count() ) |
|
1102 { |
|
1103 to.Set( TMmsGenUtils::Alias( iMmsHeaders->ToRecipients()[0] ) ); |
|
1104 if ( to.Length() <= 0 ) |
|
1105 { |
|
1106 // If no alias part then set the real address in details |
|
1107 to.Set( iMmsHeaders->ToRecipients()[0] ); |
|
1108 } |
|
1109 } |
|
1110 indexEntry.iDetails.Set( to ); |
|
1111 } |
|
1112 |
|
1113 if ( totalSizeOfAllAttachments > 0 ) |
|
1114 { |
|
1115 indexEntry.SetAttachment( ETrue ); |
|
1116 } |
|
1117 |
|
1118 if ( iAttributes->MdcaCount() > 0 ) |
|
1119 { |
|
1120 indexEntry.iMtmData1 |= KMmsAttributeStreamPresent; |
|
1121 } |
|
1122 else |
|
1123 { |
|
1124 indexEntry.iMtmData1 &= ~KMmsAttributeStreamPresent; |
|
1125 } |
|
1126 |
|
1127 switch ( iMmsHeaders->MessagePriority() ) |
|
1128 { |
|
1129 case KMmsPriorityNormal: |
|
1130 indexEntry.SetPriority( EMsvMediumPriority ); |
|
1131 break; |
|
1132 case KMmsPriorityLow: |
|
1133 indexEntry.SetPriority( EMsvLowPriority ); |
|
1134 break; |
|
1135 case KMmsPriorityHigh: |
|
1136 indexEntry.SetPriority( EMsvHighPriority ); |
|
1137 break; |
|
1138 default: |
|
1139 // if not defined default is normal |
|
1140 indexEntry.SetPriority( EMsvMediumPriority ); |
|
1141 break; |
|
1142 } |
|
1143 |
|
1144 // commit the index changes. |
|
1145 iMsvEntry->ChangeL( indexEntry ); |
|
1146 } |
|
1147 |
|
1148 // --------------------------------------------------------- |
|
1149 // CMmsClientMtm::LoadMessageL |
|
1150 // Loads the multimedia message |
|
1151 // --------------------------------------------------------- |
|
1152 // |
|
1153 void CMmsClientMtm::LoadMessageL() |
|
1154 { |
|
1155 // First we should assert that iMsvEntry is not NULL, and panic, if it is |
|
1156 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet ) ); |
|
1157 // LoadMessageL should only be supported for message entries. |
|
1158 if ( iMsvEntry->Entry().iType.iUid != KUidMsvMessageEntryValue ) |
|
1159 { |
|
1160 iAttributes->Reset(); |
|
1161 iMmsHeaders->Reset(); |
|
1162 iAddresseeList->Reset(); |
|
1163 return; |
|
1164 } |
|
1165 |
|
1166 // Old data must be reset first.... |
|
1167 iAttributes->Reset(); |
|
1168 |
|
1169 // load the correct data |
|
1170 // get read-only message store |
|
1171 CMsvStore* store = iMsvEntry->ReadStoreL(); |
|
1172 CleanupStack::PushL( store ); |
|
1173 |
|
1174 // restore headers of multimedia message |
|
1175 // Attachment info is not restored. |
|
1176 // It makes no sense to cache the attachment info as new attachments |
|
1177 // can be added with the help of the attachment magager without |
|
1178 // informing MMS Client MTM of the additions. |
|
1179 // Caller must use attachment manager to get attachment info. |
|
1180 iMmsHeaders->RestoreL( *store ); |
|
1181 |
|
1182 RestoreAttributesL( *store ); |
|
1183 |
|
1184 CleanupStack::PopAndDestroy( store ); |
|
1185 store = NULL; |
|
1186 |
|
1187 // Build the iAddresseeList up |
|
1188 BuildAddresseeListL(); |
|
1189 |
|
1190 } |
|
1191 |
|
1192 // --------------------------------------------------------- |
|
1193 // CMmsClientmtm::ReplyL |
|
1194 // Send a reply to current message |
|
1195 // --------------------------------------------------------- |
|
1196 // |
|
1197 CMsvOperation* CMmsClientMtm::ReplyL( |
|
1198 TMsvId aDestination, |
|
1199 TMsvPartList aPartList, |
|
1200 TRequestStatus& aCompletionStatus ) |
|
1201 { |
|
1202 |
|
1203 return CMmsMessageOperation::CreateReplyL( |
|
1204 aCompletionStatus, |
|
1205 Session(), |
|
1206 iMsvEntry->EntryId(), |
|
1207 aDestination, |
|
1208 aPartList, |
|
1209 iServiceId ); |
|
1210 } |
|
1211 |
|
1212 // --------------------------------------------------------- |
|
1213 // CMmsClientMtm::ForwardL |
|
1214 // Forward current message |
|
1215 // --------------------------------------------------------- |
|
1216 // |
|
1217 CMsvOperation* CMmsClientMtm::ForwardL( |
|
1218 TMsvId aDestination, |
|
1219 TMsvPartList aPartList, |
|
1220 TRequestStatus& aCompletionStatus ) |
|
1221 { |
|
1222 |
|
1223 return CMmsMessageOperation::CreateForwardL( |
|
1224 aCompletionStatus, |
|
1225 Session(), |
|
1226 iMsvEntry->EntryId(), |
|
1227 aDestination, |
|
1228 aPartList, |
|
1229 iServiceId ); |
|
1230 } |
|
1231 |
|
1232 // --------------------------------------------------------- |
|
1233 // CMmsClientMtm::ValidateMessage |
|
1234 // Validate selected parts of current message |
|
1235 // --------------------------------------------------------- |
|
1236 // |
|
1237 TMsvPartList CMmsClientMtm::ValidateMessage( |
|
1238 TMsvPartList aPartList ) |
|
1239 { |
|
1240 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet )); |
|
1241 |
|
1242 TMsvPartList retVal = 0; |
|
1243 if ( iMsvEntry->Entry().iType.iUid != KUidMsvMessageEntryValue ) |
|
1244 { |
|
1245 // not a message, no part is valid |
|
1246 retVal = aPartList; |
|
1247 } |
|
1248 |
|
1249 if ( aPartList & KMsvMessagePartRecipient ) |
|
1250 { |
|
1251 if ( iAddresseeList->Count() == 0) |
|
1252 { |
|
1253 retVal |= KMsvMessagePartRecipient; |
|
1254 } |
|
1255 else |
|
1256 { |
|
1257 // check the recipient list for valid 'addresses' |
|
1258 for (TInt ii=0; ii < iAddresseeList->Count(); ++ii) |
|
1259 { |
|
1260 TPtrC oneAddress = (*iAddresseeList)[ii]; |
|
1261 TPtrC pureAddress = TMmsGenUtils::PureAddress( oneAddress ); |
|
1262 if ( ( pureAddress.Length() == 0 ) || |
|
1263 !TMmsGenUtils::IsValidAddress( pureAddress, ETrue ) ) |
|
1264 { |
|
1265 retVal |= KMsvMessagePartRecipient; |
|
1266 break; |
|
1267 } |
|
1268 } |
|
1269 } |
|
1270 } |
|
1271 |
|
1272 // all attachments are considered valid - even no attachments |
|
1273 |
|
1274 return retVal; |
|
1275 |
|
1276 } |
|
1277 |
|
1278 // --------------------------------------------------------- |
|
1279 // CMmsClientMtm::Find |
|
1280 // Find text in selected message parts |
|
1281 // --------------------------------------------------------- |
|
1282 // |
|
1283 TMsvPartList CMmsClientMtm::Find( |
|
1284 const TDesC& aTextToFind, |
|
1285 TMsvPartList aPartList ) |
|
1286 { |
|
1287 // The final version will not have a rich text body, but we could |
|
1288 // search for example the originator and description. |
|
1289 |
|
1290 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet ) ); |
|
1291 TMsvPartList foundList = KMsvMessagePartNone; |
|
1292 |
|
1293 TRAP_IGNORE( |
|
1294 { |
|
1295 TMsvEntry entry = iMsvEntry->Entry(); |
|
1296 |
|
1297 CMsvFindText* findText = CMsvFindText::NewL(); |
|
1298 |
|
1299 CleanupStack::PushL( findText ); |
|
1300 |
|
1301 if ( aPartList & KMsvMessagePartRecipient ) |
|
1302 { |
|
1303 // Find from To, Cc and Bcc fields |
|
1304 if ( FindInRecipientL( aTextToFind, |
|
1305 aPartList, iMmsHeaders->ToRecipients(), *findText)) |
|
1306 { |
|
1307 foundList |= KMsvMessagePartRecipient; |
|
1308 } |
|
1309 else if ( FindInRecipientL( aTextToFind, |
|
1310 aPartList, iMmsHeaders->CcRecipients(), *findText )) |
|
1311 { |
|
1312 foundList |= KMsvMessagePartRecipient; |
|
1313 } |
|
1314 else if ( FindInRecipientL( aTextToFind, |
|
1315 aPartList, iMmsHeaders->BccRecipients(), *findText )) |
|
1316 { |
|
1317 foundList |= KMsvMessagePartRecipient; |
|
1318 } |
|
1319 else |
|
1320 { |
|
1321 // keep LINT happy |
|
1322 } |
|
1323 } |
|
1324 |
|
1325 if ( aPartList & KMsvMessagePartOriginator ) |
|
1326 { |
|
1327 if ( findText->FindTextL( aTextToFind, iMmsHeaders->Sender(), |
|
1328 aPartList ) ) |
|
1329 { |
|
1330 foundList |= KMsvMessagePartOriginator; |
|
1331 } |
|
1332 } |
|
1333 |
|
1334 if ( aPartList & KMsvMessagePartDescription ) |
|
1335 { |
|
1336 if ( findText->FindTextL( aTextToFind, entry.iDescription, |
|
1337 aPartList ) ) |
|
1338 { |
|
1339 foundList |= KMsvMessagePartDescription; |
|
1340 } |
|
1341 } |
|
1342 |
|
1343 CleanupStack::PopAndDestroy( findText ); |
|
1344 }); |
|
1345 return foundList; |
|
1346 |
|
1347 } |
|
1348 |
|
1349 // --------------------------------------------------------- |
|
1350 // CMmsClientMtm::AddAddresseeL |
|
1351 // --------------------------------------------------------- |
|
1352 // |
|
1353 void CMmsClientMtm::AddAddresseeL( const TDesC& aRealAddress ) |
|
1354 { |
|
1355 // Add to general list |
|
1356 // When no type is specified, the address will have type "to" |
|
1357 iAddresseeList->AppendL( EMsvRecipientTo, aRealAddress ); |
|
1358 |
|
1359 // Add to "To" recipient list |
|
1360 iMmsHeaders->AddTypedAddresseeL( aRealAddress, EMsvRecipientTo ); |
|
1361 |
|
1362 } |
|
1363 |
|
1364 // --------------------------------------------------------- |
|
1365 // CMmsClientMtm::AddAddresseeL |
|
1366 // --------------------------------------------------------- |
|
1367 // |
|
1368 void CMmsClientMtm::AddAddresseeL( |
|
1369 const TDesC& aRealAddress, |
|
1370 const TDesC& aAlias ) |
|
1371 { |
|
1372 |
|
1373 if ( aAlias.Length() > 0 ) |
|
1374 { |
|
1375 HBufC* buf = TMmsGenUtils::GenerateAddressL( aRealAddress, aAlias ); |
|
1376 CleanupStack::PushL( buf ); |
|
1377 AddAddresseeL( buf->Des() ); |
|
1378 CleanupStack::PopAndDestroy( buf ); |
|
1379 } |
|
1380 else |
|
1381 { |
|
1382 AddAddresseeL( aRealAddress ); |
|
1383 } |
|
1384 } |
|
1385 |
|
1386 // --------------------------------------------------------- |
|
1387 // CMmsClientMtm::AddAddresseeL |
|
1388 // --------------------------------------------------------- |
|
1389 // |
|
1390 void CMmsClientMtm::AddAddresseeL( TMsvRecipientType aType, |
|
1391 const TDesC& aRealAddress ) |
|
1392 { |
|
1393 // Add to general list |
|
1394 // When no type is specified, the address will have type "to" |
|
1395 iAddresseeList->AppendL( aType, aRealAddress ); |
|
1396 |
|
1397 // Add to recipient list |
|
1398 iMmsHeaders->AddTypedAddresseeL( aRealAddress, aType ); |
|
1399 |
|
1400 } |
|
1401 |
|
1402 // --------------------------------------------------------- |
|
1403 // CMmsClientMtm::AddAddresseeL |
|
1404 // --------------------------------------------------------- |
|
1405 // |
|
1406 void CMmsClientMtm::AddAddresseeL( |
|
1407 TMsvRecipientType aType, |
|
1408 const TDesC& aRealAddress, |
|
1409 const TDesC& aAlias ) |
|
1410 { |
|
1411 |
|
1412 if ( aAlias.Length() > 0 ) |
|
1413 { |
|
1414 HBufC* buf = TMmsGenUtils::GenerateAddressL( aRealAddress, aAlias ); |
|
1415 CleanupStack::PushL( buf ); |
|
1416 AddAddresseeL(aType, buf->Des()); |
|
1417 CleanupStack::PopAndDestroy( buf ); |
|
1418 } |
|
1419 else |
|
1420 { |
|
1421 AddAddresseeL( aType, aRealAddress ); |
|
1422 } |
|
1423 } |
|
1424 |
|
1425 // --------------------------------------------------------- |
|
1426 // CMmsClientMtm::RemoveAddressee |
|
1427 // --------------------------------------------------------- |
|
1428 // |
|
1429 void CMmsClientMtm::RemoveAddressee( TInt aIndex ) |
|
1430 { |
|
1431 |
|
1432 if ( iAddresseeList->Count() > aIndex ) |
|
1433 { |
|
1434 // Delete from typed list |
|
1435 TPtrC address = (*iAddresseeList)[ aIndex ]; |
|
1436 iMmsHeaders->RemoveAddressee( address ); |
|
1437 // delete from untyped list |
|
1438 iAddresseeList->Delete( aIndex ); |
|
1439 } |
|
1440 |
|
1441 } |
|
1442 |
|
1443 // --------------------------------------------------------- |
|
1444 // CMmsClientMtm::SetSubjectL |
|
1445 // --------------------------------------------------------- |
|
1446 // |
|
1447 void CMmsClientMtm::SetSubjectL( const TDesC& aSubject ) |
|
1448 { |
|
1449 iMmsHeaders->SetSubjectL( aSubject ); |
|
1450 } |
|
1451 |
|
1452 // --------------------------------------------------------- |
|
1453 // CMmsClientMtm::SubjectL |
|
1454 // --------------------------------------------------------- |
|
1455 // |
|
1456 const TPtrC CMmsClientMtm::SubjectL() const |
|
1457 { |
|
1458 return iMmsHeaders->Subject(); |
|
1459 } |
|
1460 |
|
1461 // --------------------------------------------------------- |
|
1462 // CMmsClientMtm::AddAttachmentL |
|
1463 // --------------------------------------------------------- |
|
1464 // |
|
1465 void CMmsClientMtm::AddAttachmentL( const TDesC& aFilePath, |
|
1466 const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus ) |
|
1467 { |
|
1468 |
|
1469 TInt error = KErrNone; |
|
1470 TUint charset = aCharset; |
|
1471 RFile file; |
|
1472 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && charset == 0 ) |
|
1473 { |
|
1474 // try to recognize character set |
|
1475 // We trap the recognization process |
|
1476 // If cannot recognize, the result will be 0 and default to us-ascii |
|
1477 TRAP ( error, |
|
1478 { |
|
1479 error = file.Open( Session().FileSession(), aFilePath, |
|
1480 EFileRead|EFileShareReadersOnly ); |
|
1481 if ( error == KErrNone ) |
|
1482 { |
|
1483 CleanupClosePushL( file ); |
|
1484 charset = RecognizeCharSetL( file ); |
|
1485 CleanupStack::PopAndDestroy( &file ); // close file |
|
1486 } |
|
1487 } |
|
1488 ); |
|
1489 } |
|
1490 |
|
1491 // if the attachment character set is unicode, it should be converted to utf-8 |
|
1492 // (see MMS conformance document) |
|
1493 |
|
1494 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && |
|
1495 ( charset == KMmsUTF16 || |
|
1496 charset == KMmsIso10646Ucs2 || |
|
1497 charset == KMmsUTF16BE || |
|
1498 charset == KMmsUTF16LE ) ) |
|
1499 { |
|
1500 // If we have unicode character set, we must convert the file to utf8 |
|
1501 error = file.Open( Session().FileSession(), aFilePath, |
|
1502 EFileRead|EFileShareReadersOnly ); |
|
1503 if ( error == KErrNone ) |
|
1504 { |
|
1505 CleanupClosePushL( file ); |
|
1506 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
1507 CleanupStack::PushL( store ); |
|
1508 TMsvAttachmentId attaId = 0; |
|
1509 CMmsAttachmentHandler::CreateUTF8TextAttachmentFromFileL( |
|
1510 *store, attaId, file, Session().FileSession(), |
|
1511 Session().CurrentDriveL() ); |
|
1512 store->CommitL(); |
|
1513 CleanupStack::PopAndDestroy( store ); |
|
1514 CleanupStack::PopAndDestroy( &file ); // close file |
|
1515 } |
|
1516 TRequestStatus* status = &aStatus; |
|
1517 aStatus = KRequestPending; |
|
1518 User::RequestComplete( status, error ); |
|
1519 return; |
|
1520 } |
|
1521 else |
|
1522 { |
|
1523 // Disk space is checked in AddFilePathAttachmentL after everything has been initialized |
|
1524 AddFilePathAttachmentL( aFilePath, aMimeType, CMsvAttachment::EMsvFile, aStatus, charset ); |
|
1525 } |
|
1526 } |
|
1527 |
|
1528 // --------------------------------------------------------- |
|
1529 // CMmsClientMtm::AddAttachmentL |
|
1530 // --------------------------------------------------------- |
|
1531 // |
|
1532 void CMmsClientMtm::AddAttachmentL( RFile& aFile, const TDesC8& aMimeType, |
|
1533 TUint aCharset, TRequestStatus& aStatus ) |
|
1534 { |
|
1535 |
|
1536 TInt charset = aCharset; |
|
1537 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && charset == 0 ) |
|
1538 { |
|
1539 // If no character set defined for a plain text attachment |
|
1540 // we try to recognize the character set. |
|
1541 // But if recoginzation fails, we say 0 (us-ascii) |
|
1542 TRAP_IGNORE ( |
|
1543 { |
|
1544 charset = RecognizeCharSetL( aFile ); |
|
1545 }); |
|
1546 } |
|
1547 |
|
1548 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 ) |
|
1549 { |
|
1550 // If we have unicode character set, we must convert the file to utf8 |
|
1551 if ( ( charset == KMmsUTF16 ) || |
|
1552 ( charset == KMmsIso10646Ucs2 ) || |
|
1553 ( charset == KMmsUTF16BE ) || |
|
1554 ( charset == KMmsUTF16LE ) ) |
|
1555 { |
|
1556 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
1557 CleanupStack::PushL( store ); |
|
1558 TMsvAttachmentId attaId = 0; |
|
1559 CMmsAttachmentHandler::CreateUTF8TextAttachmentFromFileL( *store, |
|
1560 attaId, aFile, Session().FileSession(), |
|
1561 Session().CurrentDriveL() ); |
|
1562 store->CommitL(); |
|
1563 CleanupStack::PopAndDestroy( store ); // store |
|
1564 // We must close the file handle because the attachment manager will also |
|
1565 // close the handle. |
|
1566 // The open file handle is always closed unless the funtion leaves |
|
1567 aFile.Close(); |
|
1568 TRequestStatus* status = &aStatus; |
|
1569 aStatus = KRequestPending; |
|
1570 User::RequestComplete( status, KErrNone ); |
|
1571 return; |
|
1572 } |
|
1573 } |
|
1574 |
|
1575 if( !iAttaWaiter ) |
|
1576 { |
|
1577 iAttaWaiter = CMmsAttachmentWaiter::NewL(); |
|
1578 } |
|
1579 |
|
1580 // store must be the first item allocated because it is the last one to be popped |
|
1581 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
1582 CleanupStack::PushL( store ); |
|
1583 |
|
1584 CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
1585 CleanupStack::PushL( attachment ); |
|
1586 |
|
1587 CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL(); |
|
1588 CleanupStack::PushL( mimeHeaders ); |
|
1589 |
|
1590 // set the size |
|
1591 TInt size = 0; |
|
1592 User::LeaveIfError( aFile.Size( size ) ); |
|
1593 attachment->SetSize( size ); |
|
1594 |
|
1595 // set the mime-type if provided |
|
1596 if( aMimeType.Length() > 0 ) |
|
1597 { |
|
1598 attachment->SetMimeTypeL( aMimeType ); |
|
1599 TInt position = aMimeType.Find( KMmsSlash8 ); |
|
1600 if ( position > 0 ) |
|
1601 { |
|
1602 mimeHeaders->SetContentTypeL( aMimeType.Left( position ) ); |
|
1603 } |
|
1604 if ( position < aMimeType.Length() - 1 ) |
|
1605 { |
|
1606 mimeHeaders->SetContentSubTypeL( aMimeType.Mid( position + 1 ) ); |
|
1607 } |
|
1608 } |
|
1609 |
|
1610 TFileName fileName; |
|
1611 User::LeaveIfError( aFile.Name( fileName ) ); |
|
1612 attachment->SetAttachmentNameL( fileName ); |
|
1613 |
|
1614 mimeHeaders->SetSuggestedFilenameL( attachment->AttachmentName() ); |
|
1615 mimeHeaders->SetMimeCharset( charset ); |
|
1616 |
|
1617 size += KMmsIndexEntryExtra + mimeHeaders->Size(); |
|
1618 mimeHeaders->StoreL( *attachment ); |
|
1619 |
|
1620 // mime headers have been streamed to CMsvAttachment, they can go now |
|
1621 CleanupStack::PopAndDestroy( mimeHeaders ); |
|
1622 |
|
1623 // Check that sufficient disk space available |
|
1624 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
1625 &Session().FileSession(), |
|
1626 size, |
|
1627 iMessageDrive ) ) |
|
1628 { |
|
1629 CleanupStack::PopAndDestroy( attachment ); |
|
1630 User::Leave( KErrDiskFull ); |
|
1631 } |
|
1632 |
|
1633 // attachment is initialised, pass to the attachment manager |
|
1634 MMsvAttachmentManager& manager = store->AttachmentManagerL(); |
|
1635 if ( iAttaWaiter->IsActive() ) |
|
1636 { |
|
1637 // can't start an active operation because already active |
|
1638 User::Leave(KErrInUse); |
|
1639 } |
|
1640 manager.AddAttachmentL( aFile, attachment, iAttaWaiter->iStatus ); |
|
1641 CleanupStack::Pop( attachment ); // ownership passed to manager |
|
1642 // We cannot start waiting before we know that the function we are waiting for |
|
1643 // did not leave. If we become active, and the function leaves, we are in trouble |
|
1644 iAttaWaiter->StartWaitingL( aStatus, store, &manager ); |
|
1645 CleanupStack::Pop( store ); // ownership passed |
|
1646 } |
|
1647 |
|
1648 // --------------------------------------------------------- |
|
1649 // CMmsClientMtm::AddLinkedAttachmentL |
|
1650 // --------------------------------------------------------- |
|
1651 // |
|
1652 void CMmsClientMtm::AddLinkedAttachmentL( const TDesC& aFilePath, |
|
1653 const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus ) |
|
1654 { |
|
1655 TInt error = KErrNone; |
|
1656 TUint charset = aCharset; |
|
1657 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && aCharset == 0 ) |
|
1658 { |
|
1659 // try to recognize character set |
|
1660 // We trap the recognization process |
|
1661 // If cannot recognize, the result will be 0 and default to us-ascii |
|
1662 TRAP ( error, |
|
1663 { |
|
1664 RFile file; |
|
1665 error = file.Open( Session().FileSession(), aFilePath, |
|
1666 EFileRead|EFileShareReadersOnly); |
|
1667 if ( error == KErrNone ) |
|
1668 { |
|
1669 CleanupClosePushL( file ); |
|
1670 charset = RecognizeCharSetL( file ); |
|
1671 CleanupStack::PopAndDestroy( &file ); // close file |
|
1672 } |
|
1673 } |
|
1674 ); |
|
1675 } |
|
1676 // Linked files cannot be converted to utf8. They must be sent as is no |
|
1677 // matter what the character set is. |
|
1678 |
|
1679 // Disk space is checked in AddFilePathAttachmentL after everything has |
|
1680 // been initialized. |
|
1681 |
|
1682 |
|
1683 if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && |
|
1684 ( charset == KMmsUTF16 || |
|
1685 charset == KMmsIso10646Ucs2 || |
|
1686 charset == KMmsUTF16LE || |
|
1687 charset == KMmsUTF16BE ) ) |
|
1688 { |
|
1689 AddAttachmentL( aFilePath, aMimeType, charset, aStatus ); |
|
1690 } |
|
1691 else |
|
1692 { |
|
1693 AddFilePathAttachmentL( aFilePath, aMimeType, |
|
1694 CMsvAttachment::EMsvLinkedFile, aStatus, charset ); |
|
1695 } |
|
1696 } |
|
1697 |
|
1698 // --------------------------------------------------------- |
|
1699 // CMmsClientMtm::AddEntryAsAttachmentL |
|
1700 // --------------------------------------------------------- |
|
1701 // |
|
1702 void CMmsClientMtm::AddEntryAsAttachmentL( TMsvId /*aAttachmentId*/, |
|
1703 TRequestStatus& /*aStatus*/ ) |
|
1704 { |
|
1705 User::Leave( KErrNotSupported ); |
|
1706 } |
|
1707 |
|
1708 // --------------------------------------------------------- |
|
1709 // CMmsClientMtm::CreateAttachmentL |
|
1710 // --------------------------------------------------------- |
|
1711 // |
|
1712 void CMmsClientMtm::CreateAttachmentL( const TDesC& aFileName, |
|
1713 RFile& aAttachmentFile, const TDesC8& aMimeType, |
|
1714 TUint aCharset, TRequestStatus& aStatus ) |
|
1715 { |
|
1716 // Character set cannot be checked here because the file does not exist yet |
|
1717 // The caller gets an open file handle and is supposed to write data into |
|
1718 // the file. |
|
1719 if( !iAttaWaiter ) |
|
1720 { |
|
1721 iAttaWaiter = CMmsAttachmentWaiter::NewL(); |
|
1722 } |
|
1723 |
|
1724 // store must be the first item allocated because it is the last one to be popped |
|
1725 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
1726 CleanupStack::PushL( store ); |
|
1727 |
|
1728 CMsvAttachment* attachmentInfo = |
|
1729 CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
1730 CleanupStack::PushL( attachmentInfo ); |
|
1731 |
|
1732 CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL(); |
|
1733 CleanupStack::PushL( mimeHeaders ); |
|
1734 |
|
1735 attachmentInfo->SetAttachmentNameL( aFileName ); |
|
1736 |
|
1737 // set the mime-type if provided |
|
1738 if( aMimeType.Length() > 0 ) |
|
1739 { |
|
1740 attachmentInfo->SetMimeTypeL( aMimeType ); |
|
1741 TInt position = aMimeType.Find( KMmsSlash8 ); |
|
1742 if ( position > 0 ) |
|
1743 { |
|
1744 mimeHeaders->SetContentTypeL( aMimeType.Left( position ) ); |
|
1745 } |
|
1746 if ( position < aMimeType.Length() - 1 ) |
|
1747 { |
|
1748 mimeHeaders->SetContentSubTypeL( aMimeType.Mid( position + 1 ) ); |
|
1749 } |
|
1750 } |
|
1751 |
|
1752 // save the character set |
|
1753 mimeHeaders->SetMimeCharset( aCharset ); |
|
1754 |
|
1755 mimeHeaders->SetSuggestedFilenameL( attachmentInfo->AttachmentName() ); |
|
1756 |
|
1757 TInt size = 0; |
|
1758 size = KMmsIndexEntryExtra + mimeHeaders->Size(); |
|
1759 mimeHeaders->StoreL( *attachmentInfo ); |
|
1760 |
|
1761 // mime headers have been streamed to CMsvAttachment, they can go now |
|
1762 CleanupStack::PopAndDestroy( mimeHeaders ); |
|
1763 |
|
1764 // Check that sufficient disk space available |
|
1765 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
1766 &Session().FileSession(), |
|
1767 size, |
|
1768 iMessageDrive ) ) |
|
1769 { |
|
1770 CleanupStack::PopAndDestroy( attachmentInfo ); |
|
1771 User::Leave( KErrDiskFull ); |
|
1772 } |
|
1773 |
|
1774 MMsvAttachmentManager& manager = store->AttachmentManagerL(); |
|
1775 if ( iAttaWaiter->IsActive() ) |
|
1776 { |
|
1777 // can't start an active operation because already active |
|
1778 User::Leave(KErrInUse); |
|
1779 } |
|
1780 manager.CreateAttachmentL( aFileName, aAttachmentFile, attachmentInfo, |
|
1781 iAttaWaiter->iStatus ); |
|
1782 CleanupStack::Pop( attachmentInfo ); // ownership passed to manager |
|
1783 iAttaWaiter->StartWaitingL( aStatus, store, &manager ); |
|
1784 CleanupStack::Pop( store ); // ownership passed |
|
1785 } |
|
1786 |
|
1787 // --------------------------------------------------------- |
|
1788 // CMmsClientMtm::CancelAttachmentOperation |
|
1789 // --------------------------------------------------------- |
|
1790 // |
|
1791 void CMmsClientMtm::CancelAttachmentOperation() |
|
1792 { |
|
1793 |
|
1794 if ( iAttaWaiter ) |
|
1795 { |
|
1796 iAttaWaiter->Cancel(); |
|
1797 delete iAttaWaiter; |
|
1798 iAttaWaiter = NULL; |
|
1799 } |
|
1800 } |
|
1801 |
|
1802 // --------------------------------------------------------- |
|
1803 // CMmsClientMtm::CreateAttachment2L |
|
1804 // --------------------------------------------------------- |
|
1805 // |
|
1806 void CMmsClientMtm::CreateAttachment2L( |
|
1807 CMsvStore& aStore, |
|
1808 RFile& aFile, |
|
1809 TDesC8& aMimeType, |
|
1810 CMsvMimeHeaders& aMimeHeaders, |
|
1811 CMsvAttachment* aAttachmentInfo, |
|
1812 TMsvAttachmentId& aAttaId) |
|
1813 { |
|
1814 _LIT8( KMmsText, "text" ); |
|
1815 _LIT8( KMmsPlain, "plain" ); |
|
1816 |
|
1817 if ( ( aMimeType.CompareF( KMmsTextPlain ) == 0 || |
|
1818 ( aMimeHeaders.ContentType().CompareF( KMmsText ) == 0 && |
|
1819 aMimeHeaders.ContentSubType().CompareF( KMmsPlain ) == 0 ) ) && |
|
1820 aMimeHeaders.MimeCharset() == 0 ) |
|
1821 { |
|
1822 // If no character set defined for a plain text attachment |
|
1823 // we try to recognize the character set. |
|
1824 // But if recoginzation fails, we say 0 (us-ascii) |
|
1825 TInt charset = 0; |
|
1826 TRAP_IGNORE ( |
|
1827 { |
|
1828 charset = RecognizeCharSetL( aFile ); |
|
1829 }); |
|
1830 aMimeHeaders.SetMimeCharset( charset ); |
|
1831 } |
|
1832 |
|
1833 return CMmsAttachmentHandler::CreateAttachmentL( |
|
1834 aStore, |
|
1835 aFile, |
|
1836 Session().FileSession(), |
|
1837 Session().CurrentDriveL(), |
|
1838 aMimeType, |
|
1839 aMimeHeaders, |
|
1840 aAttachmentInfo, |
|
1841 aAttaId ); |
|
1842 |
|
1843 } |
|
1844 |
|
1845 // --------------------------------------------------------- |
|
1846 // CMmsClientMtm::CreateTextAttachmentL |
|
1847 // --------------------------------------------------------- |
|
1848 // |
|
1849 void CMmsClientMtm::CreateTextAttachmentL( |
|
1850 CMsvStore& aStore, |
|
1851 TMsvAttachmentId& aAttachmentId, |
|
1852 const TDesC& aText, |
|
1853 const TDesC& aFile, |
|
1854 TBool aConvertParagraphSeparator ) |
|
1855 { |
|
1856 |
|
1857 CMmsAttachmentHandler::CreateTextAttachmentL( aStore, |
|
1858 aAttachmentId, |
|
1859 aText, |
|
1860 aFile, |
|
1861 Session().FileSession(), |
|
1862 Session().CurrentDriveL(), |
|
1863 aConvertParagraphSeparator ); |
|
1864 |
|
1865 } |
|
1866 |
|
1867 // --------------------------------------------------------- |
|
1868 // CMmsClientMtm::CreateMessageL |
|
1869 // --------------------------------------------------------- |
|
1870 // |
|
1871 void CMmsClientMtm::CreateMessageL( |
|
1872 TMsvId aServiceId ) |
|
1873 { |
|
1874 // Check that sufficient disk space available |
|
1875 // for index entry |
|
1876 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
1877 &Session().FileSession(), |
|
1878 KMmsIndexEntryExtra, |
|
1879 iMessageDrive ) ) |
|
1880 { |
|
1881 // we use standard error code here |
|
1882 User::Leave( KErrDiskFull ); |
|
1883 } |
|
1884 |
|
1885 // just call the base class function |
|
1886 CBaseMtm::CreateMessageL( aServiceId ); |
|
1887 |
|
1888 iMmsHeaders->Reset( iMmsSettings ); |
|
1889 } |
|
1890 |
|
1891 // --------------------------------------------------------- |
|
1892 // CMmsClientMtm::BioTypeChangedL |
|
1893 // --------------------------------------------------------- |
|
1894 // |
|
1895 void CMmsClientMtm::BioTypeChangedL( TUid /*aBioTypeUid*/ ) |
|
1896 { |
|
1897 // Do nothing. MMS does not support BIO type. |
|
1898 } |
|
1899 |
|
1900 // --------------------------------------------------------- |
|
1901 // CMmsClientMtm::DefaultServiceL |
|
1902 // --------------------------------------------------------- |
|
1903 // |
|
1904 TMsvId CMmsClientMtm::DefaultServiceL() const |
|
1905 { |
|
1906 // Override base implementation so that we always use MMS service |
|
1907 // even when called by Postcard or Audio Message which have different MTM tyoe |
|
1908 |
|
1909 if ( iServiceId != KMsvNullIndexEntryId ) |
|
1910 { |
|
1911 return iServiceId; |
|
1912 } |
|
1913 |
|
1914 // Create a new entry, showing invisible entries (because the service entry is invisible) |
|
1915 |
|
1916 TMsvSelectionOrdering ordering( KMsvNoGrouping, EMsvSortByNone, ETrue ); |
|
1917 CMsvEntry* entry = CMsvEntry::NewL( iOwnSession, KMsvRootIndexEntryId, ordering ); |
|
1918 CleanupStack::PushL( entry ); |
|
1919 |
|
1920 CMsvEntrySelection *sel=entry->ChildrenWithMtmL( KUidMsgTypeMultimedia ); |
|
1921 CleanupStack::PushL( sel ); |
|
1922 if( sel->Count() == 0 ) |
|
1923 { |
|
1924 User::Leave(KErrNotFound); |
|
1925 } |
|
1926 TMsvId service=sel->At( 0 ); |
|
1927 CleanupStack::PopAndDestroy( sel ); |
|
1928 CleanupStack::PopAndDestroy( entry ); |
|
1929 return service; |
|
1930 } |
|
1931 |
|
1932 // --------------------------------------------------------- |
|
1933 // CMmsClientMtm::RemoveDefaultServiceL |
|
1934 // --------------------------------------------------------- |
|
1935 // |
|
1936 void CMmsClientMtm::RemoveDefaultServiceL() |
|
1937 { |
|
1938 // not supported |
|
1939 } |
|
1940 |
|
1941 // --------------------------------------------------------- |
|
1942 // CMmsClientMtm::ChangeDefaultServiceL |
|
1943 // --------------------------------------------------------- |
|
1944 // |
|
1945 void CMmsClientMtm::ChangeDefaultServiceL( const TMsvId& /*aService*/ ) |
|
1946 { |
|
1947 // not supported |
|
1948 } |
|
1949 |
|
1950 // --------------------------------------------------------- |
|
1951 // CMmsClientMtm::QueryCapability |
|
1952 // --------------------------------------------------------- |
|
1953 // |
|
1954 TInt CMmsClientMtm::QueryCapability( |
|
1955 TUid aCapability, |
|
1956 TInt& aResponse ) |
|
1957 { |
|
1958 TInt error = KErrNone; |
|
1959 switch ( aCapability.iUid ) |
|
1960 { |
|
1961 // Supported: |
|
1962 case KUidMtmQueryMaxTotalMsgSizeValue: |
|
1963 aResponse = KMaxTInt; |
|
1964 break; |
|
1965 case KUidMsvMtmQueryEditorUidValue: |
|
1966 aResponse = KUidMsgMmsEditor; |
|
1967 break; |
|
1968 case KUidMtmQueryMaxRecipientCountValue: |
|
1969 // According to conformance document we must support at least 20 |
|
1970 aResponse = -1; // unlimited number |
|
1971 break; |
|
1972 case KUidMtmQuerySendAsMessageSendSupportValue: |
|
1973 aResponse = ETrue; |
|
1974 break; |
|
1975 case KUidMtmQuerySupportSubjectValue: |
|
1976 case KUidMtmQuerySupportAttachmentsValue: |
|
1977 case KUidMtmQueryCanSendMsgValue: |
|
1978 case KUidMtmQueryCanReceiveMsgValue: |
|
1979 case KUidMtmQuerySupportsRecipientTypeValue: |
|
1980 // returns KErrNone |
|
1981 break; |
|
1982 // All others - Not Supported: |
|
1983 default: |
|
1984 error = KErrNotSupported; |
|
1985 break; |
|
1986 } |
|
1987 return error; |
|
1988 |
|
1989 } |
|
1990 |
|
1991 // --------------------------------------------------------- |
|
1992 // CClientMtm::InvokeSyncFunctionL |
|
1993 // --------------------------------------------------------- |
|
1994 // |
|
1995 void CMmsClientMtm::InvokeSyncFunctionL( |
|
1996 TInt /*aFunctionId*/, |
|
1997 const CMsvEntrySelection& /*aSelection*/, |
|
1998 TDes8& /*aParameter*/ ) |
|
1999 { |
|
2000 |
|
2001 User::Leave( KErrNotSupported ); |
|
2002 |
|
2003 } |
|
2004 |
|
2005 // --------------------------------------------------------- |
|
2006 // CMmsClientMtm::InvokeAsyncFunctionL |
|
2007 // --------------------------------------------------------- |
|
2008 // |
|
2009 CMsvOperation* CMmsClientMtm::InvokeAsyncFunctionL( |
|
2010 TInt aFunctionId, |
|
2011 const CMsvEntrySelection& aSelection, |
|
2012 TDes8& aParameter, |
|
2013 TRequestStatus& aCompletionStatus ) |
|
2014 { |
|
2015 |
|
2016 CMsvOperation* op = NULL; |
|
2017 |
|
2018 if ( aSelection.Count() == 0 ) |
|
2019 { |
|
2020 User::Leave( KErrArgument ); |
|
2021 } |
|
2022 |
|
2023 // make a copy of the selection just in case |
|
2024 CMsvEntrySelection* selection = aSelection.CopyL(); |
|
2025 CleanupStack::PushL( selection ); |
|
2026 |
|
2027 // Change service id to related id |
|
2028 // for the scheduled commands |
|
2029 CMsvEntry* cEntry = NULL; |
|
2030 TInt error = KErrNone; |
|
2031 |
|
2032 if ( aFunctionId == EMmsScheduledSend || |
|
2033 aFunctionId == EMmsScheduledReceive || |
|
2034 aFunctionId == EMmsScheduledReceiveForced || |
|
2035 aFunctionId == EMmsDeleteSchedule || |
|
2036 aFunctionId == EMmsScheduledForward || |
|
2037 aFunctionId == EMmsScheduledNotificationDelete || |
|
2038 aFunctionId == KMTMStandardFunctionsSendMessage ) |
|
2039 { |
|
2040 TInt j = 0; |
|
2041 TInt i; |
|
2042 cEntry = Session().GetEntryL( KMsvRootIndexEntryId ); |
|
2043 CleanupStack::PushL( cEntry ); |
|
2044 |
|
2045 if ( aSelection.At( 0 ) == iServiceId ) |
|
2046 { |
|
2047 // skip service |
|
2048 j++; |
|
2049 } |
|
2050 |
|
2051 for ( i = aSelection.Count() - 1; i >=j; i-- ) |
|
2052 { |
|
2053 TRAP( error, |
|
2054 { |
|
2055 cEntry->SetEntryL( aSelection.At( i ) ); |
|
2056 TMsvEntry entry = cEntry->Entry(); |
|
2057 // check first to be sure you don't lose the original |
|
2058 // service id |
|
2059 if ( entry.iServiceId != KMsvLocalServiceIndexEntryId ) |
|
2060 { |
|
2061 entry.iRelatedId = entry.iServiceId; |
|
2062 } |
|
2063 entry.iServiceId = KMsvLocalServiceIndexEntryId; |
|
2064 cEntry->ChangeL( entry ); |
|
2065 }); |
|
2066 if ( error == KErrNotFound ) |
|
2067 { |
|
2068 selection->Delete( i ); |
|
2069 } |
|
2070 } |
|
2071 |
|
2072 CleanupStack::PopAndDestroy( cEntry ); |
|
2073 cEntry = NULL; |
|
2074 } |
|
2075 |
|
2076 if ( aFunctionId == KMTMStandardFunctionsSendMessage && selection->Count() > 0 ) |
|
2077 { |
|
2078 // This is the SendAs send command. Ignore parameter |
|
2079 TCommandParameters parameters; // initialized to zero |
|
2080 TCommandParametersBuf paramPack( parameters ); |
|
2081 // Move the messages to OUTBOX synchronously |
|
2082 cEntry = Session().GetEntryL( KMsvLocalServiceIndexEntryIdValue ); |
|
2083 CleanupStack::PushL( cEntry ); |
|
2084 cEntry->SetEntryL( selection->At( 0 ) ); |
|
2085 TMsvId currentParent = cEntry->Entry().Parent(); |
|
2086 TMsvLocalOperationProgress progress; |
|
2087 if ( currentParent != KMsvGlobalOutBoxIndexEntryId ) |
|
2088 { |
|
2089 cEntry->MoveL( *selection, KMsvGlobalOutBoxIndexEntryId, progress ); |
|
2090 } |
|
2091 CleanupStack::PopAndDestroy( cEntry ); |
|
2092 cEntry = NULL; |
|
2093 } |
|
2094 |
|
2095 if ( selection->Count() == 0 ) |
|
2096 { |
|
2097 // we are given a selection of entries that were not found. |
|
2098 User::Leave( KErrNotFound ); |
|
2099 } |
|
2100 |
|
2101 // |
|
2102 // Pass all commands onto the server MTM |
|
2103 // |
|
2104 if ( aFunctionId == KMTMStandardFunctionsSendMessage ) |
|
2105 { |
|
2106 // no need to put op on cleanup stack because |
|
2107 // its ownership will be transferred to caller in a moment |
|
2108 op = CMmsSendMessageOperation::NewL( Session(), |
|
2109 *selection, |
|
2110 aParameter, |
|
2111 aCompletionStatus ); |
|
2112 } |
|
2113 else |
|
2114 { |
|
2115 op = Session().TransferCommandL( |
|
2116 *selection, aFunctionId, aParameter, aCompletionStatus ); |
|
2117 } |
|
2118 CleanupStack::PopAndDestroy( selection ); |
|
2119 return op; |
|
2120 } |
|
2121 |
|
2122 // --------------------------------------------------------- |
|
2123 // CMmsClientMtm::ListNotificationsInInboxL |
|
2124 // --------------------------------------------------------- |
|
2125 // |
|
2126 CMsvEntrySelection* CMmsClientMtm::ListNotificationsInInboxL() |
|
2127 { |
|
2128 CMsvEntry* cEntry = Session().GetEntryL( KMsvGlobalInBoxIndexEntryId ); |
|
2129 CleanupStack::PushL( cEntry ); |
|
2130 |
|
2131 CMsvEntrySelection* notifications = |
|
2132 cEntry->ChildrenWithMtmL( KUidMsgMMSNotification ); |
|
2133 CleanupStack::PushL( notifications ); |
|
2134 |
|
2135 // Count only notifications that are free for a new operation |
|
2136 for ( TInt i = notifications->Count() - 1 ; i >= 0; i-- ) |
|
2137 { |
|
2138 TMsvId notifId = notifications->At( i ); |
|
2139 cEntry->SetEntryL( notifId ); |
|
2140 |
|
2141 TMsvEntry tEntry = cEntry->Entry(); |
|
2142 if ( tEntry.iMtmData2 & KMmsNewOperationForbidden ) |
|
2143 { |
|
2144 // Delete notification from the notifications array. |
|
2145 notifications->Delete( i ); |
|
2146 } |
|
2147 } |
|
2148 |
|
2149 notifications->Compress(); |
|
2150 CleanupStack::Pop( notifications ); // ownership transferred to caller |
|
2151 CleanupStack::PopAndDestroy( cEntry ); |
|
2152 return notifications; |
|
2153 } |
|
2154 |
|
2155 // --------------------------------------------------------- |
|
2156 // CMmsClientMtm::ContextEntrySwitched |
|
2157 // --------------------------------------------------------- |
|
2158 // |
|
2159 void CMmsClientMtm::ContextEntrySwitched() |
|
2160 { |
|
2161 // Context change notification. |
|
2162 // Reset data. |
|
2163 |
|
2164 // Note: Body text reset would be here if supported. |
|
2165 |
|
2166 iAddresseeList->Reset(); |
|
2167 iMmsHeaders->Reset( iMmsSettings ); |
|
2168 iFetchAll = EFalse; |
|
2169 iFetchOverride = ETrue; |
|
2170 iAttributes->Reset(); |
|
2171 } |
|
2172 |
|
2173 // --------------------------------------------------------- |
|
2174 // CMmsClientMtm::HandleEntryEventL |
|
2175 // --------------------------------------------------------- |
|
2176 // |
|
2177 void CMmsClientMtm::HandleEntryEventL( |
|
2178 TMsvEntryEvent /*aEvent*/, |
|
2179 TAny* /*arg1*/, |
|
2180 TAny* /*arg2*/, |
|
2181 TAny* /*arg3*/ ) |
|
2182 { |
|
2183 // No operation |
|
2184 } |
|
2185 |
|
2186 // --------------------------------------------------------- |
|
2187 // CMmsClientMtm::ConstructL |
|
2188 // --------------------------------------------------------- |
|
2189 // |
|
2190 void CMmsClientMtm::ConstructL() |
|
2191 { |
|
2192 // First loading settings |
|
2193 iMmsSettings = CMmsSettings::NewL(); |
|
2194 iMmsSettings->LoadSettingsL(); |
|
2195 // Get the base values to detect changes |
|
2196 iHomeMode = iMmsSettings->ReceivingModeHome(); |
|
2197 iRoamingMode = iMmsSettings->ReceivingModeForeign(); |
|
2198 iAccessPointCount = iMmsSettings->AccessPointCount(); |
|
2199 |
|
2200 iMessageDrive = EDriveC; |
|
2201 TInt error = KErrNone; |
|
2202 |
|
2203 TRAP ( error, { iMessageDrive = Session().CurrentDriveL(); } ); |
|
2204 |
|
2205 if ( error != KErrNone ) |
|
2206 { |
|
2207 // if cannot ask, use default |
|
2208 iMessageDrive = EDriveC; |
|
2209 } |
|
2210 |
|
2211 // if no service, creating one |
|
2212 TMsvId tempServiceId = KMsvNullIndexEntryId; |
|
2213 TRAP( error, tempServiceId = DefaultServiceL() ) |
|
2214 { |
|
2215 if ( error == KErrNotFound ) |
|
2216 { |
|
2217 tempServiceId = KMsvNullIndexEntryId; |
|
2218 } |
|
2219 } |
|
2220 |
|
2221 // service id is set after call to DefaultServiceL(), otherwise |
|
2222 // DefaultServiceL() will just return iServiceId |
|
2223 iServiceId = iMmsSettings->Service(); |
|
2224 if ( iServiceId == KMsvNullIndexEntryId || |
|
2225 iServiceId != tempServiceId ) |
|
2226 { |
|
2227 // If there was no default service, a new one must be created. |
|
2228 |
|
2229 // If the service id saved in the settings differs from |
|
2230 // the one read from disk, we call create service. |
|
2231 // The create service function should check the actual |
|
2232 // values of MMS service and MMS private folders and |
|
2233 // ensure that the values in central repository and mail store match. |
|
2234 |
|
2235 // Check that sufficient disk space available |
|
2236 // for service entry |
|
2237 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
2238 &Session().FileSession(), |
|
2239 KMmsIndexEntryExtra, // Service entry has no extra data |
|
2240 iMessageDrive ) ) |
|
2241 { |
|
2242 // we use standard error code here |
|
2243 User::Leave( KErrDiskFull ); |
|
2244 } |
|
2245 // creates new service entry + notification and mmbox folder entries |
|
2246 iMmsSettings->CreateNewServiceL( Session() ); |
|
2247 // Save settings is not needed - service creation saves the settings. |
|
2248 iServiceId = iMmsSettings->Service(); |
|
2249 } |
|
2250 |
|
2251 iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() ); |
|
2252 |
|
2253 // Address alias separators no longer read from resoure. |
|
2254 // Standard MIME separators < and > always used. |
|
2255 |
|
2256 iAttributes = new(ELeave) CDesCArrayFlat( KMmsAttributeArrayGranularity ); |
|
2257 |
|
2258 // Set the original context to the service entry |
|
2259 SwitchCurrentEntryL( iServiceId ); |
|
2260 |
|
2261 } |
|
2262 |
|
2263 // --------------------------------------------------------- |
|
2264 // CMmsClientMtm::ValidateService |
|
2265 // --------------------------------------------------------- |
|
2266 // |
|
2267 TInt CMmsClientMtm::ValidateService( TMsvId aServiceId ) |
|
2268 { |
|
2269 TInt error = KErrNone; |
|
2270 // There should be only one service, |
|
2271 // and it must match with the one that is in settings |
|
2272 if( aServiceId != iMmsSettings->Service() ) |
|
2273 { |
|
2274 return KErrNotFound; |
|
2275 } |
|
2276 |
|
2277 // Check settings |
|
2278 error = iMmsSettings->ValidateSettings(); |
|
2279 return error; |
|
2280 } |
|
2281 |
|
2282 // --------------------------------------------------------- |
|
2283 // CMmsClientMtm::MessageSize |
|
2284 // --------------------------------------------------------- |
|
2285 // |
|
2286 TInt32 CMmsClientMtm::MessageSize() |
|
2287 { |
|
2288 // First we should assert that iMsvEntry is not NULL, and panic, if it is |
|
2289 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet )); |
|
2290 TUint size = 0; |
|
2291 TRAP_IGNORE({size = AttachmentsSizeL() + iMmsHeaders->Size();} ); |
|
2292 return size; |
|
2293 } |
|
2294 |
|
2295 // --------------------------------------------------------- |
|
2296 // CMmsClientMtm::SetMessageDescriptionL |
|
2297 // --------------------------------------------------------- |
|
2298 // |
|
2299 void CMmsClientMtm::SetMessageDescriptionL( const TDesC& aText ) |
|
2300 { |
|
2301 // First we should assert that iMsvEntry is not NULL, and panic, if it is |
|
2302 __ASSERT_DEBUG( iMsvEntry, gPanic( EMmsNoCMsvEntrySet )); |
|
2303 TMsvEntry entry = iMsvEntry->Entry(); |
|
2304 entry.iDescription.Set( aText ); |
|
2305 iMsvEntry->ChangeL( entry ); |
|
2306 } |
|
2307 |
|
2308 // --------------------------------------------------------- |
|
2309 // CMmsClientMtm::AddAttributeL |
|
2310 // --------------------------------------------------------- |
|
2311 // |
|
2312 void CMmsClientMtm::AddAttributeL( const TDesC& aName, const TDesC& aValue ) |
|
2313 { |
|
2314 if ( aName.Length() == 0 || aValue.Length() == 0 ) |
|
2315 { |
|
2316 User::Leave( KErrArgument ); |
|
2317 } |
|
2318 TMmsGenUtils::AddAttributeL( aName, aValue, *iAttributes ); |
|
2319 } |
|
2320 |
|
2321 // --------------------------------------------------------- |
|
2322 // CMmsClientMtm::GetAttributeL |
|
2323 // --------------------------------------------------------- |
|
2324 // |
|
2325 TPtrC CMmsClientMtm::GetAttributeL( const TDesC& aName ) |
|
2326 { |
|
2327 if ( aName.Length() == 0 ) |
|
2328 { |
|
2329 User::Leave( KErrArgument ); |
|
2330 } |
|
2331 return TMmsGenUtils::GetAttributeL( aName, *iAttributes ); |
|
2332 } |
|
2333 |
|
2334 // --------------------------------------------------------- |
|
2335 // CMmsClientMtm::FindAttribute |
|
2336 // --------------------------------------------------------- |
|
2337 // |
|
2338 TBool CMmsClientMtm::FindAttribute( const TDesC& aName ) |
|
2339 { |
|
2340 if ( aName.Length() == 0 ) |
|
2341 { |
|
2342 return EFalse; |
|
2343 } |
|
2344 return TMmsGenUtils::FindAttribute( aName, *iAttributes ); |
|
2345 } |
|
2346 |
|
2347 // --------------------------------------------------------- |
|
2348 // CMmsClientMtm::DeleteAttribute |
|
2349 // --------------------------------------------------------- |
|
2350 // |
|
2351 void CMmsClientMtm::DeleteAttribute( const TDesC& aName ) |
|
2352 { |
|
2353 if ( aName.Length() == 0 ) |
|
2354 { |
|
2355 return; |
|
2356 } |
|
2357 TMmsGenUtils::DeleteAttribute( aName, *iAttributes ); |
|
2358 } |
|
2359 |
|
2360 // --------------------------------------------------------- |
|
2361 // CMmsClientMtm::ResetAttributes |
|
2362 // --------------------------------------------------------- |
|
2363 // |
|
2364 void CMmsClientMtm::ResetAttributes() |
|
2365 { |
|
2366 iAttributes->Reset(); |
|
2367 } |
|
2368 |
|
2369 // --------------------------------------------------------- |
|
2370 // CMmsClientMtm::BuildAddresseeListL |
|
2371 // --------------------------------------------------------- |
|
2372 // |
|
2373 void CMmsClientMtm::BuildAddresseeListL() |
|
2374 { |
|
2375 |
|
2376 iAddresseeList->Reset(); |
|
2377 |
|
2378 const CDesCArray& array1 = iMmsHeaders->ToRecipients(); |
|
2379 const CDesCArray& array2 = iMmsHeaders->CcRecipients(); |
|
2380 const CDesCArray& array3 = iMmsHeaders->BccRecipients(); |
|
2381 |
|
2382 BuildAddresseeListL( array1, EMsvRecipientTo ); |
|
2383 BuildAddresseeListL( array2, EMsvRecipientCc ); |
|
2384 BuildAddresseeListL( array3, EMsvRecipientBcc ); |
|
2385 |
|
2386 } |
|
2387 |
|
2388 // --------------------------------------------------------- |
|
2389 // CMmsClientMtm::BuildAddresseeListL |
|
2390 // --------------------------------------------------------- |
|
2391 // |
|
2392 void CMmsClientMtm::BuildAddresseeListL( |
|
2393 const CDesCArray& aArray, TMsvRecipientType aValue ) |
|
2394 { |
|
2395 |
|
2396 TInt size; |
|
2397 size = aArray.Count(); |
|
2398 for ( TInt i=0; i < size; i++ ) |
|
2399 { |
|
2400 iAddresseeList->AppendL( aValue, aArray[i] ); |
|
2401 } |
|
2402 } |
|
2403 |
|
2404 // --------------------------------------------------------- |
|
2405 // CMmsClientMtm::AttachmentsSizeL |
|
2406 // --------------------------------------------------------- |
|
2407 // |
|
2408 TInt32 CMmsClientMtm::AttachmentsSizeL() |
|
2409 { |
|
2410 TInt32 size = 0; |
|
2411 // We need to have store. If the caller is keeping edit store open, |
|
2412 // this function leaves. |
|
2413 // That makes sense, because in that case the user might have |
|
2414 // uncommitted attachments, and the total size would be incorrect anyway. |
|
2415 CMsvStore* store = iMsvEntry->ReadStoreL(); |
|
2416 CleanupStack::PushL( store ); |
|
2417 size = CMmsAttachmentHandler::AttachmentsSizeL( *store ); |
|
2418 CleanupStack::PopAndDestroy( store ); |
|
2419 store = NULL; |
|
2420 return size; |
|
2421 } |
|
2422 |
|
2423 // --------------------------------------------------------- |
|
2424 // CMmsClientMtm::ListMmsFolderNotificationsL() |
|
2425 // --------------------------------------------------------- |
|
2426 // |
|
2427 CMsvEntrySelection* CMmsClientMtm::ListMmsFolderNotificationsL() |
|
2428 { |
|
2429 |
|
2430 // list notifications in private invisible folder |
|
2431 |
|
2432 TMsvId notificationParent = iMmsSettings->NotificationFolder(); |
|
2433 |
|
2434 CMsvEntrySelection* notifications = NULL; |
|
2435 if ( notificationParent == KMsvNullIndexEntryId ) |
|
2436 { |
|
2437 notifications = new ( ELeave ) CMsvEntrySelection(); |
|
2438 return notifications; // empty selection |
|
2439 } |
|
2440 |
|
2441 CMsvEntry* cEntry = NULL; |
|
2442 cEntry = Session().GetEntryL( notificationParent ); |
|
2443 CleanupStack::PushL( cEntry ); |
|
2444 |
|
2445 // show invisible entries |
|
2446 cEntry->SetSortTypeL( TMsvSelectionOrdering( KMsvNoGrouping, |
|
2447 EMsvSortByNone, ETrue ) ); |
|
2448 notifications = cEntry->ChildrenWithMtmL( KUidMsgTypeMultimedia ); |
|
2449 CleanupStack::PushL( notifications ); |
|
2450 |
|
2451 // strip off stuff other than notifications |
|
2452 // We are handling the invisible MMS folder now |
|
2453 // There may be delivery reports or binary notifications besides |
|
2454 // the normal notifications |
|
2455 |
|
2456 for ( TInt i = notifications->Count() - 1; i >= 0; i-- ) |
|
2457 { |
|
2458 cEntry->SetEntryL( notifications->At( i )); |
|
2459 |
|
2460 TMsvEntry myEntry = cEntry->Entry(); |
|
2461 if ( !( ( myEntry.iMtmData1 & KMmsMessageTypeMask ) == |
|
2462 KMmsMessageMNotificationInd ) ) |
|
2463 { |
|
2464 // this is not notification |
|
2465 notifications->Delete( i ); |
|
2466 } |
|
2467 } |
|
2468 |
|
2469 notifications->Compress(); |
|
2470 |
|
2471 CleanupStack::Pop( notifications ); // ownership transferred to caller |
|
2472 CleanupStack::PopAndDestroy( cEntry ); |
|
2473 |
|
2474 return notifications; |
|
2475 |
|
2476 } |
|
2477 |
|
2478 // --------------------------------------------------------- |
|
2479 // CMmsClientMtm::ListInboxNotificationsL() |
|
2480 // --------------------------------------------------------- |
|
2481 // |
|
2482 CMsvEntrySelection* CMmsClientMtm::ListInboxNotificationsL() |
|
2483 { |
|
2484 CMsvEntry* cEntry = NULL; |
|
2485 cEntry = Session().GetEntryL( KMsvGlobalInBoxIndexEntryId ); |
|
2486 CleanupStack::PushL( cEntry ); |
|
2487 |
|
2488 CMsvEntrySelection* notifications = new( ELeave )CMsvEntrySelection; |
|
2489 CleanupStack::PushL( notifications ); |
|
2490 |
|
2491 // Notifications from inbox - but not in offline state if the user has not |
|
2492 // initiated the fetch (iFetchOeverride = ETrue) |
|
2493 // If the user initiates the fetch in offline mode, the entry goes to |
|
2494 // failed state because the use must see why the fetching fails. |
|
2495 // CMmsNotificationClientMtm overrides the FetchAllL function so that |
|
2496 // we should get here only when the receiving mode changes. |
|
2497 if ( iFetchOverride || TMmsGenUtils::NetworkOperationsAllowed() ) |
|
2498 { |
|
2499 CMsvEntrySelection* notificationsInInbox = ListNotificationsInInboxL(); |
|
2500 CleanupStack::PushL( notificationsInInbox ); |
|
2501 |
|
2502 // The readOnly flag has to be set on for notifications in inbox |
|
2503 // in order to schedule notifications. |
|
2504 for ( TInt j = notificationsInInbox->Count() - 1; j >= 0; j-- ) |
|
2505 { |
|
2506 cEntry->SetEntryL( notificationsInInbox->At( j ) ); |
|
2507 TMsvEntry entry = cEntry->Entry(); |
|
2508 entry.SetReadOnly( EFalse ); |
|
2509 cEntry->ChangeL( entry ); |
|
2510 |
|
2511 notifications->AppendL( notificationsInInbox->At( j ) ); |
|
2512 } |
|
2513 |
|
2514 CleanupStack::PopAndDestroy( notificationsInInbox ); |
|
2515 } |
|
2516 |
|
2517 CleanupStack::Pop( notifications ); // ownership transferred to caller |
|
2518 CleanupStack::PopAndDestroy( cEntry ); |
|
2519 |
|
2520 return notifications; |
|
2521 } |
|
2522 |
|
2523 // --------------------------------------------------------- |
|
2524 // CMmsClientMtm::FetchAllFromInboxL |
|
2525 // --------------------------------------------------------- |
|
2526 // |
|
2527 CMsvOperation* CMmsClientMtm::FetchAllFromInboxL( TRequestStatus& aCompletionStatus, |
|
2528 TBool aForced ) |
|
2529 { |
|
2530 |
|
2531 iFetchOverride = aForced; |
|
2532 |
|
2533 CMsvEntrySelection* selection = ListInboxNotificationsL(); |
|
2534 CleanupStack::PushL( selection ); |
|
2535 |
|
2536 if ( selection->Count() == 0 ) |
|
2537 { |
|
2538 CleanupStack::PopAndDestroy( selection ); |
|
2539 TPckgC < TMsvId > progress = 0; |
|
2540 aCompletionStatus = KRequestPending; |
|
2541 return CMsvCompletedOperation::NewL( Session(), Type(), progress, |
|
2542 KMsvLocalServiceIndexEntryId, aCompletionStatus ); |
|
2543 } |
|
2544 |
|
2545 TCommandParameters parameters; // initialized to zero |
|
2546 TCommandParametersBuf paramPack( parameters ); |
|
2547 |
|
2548 CMsvOperation* op = NULL; |
|
2549 if ( iFetchOverride ) |
|
2550 { |
|
2551 op = InvokeAsyncFunctionL( |
|
2552 EMmsScheduledReceiveForced, |
|
2553 *selection, |
|
2554 paramPack, |
|
2555 aCompletionStatus ); |
|
2556 } |
|
2557 else |
|
2558 { |
|
2559 op = InvokeAsyncFunctionL( |
|
2560 EMmsScheduledReceive, |
|
2561 *selection, |
|
2562 paramPack, |
|
2563 aCompletionStatus ); |
|
2564 // reset override to default value |
|
2565 iFetchOverride = ETrue; |
|
2566 } |
|
2567 |
|
2568 CleanupStack::PopAndDestroy( selection ); |
|
2569 return op; |
|
2570 } |
|
2571 |
|
2572 |
|
2573 // --------------------------------------------------------- |
|
2574 // CMmsClientMtm::ConvertUTCDateToLocal |
|
2575 // --------------------------------------------------------- |
|
2576 // |
|
2577 /* |
|
2578 TInt64 CMmsClientMtm::ConvertUTCDateToLocal( TInt64 aDate ) const |
|
2579 { |
|
2580 |
|
2581 TLocale locale; |
|
2582 locale.Refresh(); |
|
2583 TInt64 localDate; |
|
2584 TTimeIntervalSeconds universalTimeOffset( locale.UniversalTimeOffset() ); |
|
2585 |
|
2586 localDate = aDate + universalTimeOffset.Int(); |
|
2587 |
|
2588 if ( locale.QueryHomeHasDaylightSavingOn() ) |
|
2589 { |
|
2590 TTimeIntervalSeconds daylightSaving( 60 * 60 ); |
|
2591 localDate += daylightSaving.Int(); |
|
2592 } |
|
2593 |
|
2594 return localDate; |
|
2595 |
|
2596 } |
|
2597 */ |
|
2598 |
|
2599 // --------------------------------------------------------- |
|
2600 // CMmsClientMtm::FindInRecipientL |
|
2601 // --------------------------------------------------------- |
|
2602 // |
|
2603 TBool CMmsClientMtm::FindInRecipientL( |
|
2604 const TDesC& aTextToFind, |
|
2605 TMsvPartList aPartlist, |
|
2606 const CDesCArray& aRecipients, |
|
2607 CMsvFindText& aFindText ) |
|
2608 { |
|
2609 TInt count = aRecipients.Count(); |
|
2610 TBool found = EFalse; |
|
2611 for (TInt i=0; i < count; i++ ) |
|
2612 { |
|
2613 // Check alias and real address parts |
|
2614 // separately. Otherwise separator character could |
|
2615 // spoil the check. |
|
2616 if ( aFindText.FindTextL( aTextToFind, |
|
2617 TMmsGenUtils::Alias( aRecipients[i] ), aPartlist ) ) |
|
2618 { |
|
2619 found = ETrue; |
|
2620 break; |
|
2621 } |
|
2622 else if ( aFindText.FindTextL( aTextToFind, |
|
2623 TMmsGenUtils::PureAddress( aRecipients[i] ), aPartlist ) ) |
|
2624 { |
|
2625 found = ETrue; |
|
2626 break; |
|
2627 } |
|
2628 else |
|
2629 { |
|
2630 // keep LINT happy |
|
2631 } |
|
2632 } |
|
2633 return found; |
|
2634 } |
|
2635 |
|
2636 // --------------------------------------------------------- |
|
2637 // CMmsClientMtm::AddFilePathAttachmentL |
|
2638 // --------------------------------------------------------- |
|
2639 // |
|
2640 void CMmsClientMtm::AddFilePathAttachmentL( |
|
2641 const TDesC& aFilePath, |
|
2642 const TDesC8& aMimeType, |
|
2643 CMsvAttachment::TMsvAttachmentType aType, |
|
2644 TRequestStatus& aStatus, |
|
2645 const TUint aCharacterSet /* = 0 */ ) |
|
2646 { |
|
2647 __ASSERT_DEBUG( aType != CMsvAttachment::EMsvMessageEntry, |
|
2648 User::Invariant() ); |
|
2649 |
|
2650 if( !iAttaWaiter ) |
|
2651 { |
|
2652 iAttaWaiter = CMmsAttachmentWaiter::NewL(); |
|
2653 } |
|
2654 |
|
2655 // store must be the first item allocated because it is the last one to be popped |
|
2656 CMsvStore* store = iMsvEntry->EditStoreL(); |
|
2657 CleanupStack::PushL( store ); |
|
2658 |
|
2659 CMsvAttachment* attachment = CMsvAttachment::NewL( aType ); |
|
2660 CleanupStack::PushL( attachment ); |
|
2661 |
|
2662 CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL(); |
|
2663 CleanupStack::PushL( mimeHeaders ); |
|
2664 |
|
2665 // set the size |
|
2666 TEntry fileEntry; |
|
2667 RFs& fs = Session().FileSession(); |
|
2668 User::LeaveIfError( fs.Entry( aFilePath, fileEntry ) ); |
|
2669 attachment->SetSize( fileEntry.iSize ); |
|
2670 |
|
2671 // set attachment name |
|
2672 TParse fileNameParser; |
|
2673 User::LeaveIfError( fileNameParser.Set( aFilePath, NULL, NULL) ); |
|
2674 |
|
2675 attachment->SetAttachmentNameL( fileNameParser.NameAndExt() ); |
|
2676 // set the mime-type if provided |
|
2677 if( aMimeType.Length() > 0 ) |
|
2678 { |
|
2679 attachment->SetMimeTypeL( aMimeType ); |
|
2680 TInt position = aMimeType.Find( KMmsSlash8 ); |
|
2681 if ( position > 0 ) |
|
2682 { |
|
2683 mimeHeaders->SetContentTypeL( aMimeType.Left( position ) ); |
|
2684 } |
|
2685 if ( position < aMimeType.Length() - 1 ) |
|
2686 { |
|
2687 mimeHeaders->SetContentSubTypeL( aMimeType.Mid( position + 1 ) ); |
|
2688 } |
|
2689 } |
|
2690 |
|
2691 mimeHeaders->SetSuggestedFilenameL( attachment->AttachmentName() ); |
|
2692 |
|
2693 mimeHeaders->SetMimeCharset( aCharacterSet ); |
|
2694 mimeHeaders->StoreL( *attachment ); |
|
2695 |
|
2696 TInt diskSpace = 0; |
|
2697 diskSpace = KMmsIndexEntryExtra + mimeHeaders->Size(); |
|
2698 |
|
2699 // mime headers have been streamed to CMsvAttachment, they can go now |
|
2700 CleanupStack::PopAndDestroy( mimeHeaders ); |
|
2701 |
|
2702 // now we know how much disk space we need |
|
2703 if ( aType == CMsvAttachment::EMsvFile ) |
|
2704 { |
|
2705 diskSpace += attachment->Size(); |
|
2706 } |
|
2707 |
|
2708 // Check that sufficient disk space available |
|
2709 if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
2710 &Session().FileSession(), |
|
2711 diskSpace, |
|
2712 iMessageDrive ) ) |
|
2713 { |
|
2714 // we use standard error code here |
|
2715 CleanupStack::PopAndDestroy( attachment ); |
|
2716 User::Leave( KErrDiskFull ); |
|
2717 } |
|
2718 |
|
2719 // attachment is initialised, pass to the attachment manager |
|
2720 MMsvAttachmentManager& manager = store->AttachmentManagerL(); |
|
2721 if ( iAttaWaiter->IsActive() ) |
|
2722 { |
|
2723 // can't start an active operation because already active |
|
2724 User::Leave(KErrInUse); |
|
2725 } |
|
2726 switch( aType ) |
|
2727 { |
|
2728 case CMsvAttachment::EMsvLinkedFile: |
|
2729 manager.AddLinkedAttachmentL( aFilePath, attachment, |
|
2730 iAttaWaiter->iStatus ); |
|
2731 break; |
|
2732 default: // CMsvAttachment::EMsvFile |
|
2733 manager.AddAttachmentL( aFilePath, attachment, |
|
2734 iAttaWaiter->iStatus ); |
|
2735 break; |
|
2736 } |
|
2737 |
|
2738 CleanupStack::Pop( attachment ); // ownership passed to manager |
|
2739 // We cannot start waiting before we know that the function we are waiting for |
|
2740 // did not leave. If we become active, and the function leaves, we are in trouble |
|
2741 iAttaWaiter->StartWaitingL( aStatus, store, &manager ); |
|
2742 CleanupStack::Pop( store ); // ownership passed to iAttaWaiter |
|
2743 } |
|
2744 |
|
2745 |
|
2746 // --------------------------------------------------------- |
|
2747 // CMmsClientMtm::StoreAttributesL |
|
2748 // --------------------------------------------------------- |
|
2749 // |
|
2750 void CMmsClientMtm::StoreAttributesL( CMsvStore& aStore ) |
|
2751 { |
|
2752 |
|
2753 if ( iAttributes->MdcaCount() == 0 ) |
|
2754 { |
|
2755 if ( aStore.IsPresentL( KUidMmsAttributeStream ) ) |
|
2756 { |
|
2757 aStore.RemoveL( KUidMmsAttributeStream ); |
|
2758 } |
|
2759 return; |
|
2760 } |
|
2761 |
|
2762 RMsvWriteStream writeStream; |
|
2763 // pushes 'writeStream' to the stack |
|
2764 writeStream.AssignLC( aStore, KUidMmsAttributeStream ); |
|
2765 |
|
2766 writeStream.WriteInt32L( iAttributes->MdcaCount() ); |
|
2767 |
|
2768 TInt i; |
|
2769 for ( i = 0; i < iAttributes->MdcaCount(); i++ ) |
|
2770 { |
|
2771 writeStream << (*iAttributes)[i]; |
|
2772 } |
|
2773 |
|
2774 writeStream.CommitL(); |
|
2775 writeStream.Close(); |
|
2776 CleanupStack::PopAndDestroy( &writeStream ); // close writeStream |
|
2777 } |
|
2778 |
|
2779 // --------------------------------------------------------- |
|
2780 // CMmsClientMtm::RestoreAttributesL |
|
2781 // --------------------------------------------------------- |
|
2782 // |
|
2783 void CMmsClientMtm::RestoreAttributesL( CMsvStore& aStore ) |
|
2784 { |
|
2785 iAttributes->Reset(); |
|
2786 if ( !aStore.IsPresentL( KUidMmsAttributeStream ) ) |
|
2787 { |
|
2788 return; |
|
2789 } |
|
2790 |
|
2791 RMsvReadStream readStream; |
|
2792 // pushes readStream to clenaup stack |
|
2793 readStream.OpenLC( aStore, KUidMmsAttributeStream ); |
|
2794 |
|
2795 TInt count = 0; |
|
2796 |
|
2797 count = readStream.ReadInt32L(); |
|
2798 TInt i; |
|
2799 HBufC* desBuffer; |
|
2800 |
|
2801 for ( i = 0; i < count; i++ ) |
|
2802 { |
|
2803 desBuffer = HBufC::NewLC( readStream, KMaxTInt ); |
|
2804 iAttributes->AppendL( *desBuffer ); |
|
2805 CleanupStack::PopAndDestroy( desBuffer ); |
|
2806 } |
|
2807 |
|
2808 readStream.Close(); |
|
2809 CleanupStack::PopAndDestroy( &readStream ); // close readStream |
|
2810 } |
|
2811 |
|
2812 // --------------------------------------------------------- |
|
2813 // CMmsClientMtm::RecognizeCharSetL |
|
2814 // --------------------------------------------------------- |
|
2815 // |
|
2816 TUint CMmsClientMtm::RecognizeCharSetL( RFile& aFile ) |
|
2817 { |
|
2818 TUint charset = 0; |
|
2819 |
|
2820 // Use CMsgTextUtils for character conversion |
|
2821 CMsgTextUtils* msgTextUtils = CMsgTextUtils::NewL( Session().FileSession() ); |
|
2822 CleanupStack::PushL( msgTextUtils ); |
|
2823 |
|
2824 charset = msgTextUtils->RecognizeCharSetL( Session().FileSession(), aFile ); |
|
2825 if ( charset == 0 ) |
|
2826 { |
|
2827 charset = KMmsUTF16; // utf16 with explicit byte order mark |
|
2828 CleanupStack::PopAndDestroy( msgTextUtils ); |
|
2829 return charset; // unicode little endian or big endian |
|
2830 } |
|
2831 |
|
2832 charset = msgTextUtils->CharconvIdToMibIdL( charset ); |
|
2833 CleanupStack::PopAndDestroy( msgTextUtils ); |
|
2834 return charset; |
|
2835 } |
|
2836 |
|
2837 |
|
2838 |
|
2839 // --------------------------------------------------------- |
|
2840 // CMmsClientMtm:: |
|
2841 // --------------------------------------------------------- |
|
2842 // |
|
2843 |
|
2844 |
|
2845 // ================= OTHER EXPORTED FUNCTIONS ============== |
|
2846 |
|
2847 // |
|
2848 // --------------------------------------------------------- |
|
2849 // gPanic implements |
|
2850 // panic function, should be used by debug version only |
|
2851 // |
|
2852 GLDEF_C void gPanic( TMmsPanic aPanic ) // error number enumerations |
|
2853 { |
|
2854 _LIT(KMmsPanic,"MMS"); |
|
2855 User::Panic( KMmsPanic, aPanic ); |
|
2856 } |
|
2857 |
|
2858 // End of File |