email/mail/UtilsSrc/MsgMailAppUi.cpp
changeset 79 2981cb3aa489
parent 0 72b543305e3a
equal deleted inserted replaced
25:84d9eb65b26f 79:2981cb3aa489
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  A common base class for Mail application ui classes.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <akntitle.h>
       
    21 #include <AknsUtils.h>
       
    22 #include <aknlayoutscalable_apps.cdl.h>
       
    23 #include <aknlayoutscalable_avkon.cdl.h>
       
    24 #include <gulicon.h>
       
    25 
       
    26 #include <msgmailutils.mbg>
       
    27 #include <miuthdr.h>                    // CImHeader
       
    28 #include <msvapi.h>                     // CMsvEntry
       
    29 #include <miutmsg.h>                    // CImEmailMessage
       
    30 #include <mmsvattachmentmanager.h>
       
    31 #include <cmsvattachment.h>
       
    32 #include <ConeResLoader.h>              // RConeResourceLoader
       
    33 #include <CommonContentPolicy.h>        // ContentPolicy
       
    34 #include <muiumsvuiserviceutilitiesinternal.h>  // MUIU MTM utils 
       
    35 
       
    36 
       
    37 
       
    38 
       
    39 #include <AknWaitNoteWrapper.h>
       
    40 #include <AknWaitDialog.h>
       
    41 #include <featmgr.h>                    // FeatureManager
       
    42 #include <bldvariant.hrh>
       
    43 #include <coeutils.h>
       
    44 #include <data_caging_path_literals.hrh> 
       
    45 #include <messaginginternalcrkeys.h>
       
    46 #include <messagingvariant.hrh>
       
    47 
       
    48 // Editor base classes:
       
    49 #include <MsgAttachmentInfo.h>
       
    50 #include <MsgAttachmentModel.h>
       
    51 #include <MsgEditorView.h>
       
    52 #include <MsgBodyControl.h>
       
    53 #include <MsgAddressControl.h>
       
    54 #include <MsgRecipientItem.h>
       
    55 
       
    56 #include <MuiuOperationWait.h>              // CMuiuOperationWait
       
    57 #include <StringLoader.h>
       
    58 
       
    59 #include <MsgMailUtils.rsg>
       
    60 #include "MsgMailAppUi.h"
       
    61 #include "MsgMailDocument.h"
       
    62 #include "MsgMailPreferences.h"
       
    63 #include "MailUtils.h"
       
    64 
       
    65 // Mail Central Repository handler
       
    66 #include "CMailCRHandler.h"
       
    67 
       
    68 // LOCAL CONSTANTS AND MACROS
       
    69 
       
    70 _LIT(KResourcesWithDir,"z:MsgMailUtils.rSC");
       
    71 _LIT( KMsgMailMBMFileName, "z:msgmailutils.mbm" );
       
    72 /// Message details item separator.
       
    73 _LIT( KMsgDetailsSeparator, "; " );
       
    74 /// Max length used for message details.
       
    75 const TInt KMsgMaxDetailsLength    = 128;
       
    76 
       
    77 // LOCAL FUNCTION PROTOTYPES
       
    78 typedef TBool (*TParseFunc)( TLex& aLex );
       
    79 LOCAL_C TBool DoOrReverse( TParseFunc aFunc, TLex& aLex );
       
    80 LOCAL_C TBool Star( TParseFunc aFunc, TLex& aLex );
       
    81 LOCAL_C TBool Plus( TParseFunc aFunc, TLex& aLex );
       
    82 LOCAL_C TBool NoWSCtl( TLex& aLex );
       
    83 LOCAL_C TBool WSP( TLex& aLex );
       
    84 LOCAL_C TBool FWS( TLex& aLex );
       
    85 LOCAL_C TBool CText( TLex& aLex );
       
    86 LOCAL_C TBool QuotedPair( TLex& aLex );
       
    87 LOCAL_C TBool FWSCContent( TLex& aLex );
       
    88 LOCAL_C TBool CContent( TLex& aLex );
       
    89 LOCAL_C TBool Comment( TLex& aLex );
       
    90 LOCAL_C TBool CFWS( TLex& aLex );
       
    91 LOCAL_C TBool AText( TLex& aLex );
       
    92 LOCAL_C TBool Atom( TLex& aLex );
       
    93 LOCAL_C TBool DotAtomText( TLex& aLex );
       
    94 LOCAL_C TBool DotAtom( TLex& aLex );
       
    95 LOCAL_C TBool DotPlusAText( TLex& aLex );
       
    96 LOCAL_C TBool QText( TLex& aLex );
       
    97 LOCAL_C TBool QContent( TLex& aLex );
       
    98 LOCAL_C TBool FWSQContent( TLex& aLex );
       
    99 LOCAL_C TBool QuotedString( TLex& aLex );
       
   100 LOCAL_C TBool LocalPart( TLex& aLex );
       
   101 LOCAL_C TBool DText( TLex& aLex );
       
   102 LOCAL_C TBool DContent( TLex& aLex );
       
   103 LOCAL_C TBool DomainLiteral( TLex& aLex );
       
   104 LOCAL_C TBool Domain( TLex& aLex );
       
   105 LOCAL_C TBool FWSDContent( TLex& aLex );
       
   106 LOCAL_C TBool AddrSpec( TLex& aLex );
       
   107 LOCAL_C TBool Word( TLex& aLex );
       
   108 LOCAL_C TBool DisplayName( TLex& aLex );
       
   109 LOCAL_C TBool CommaMailbox( TLex& aLex );
       
   110 LOCAL_C TBool AngleAddr( TLex& aLex );
       
   111 LOCAL_C TBool NameAddr( TLex& aLex );
       
   112 LOCAL_C TBool Mailbox( TLex& aLex );
       
   113 LOCAL_C TBool MailboxList( TLex& aLex );
       
   114 LOCAL_C TBool Group( TLex& aLex );
       
   115 LOCAL_C TBool Address( TLex& aLex );
       
   116 
       
   117 // ==================== LOCAL FUNCTIONS ====================
       
   118 
       
   119 // ----------------------------------------------------
       
   120 // DoOrReverse()
       
   121 // Calls aFunc. If it fails, the lexer is returned to 
       
   122 // the state before calling DoOrReverse().
       
   123 // ----------------------------------------------------
       
   124 //
       
   125 LOCAL_C TBool DoOrReverse( TParseFunc aFunc, TLex& aLex )
       
   126 	{
       
   127 	TLexMark mark;
       
   128 	aLex.Mark( mark );
       
   129 	if( (*aFunc)(aLex) )
       
   130 		{
       
   131 		return ETrue;
       
   132 		}
       
   133 	else
       
   134 		{
       
   135 		aLex.UnGetToMark( mark );
       
   136 		return EFalse;
       
   137 		}
       
   138 	}
       
   139 
       
   140 // ----------------------------------------------------
       
   141 // Star()
       
   142 // Calls aFunc repeatedly until aFunc returns EFalse.
       
   143 // The lexer is left to the state where it was after
       
   144 // the last succesful aFunc call. Returns ETrue if
       
   145 // at least one call to aFunc succeeded.
       
   146 // ----------------------------------------------------
       
   147 //
       
   148 LOCAL_C TBool Star( TParseFunc aFunc, TLex& aLex )
       
   149 	{
       
   150 	TBool hasMore( ETrue );
       
   151 	TBool hasOne( EFalse );
       
   152 	while( hasMore )
       
   153 		{
       
   154 		if( DoOrReverse( aFunc, aLex ) )
       
   155 			{
       
   156 			hasOne = ETrue;	
       
   157 			}
       
   158 		else
       
   159 			{
       
   160 			hasMore = EFalse;
       
   161 			}
       
   162 		}
       
   163 
       
   164 	return hasOne;
       
   165 	}
       
   166 
       
   167 // ----------------------------------------------------
       
   168 // Like Star() except enforces one succesful call
       
   169 // to aFunc.
       
   170 // ----------------------------------------------------
       
   171 //
       
   172 LOCAL_C TBool Plus( TParseFunc aFunc, TLex& aLex )
       
   173 	{
       
   174 	if( !DoOrReverse( aFunc, aLex ) )
       
   175 		{
       
   176 		return EFalse;
       
   177 		}
       
   178 
       
   179 	Star( aFunc, aLex );
       
   180 	return ETrue;
       
   181 	}
       
   182 
       
   183 // ----------------------------------------------------
       
   184 // NO-WS-CTL := %d1-8 / %d11 / %d12 / %d14-31 / %d127 ; US-ASCII 
       
   185 // control characters that do not include the carriage return, 
       
   186 // line feed, and white space characters
       
   187 // ----------------------------------------------------
       
   188 //
       
   189 LOCAL_C TBool NoWSCtl( TLex& aLex )
       
   190 	{
       
   191 	TChar ch( aLex.Get() );
       
   192 	return ( (ch >= 1 && ch <= 8)			// CSI: 47 # See a comment above.
       
   193 		|| ch == 11							// CSI: 47 # See a comment above.
       
   194 		|| ch == 12							// CSI: 47 # See a comment above.
       
   195 		|| (ch >= 14 && ch <= 31)			// CSI: 47 # See a comment above.
       
   196 		|| ch == 127 );						// CSI: 47 # See a comment above.
       
   197 	}
       
   198 
       
   199 
       
   200 // ----------------------------------------------------
       
   201 // text := %d1-9 / %d11 / %d12 / %d14-127 / obs-text ; Characters excluding CR and LF
       
   202 // ----------------------------------------------------
       
   203 //
       
   204 LOCAL_C TBool Text( TLex& aLex )
       
   205 	{
       
   206 	TChar ch( aLex.Get() );
       
   207 	return ( (ch >= 1 && ch <= 9)			// CSI: 47 # See a comment above.
       
   208 		|| ch == 11							// CSI: 47 # See a comment above.
       
   209 		|| ch == 12							// CSI: 47 # See a comment above.
       
   210 		|| (ch >= 14 && ch <= 127) );		// CSI: 47 # See a comment above.
       
   211 	}
       
   212 
       
   213 // ----------------------------------------------------
       
   214 // quoted-pair := ("\" text) / obs-qp
       
   215 // ----------------------------------------------------
       
   216 //
       
   217 LOCAL_C TBool QuotedPair( TLex& aLex )
       
   218 	{
       
   219 	if( aLex.Get() != '\\' )
       
   220 		{
       
   221 		return EFalse;
       
   222 		}
       
   223 
       
   224 	return Text( aLex );
       
   225 	}
       
   226 
       
   227 // ----------------------------------------------------
       
   228 // WSP = SPACE / HTAB
       
   229 // ----------------------------------------------------
       
   230 //
       
   231 LOCAL_C TBool WSP( TLex& aLex )
       
   232 	{
       
   233 	TChar ch( aLex.Get() );
       
   234 	return ch == EKeySpace || ch == EKeyTab;
       
   235 	}
       
   236 
       
   237 // ----------------------------------------------------
       
   238 // FWS := ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space
       
   239 // ----------------------------------------------------
       
   240 //
       
   241 LOCAL_C TBool FWS( TLex& aLex )
       
   242 	{
       
   243 	return Plus( WSP, aLex );
       
   244 	}
       
   245 
       
   246 // ----------------------------------------------------
       
   247 // ctext := NO-WS-CTL / %d33-39 / %d42-91 / %d93-126 ; Non white space 
       
   248 // controls and The rest of the US-ASCII characters not including "(", ")", or "\"
       
   249 // ----------------------------------------------------
       
   250 //
       
   251 LOCAL_C TBool CText( TLex& aLex )
       
   252 	{
       
   253 	if( !DoOrReverse( NoWSCtl, aLex ) )
       
   254 		{
       
   255 		TChar ch( aLex.Get() );
       
   256 		return( (ch >= 33 && ch <= 39)				// CSI: 47 # See a comment above.
       
   257 			|| (ch >= 42 && ch <= 91)				// CSI: 47 # See a comment above.
       
   258 			|| (ch >= 93 && ch <= 126) );			// CSI: 47 # See a comment above.
       
   259 		}
       
   260 	else
       
   261 		{
       
   262 		return ETrue;
       
   263 		}
       
   264 	}
       
   265 
       
   266 // ----------------------------------------------------
       
   267 // ccontent := ctext / quoted-pair / comment
       
   268 // ----------------------------------------------------
       
   269 //
       
   270 LOCAL_C TBool CContent( TLex& aLex )
       
   271 	{
       
   272 	return DoOrReverse( CText, aLex ) || DoOrReverse( QuotedPair, aLex ) || Comment( aLex );
       
   273 	}
       
   274 
       
   275 // ----------------------------------------------------
       
   276 // [FWS] ccontent
       
   277 // ----------------------------------------------------
       
   278 //
       
   279 LOCAL_C TBool FWSCContent( TLex& aLex )
       
   280 	{
       
   281 	FWS( aLex );
       
   282 	return CContent( aLex );
       
   283 	}
       
   284 
       
   285 // ----------------------------------------------------
       
   286 // comment := "(" *([FWS] ccontent) [FWS] ")"
       
   287 // ----------------------------------------------------
       
   288 //
       
   289 LOCAL_C TBool Comment( TLex& aLex )
       
   290 	{
       
   291 	if( aLex.Get() != '(' )
       
   292 		{
       
   293 		return EFalse;
       
   294 		}
       
   295 
       
   296 	Star( FWSCContent, aLex );
       
   297 	FWS( aLex );
       
   298 	return aLex.Get() == ')';
       
   299 	}
       
   300 
       
   301 // ----------------------------------------------------
       
   302 // [FWS] comment
       
   303 // ----------------------------------------------------
       
   304 //
       
   305 LOCAL_C TBool FWSComment( TLex& aLex )
       
   306 	{
       
   307 	FWS( aLex );
       
   308 	return Comment( aLex );
       
   309 	}
       
   310 
       
   311 // ----------------------------------------------------
       
   312 // CFWS := *([FWS] comment) (([FWS] comment) / FWS)
       
   313 // ----------------------------------------------------
       
   314 //
       
   315 LOCAL_C TBool CFWS( TLex& aLex )
       
   316 	{
       
   317 	TBool hasOne( Star( FWSComment, aLex ) );
       
   318 
       
   319 	return hasOne || FWS( aLex );
       
   320 	}
       
   321 
       
   322 // ----------------------------------------------------
       
   323 // atext := ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / 
       
   324 // "-" / "/" / "=" / "?" "^" / "_" / "`" / "{" / "|" / "}" / "~"; Any 
       
   325 // character except controls, SP, and specials. Used for atoms
       
   326 // ----------------------------------------------------
       
   327 //
       
   328 LOCAL_C TBool AText( TLex& aLex )
       
   329 	{
       
   330 	//ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" "^" / "_" / 
       
   331 	//	"`" / "{" / "|" / "}" / "~"
       
   332 	TChar ch( aLex.Get() );
       
   333 	return( (ch >= 'a' && ch <= 'z' )
       
   334 		|| (ch >= 'A' && ch <= 'Z' )
       
   335 		|| (ch >= '0' && ch <= '9' )
       
   336 		|| ch == '!'
       
   337 		|| ch == '#'
       
   338 		|| ch == '$'
       
   339 		|| ch == '%'
       
   340 		|| ch == '&'
       
   341 		|| ch == '\''
       
   342 		|| ch == '*'
       
   343 		|| ch == '+'
       
   344 		|| ch == '-'
       
   345 		|| ch == '/'
       
   346 		|| ch == '='
       
   347 		|| ch == '?'
       
   348 		|| ch == '^'
       
   349 		|| ch == '_'
       
   350 		|| ch == '`'
       
   351 		|| ch == '{'
       
   352 		|| ch == '|'
       
   353 		|| ch == '}'
       
   354 		|| ch == '~' );
       
   355 	}
       
   356 
       
   357 // ----------------------------------------------------
       
   358 // atom := [CFWS] 1*atext [CFWS]
       
   359 // ----------------------------------------------------
       
   360 //
       
   361 LOCAL_C TBool Atom( TLex& aLex )
       
   362 	{
       
   363 	DoOrReverse( CFWS, aLex );
       
   364 
       
   365 	if( !Plus( AText, aLex ) )
       
   366 		{
       
   367 		return EFalse;
       
   368 		}
       
   369 
       
   370 	DoOrReverse( CFWS, aLex );
       
   371 	return ETrue;
       
   372 	}
       
   373 
       
   374 // ----------------------------------------------------
       
   375 // dot-atom := [CFWS] dot-atom-text [CFWS]
       
   376 // ----------------------------------------------------
       
   377 //
       
   378 LOCAL_C TBool DotAtom( TLex& aLex )
       
   379 	{
       
   380 	DoOrReverse( CFWS, aLex );
       
   381 	if( !DoOrReverse( DotAtomText, aLex ) )
       
   382 		{
       
   383 		return EFalse;
       
   384 		}
       
   385 	DoOrReverse( CFWS, aLex );
       
   386 
       
   387 	return ETrue;
       
   388 	}
       
   389 
       
   390 // ----------------------------------------------------
       
   391 // "." 1*atext
       
   392 // ----------------------------------------------------
       
   393 //
       
   394 LOCAL_C TBool DotPlusAText( TLex& aLex )
       
   395 	{
       
   396 	return aLex.Get() == '.' && Plus( AText, aLex );
       
   397 	}
       
   398 
       
   399 // ----------------------------------------------------
       
   400 // dot-atom-text := 1*atext *("." 1*atext)
       
   401 // ----------------------------------------------------
       
   402 //
       
   403 LOCAL_C TBool DotAtomText( TLex& aLex )
       
   404 	{
       
   405 	if( !Plus( AText, aLex ) )
       
   406 		{
       
   407 		return EFalse;
       
   408 		}
       
   409 
       
   410 	Star( DotPlusAText, aLex );
       
   411 	return ETrue;
       
   412 	}
       
   413 
       
   414 // ----------------------------------------------------
       
   415 // qtext := NO-WS-CTL / %d33 / %d35-91 / %d93-126 ; Non white space 
       
   416 // controls and The rest of the US-ASCII characters not including "\" 
       
   417 // or the quote character
       
   418 // ----------------------------------------------------
       
   419 //
       
   420 LOCAL_C TBool QText( TLex& aLex )
       
   421 	{
       
   422 	if( DoOrReverse( NoWSCtl, aLex ) )
       
   423 		{
       
   424 		return ETrue;
       
   425 		}
       
   426 
       
   427 	TChar ch( aLex.Get() );
       
   428 	return ch == 33						// CSI: 47 # See a comment above.
       
   429 		|| (ch >= 35 && ch <= 91)		// CSI: 47 # See a comment above.
       
   430 		|| (ch >= 93 && ch <= 126);		// CSI: 47 # See a comment above.
       
   431 	}
       
   432 
       
   433 // ----------------------------------------------------
       
   434 // qcontent := qtext / quoted-pair
       
   435 // ----------------------------------------------------
       
   436 //
       
   437 LOCAL_C TBool QContent( TLex& aLex )
       
   438 	{
       
   439 	return DoOrReverse( QText, aLex ) || QuotedPair( aLex );
       
   440 	}
       
   441 
       
   442 // ----------------------------------------------------
       
   443 // [FWS] qcontent
       
   444 // ----------------------------------------------------
       
   445 //
       
   446 LOCAL_C TBool FWSQContent( TLex& aLex )
       
   447 	{
       
   448 	FWS( aLex );
       
   449 	return QContent( aLex );
       
   450 	}
       
   451 
       
   452 // ----------------------------------------------------
       
   453 // quoted-string := [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
       
   454 // ----------------------------------------------------
       
   455 //
       
   456 LOCAL_C TBool QuotedString( TLex& aLex )
       
   457 	{
       
   458 	DoOrReverse( CFWS, aLex );
       
   459 
       
   460 	if( aLex.Get() != '"' )
       
   461 		{
       
   462 		return EFalse;
       
   463 		}
       
   464 
       
   465 	Star( FWSQContent, aLex );
       
   466 
       
   467 	DoOrReverse( FWS, aLex );
       
   468 
       
   469 	if( aLex.Get() != '"' )
       
   470 		{
       
   471 		return EFalse;
       
   472 		}
       
   473 
       
   474 	DoOrReverse( CFWS, aLex );
       
   475 	return ETrue;
       
   476 	}
       
   477 
       
   478 // ----------------------------------------------------
       
   479 // word := atom / quoted-string
       
   480 // ----------------------------------------------------
       
   481 //
       
   482 LOCAL_C TBool Word( TLex& aLex )
       
   483 	{
       
   484 	return DoOrReverse( Atom, aLex ) || QuotedString( aLex );
       
   485 	}
       
   486 
       
   487 // ----------------------------------------------------
       
   488 // address := mailbox / group
       
   489 // ----------------------------------------------------
       
   490 //
       
   491 LOCAL_C TBool Address( TLex& aLex )
       
   492 	{
       
   493 	return DoOrReverse( Mailbox, aLex ) || Group( aLex );
       
   494 	}
       
   495 
       
   496 // ----------------------------------------------------
       
   497 // mailbox := name-addr / addr-spec
       
   498 // ----------------------------------------------------
       
   499 //
       
   500 LOCAL_C TBool Mailbox( TLex& aLex )
       
   501 	{
       
   502 	return DoOrReverse( NameAddr, aLex ) || AddrSpec( aLex );
       
   503 	}
       
   504 
       
   505 // ----------------------------------------------------
       
   506 // name-addr := [display-name] angle-addr
       
   507 // ----------------------------------------------------
       
   508 //
       
   509 LOCAL_C TBool NameAddr( TLex& aLex )
       
   510 	{
       
   511 	DoOrReverse( DisplayName, aLex );
       
   512 	return AngleAddr( aLex );
       
   513 	}
       
   514 
       
   515 // ----------------------------------------------------
       
   516 // angle-addr := [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
       
   517 // ----------------------------------------------------
       
   518 //
       
   519 LOCAL_C TBool AngleAddr( TLex& aLex )
       
   520 	{
       
   521 	DoOrReverse( CFWS, aLex );
       
   522 	if( aLex.Get() != '<' )
       
   523 		{
       
   524 		return EFalse;
       
   525 		}
       
   526 
       
   527 	if( !DoOrReverse( AddrSpec, aLex ) )
       
   528 		{
       
   529 		return EFalse;
       
   530 		}
       
   531 
       
   532 	if( aLex.Get() != '>' )
       
   533 		{
       
   534 		return EFalse;
       
   535 		}
       
   536 
       
   537 	DoOrReverse( CFWS, aLex );
       
   538 	return ETrue;
       
   539 	}
       
   540 
       
   541 // ----------------------------------------------------
       
   542 // group := display-name ":" [mailbox-list / CFWS] ";" [CFWS]
       
   543 // ----------------------------------------------------
       
   544 //
       
   545 LOCAL_C TBool Group( TLex& aLex )
       
   546 	{
       
   547 	if( !DisplayName( aLex ) )
       
   548 		{
       
   549 		return EFalse;
       
   550 		}
       
   551 
       
   552 	if( aLex.Get() != ':' )
       
   553 		{
       
   554 		return EFalse;
       
   555 		}
       
   556 
       
   557 	if( !DoOrReverse( MailboxList, aLex ) )
       
   558 		{
       
   559 		DoOrReverse( CFWS, aLex );
       
   560 		}
       
   561 
       
   562 	if( aLex.Get() != ';' )
       
   563 		{
       
   564 		return EFalse;
       
   565 		}
       
   566 
       
   567 	DoOrReverse( CFWS, aLex );
       
   568 	return ETrue;
       
   569 	}
       
   570 
       
   571 // ----------------------------------------------------
       
   572 // display-name := phrase
       
   573 // phrase := 1*word / obs-phrase
       
   574 // ----------------------------------------------------
       
   575 //
       
   576 LOCAL_C TBool DisplayName( TLex& aLex )
       
   577 	{
       
   578 	return Plus( Word, aLex );
       
   579 	}
       
   580 
       
   581 // ----------------------------------------------------
       
   582 // "," mailbox
       
   583 // ----------------------------------------------------
       
   584 //
       
   585 LOCAL_C TBool CommaMailbox( TLex& aLex )
       
   586 	{
       
   587 	return aLex.Get() == ',' && Mailbox( aLex );
       
   588 	}
       
   589 
       
   590 // ----------------------------------------------------
       
   591 // mailbox-list := (mailbox *("," mailbox)) / obs-mbox-list
       
   592 // ----------------------------------------------------
       
   593 //
       
   594 LOCAL_C TBool MailboxList( TLex& aLex )
       
   595 	{
       
   596 	if( !DoOrReverse( Mailbox, aLex ) )
       
   597 		{
       
   598 		return EFalse;
       
   599 		}
       
   600 
       
   601 	Star( CommaMailbox, aLex );
       
   602 
       
   603 	return ETrue;
       
   604 	}
       
   605 
       
   606 // ----------------------------------------------------
       
   607 // addr-spec := local-part "@" domain
       
   608 // ----------------------------------------------------
       
   609 //
       
   610 LOCAL_C TBool AddrSpec( TLex& aLex )
       
   611 	{
       
   612 	if( !LocalPart( aLex ) )
       
   613 		{
       
   614 		return EFalse;
       
   615 		}
       
   616 
       
   617 	if( aLex.Get() != '@' )
       
   618 		{
       
   619 		return EFalse;
       
   620 		}
       
   621 
       
   622 	return Domain( aLex );
       
   623 	}
       
   624 
       
   625 // ----------------------------------------------------
       
   626 // local-part := dot-atom / quoted-string / obs-local-part
       
   627 // ----------------------------------------------------
       
   628 //
       
   629 LOCAL_C TBool LocalPart( TLex& aLex )
       
   630 	{
       
   631 	return DoOrReverse( DotAtom, aLex ) || QuotedString( aLex );
       
   632 	}
       
   633 
       
   634 // ----------------------------------------------------
       
   635 // domain := dot-atom / domain-literal / obs-domain
       
   636 // ----------------------------------------------------
       
   637 //
       
   638 LOCAL_C TBool Domain( TLex& aLex )
       
   639 	{
       
   640 	return DoOrReverse( DotAtom, aLex ) || DomainLiteral( aLex );
       
   641 	}
       
   642 
       
   643 // ----------------------------------------------------
       
   644 // [FWS] dcontent
       
   645 // ----------------------------------------------------
       
   646 //
       
   647 LOCAL_C TBool FWSDContent( TLex& aLex )
       
   648 	{
       
   649 	FWS( aLex );
       
   650 	return DContent( aLex );
       
   651 	}
       
   652 
       
   653 // ----------------------------------------------------
       
   654 // domain-literal := [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
       
   655 // ----------------------------------------------------
       
   656 //
       
   657 LOCAL_C TBool DomainLiteral( TLex& aLex )
       
   658 	{
       
   659 	DoOrReverse( CFWS, aLex );
       
   660 	if( aLex.Get() != '[' )
       
   661 		{
       
   662 		return EFalse;
       
   663 		}
       
   664 
       
   665 	Star( FWSDContent, aLex );
       
   666 
       
   667 	DoOrReverse( FWS, aLex );
       
   668 	if( aLex.Get() != ']' )
       
   669 		{
       
   670 		return EFalse;
       
   671 		}
       
   672 
       
   673 	DoOrReverse( CFWS, aLex );
       
   674 	return ETrue;
       
   675 	}
       
   676 
       
   677 // ----------------------------------------------------
       
   678 // dcontent := dtext / quoted-pair
       
   679 // ----------------------------------------------------
       
   680 //
       
   681 LOCAL_C TBool DContent( TLex& aLex )
       
   682 	{
       
   683 	return DoOrReverse( DText, aLex ) || QuotedPair( aLex );
       
   684 	}
       
   685 
       
   686 // ----------------------------------------------------
       
   687 // dtext := NO-WS-CTL / %d33-90 / %d94-126 ; Non white space controls and 
       
   688 // the rest of the US-ASCII characters not including "[", "]", or "\"
       
   689 // ----------------------------------------------------
       
   690 //
       
   691 LOCAL_C TBool DText( TLex& aLex )
       
   692 	{
       
   693 	if( DoOrReverse( NoWSCtl, aLex ) )
       
   694 		{
       
   695 		return ETrue;
       
   696 		}
       
   697 
       
   698 	TChar ch( aLex.Get() );
       
   699 	return (ch >= 33 && ch <= 90)				// CSI: 47 # See a comment above.
       
   700 		|| (ch >= 94 && ch <= 126);				// CSI: 47 # See a comment above.
       
   701 	}
       
   702 
       
   703 // ================= MEMBER FUNCTIONS =======================
       
   704 
       
   705 // C++ default constructor cannot contain any code that might leave
       
   706 EXPORT_C CMsgMailAppUi::CMsgMailAppUi()
       
   707     : iResource(*iCoeEnv)
       
   708     {
       
   709     }
       
   710 
       
   711 // Symbian OS default constructor can leave.
       
   712 EXPORT_C void CMsgMailAppUi::ConstructL()
       
   713     {
       
   714     // the implementation of this virtual function must call 
       
   715     // CEikAppUi::ConstructL or CEikAppUi::BaseConstructL 
       
   716     // before calling any other leaving function    
       
   717     CMsgEditorAppUi::ConstructL();
       
   718     SetSmallIconL();
       
   719         
       
   720 	TParse* fp = new(ELeave) TParse(); 
       
   721 	fp->Set(KResourcesWithDir, &KDC_RESOURCE_FILES_DIR, NULL); 
       
   722 
       
   723 	TFileName fileName(fp->FullName());
       
   724 	delete fp;
       
   725 	iResource.OpenL(fileName);
       
   726     
       
   727     // Used in derived AppUI classes
       
   728     if (FeatureManager::FeatureSupported( KFeatureIdHelp ))
       
   729     	{
       
   730     	iCommonFlags |= EHelpSupported;
       
   731     	}
       
   732     if (FeatureManager::FeatureSupported( KFeatureIdAvkonELaf ))
       
   733     	{
       
   734     	iCommonFlags |= EWestern;
       
   735     	}
       
   736     
       
   737     // Call PrepareToLaunchL if opened as standalone
       
   738     if( !iEikonEnv->StartedAsServerApp( ) )
       
   739     	{
       
   740        	Document()->PrepareToLaunchL( this );
       
   741        	}
       
   742   
       
   743     }
       
   744 
       
   745     
       
   746 // Destructor
       
   747 EXPORT_C CMsgMailAppUi::~CMsgMailAppUi()
       
   748     {
       
   749     delete iBannedChars;
       
   750     iResource.Close();
       
   751     }
       
   752 
       
   753 
       
   754 // ----------------------------------------------------------------------------
       
   755 // CMsgMailAppUi::MsgSaveL()
       
   756 // Saves message header, body, attachments and send options
       
   757 // in message store.
       
   758 // Argument:
       
   759 // TBool       aInPreparation
       
   760 // In certain cases (e.g. printing) new message has to be saved temporarily,
       
   761 // then aInPreparation flag is set to ETrue (default is EEalse) so automatic
       
   762 // cleanup is made by the server if something goes wrong.
       
   763 // ----------------------------------------------------------------------------
       
   764 //
       
   765 EXPORT_C TBool CMsgMailAppUi::MsgSaveL(const TBool aInPreparation, 
       
   766                                       const TBool aReply /*= EFalse*/)
       
   767     {
       
   768     TBool saved(ETrue);
       
   769     if ( Document()->MediaAvailable() )
       
   770         {
       
   771         saved = DoSaveMessageL( aInPreparation, aReply );
       
   772         }
       
   773     return saved;    
       
   774     }
       
   775 
       
   776 // -----------------------------------------------------------------------------
       
   777 // CMsgMailAppUi::CheckStoreSpaceL()
       
   778 // -----------------------------------------------------------------------------
       
   779 //
       
   780 void CMsgMailAppUi::CheckStoreSpaceL( TMsvEmailEntry aMessage, TBool aReply )
       
   781     {
       
   782     // calculate message size
       
   783     // if forwarding HTML message, all attachments are copied.
       
   784     TBool countAttachments( ( aMessage.MHTMLEmail() && !aReply ) );
       
   785     TInt docSize( MessageSizeL( countAttachments ) );
       
   786     LOG1( "CMsgMailAppUi::CheckStoreSpaceL: %d", docSize );
       
   787     
       
   788     MailDocument()->DiskSpaceBelowCriticalLevelL( docSize );
       
   789     }
       
   790 
       
   791 // -----------------------------------------------------------------------------
       
   792 // CMsgMailAppUi::SetServiceIdL()
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 TBool CMsgMailAppUi::SetServiceIdL( 
       
   796     TMsvEmailEntry& aEntry, CMsgMailDocument& aDocument )
       
   797 	{
       
   798 	TBool returnValue( ETrue );
       
   799 
       
   800 	// set related service ID
       
   801 	CMsvEntry* rootEntry = 
       
   802 		aDocument.Session().GetEntryL(KMsvRootIndexEntryIdValue);
       
   803 	CleanupStack::PushL(rootEntry);
       
   804 	rootEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvNoGrouping,
       
   805 		EMsvSortByNone,ETrue));    
       
   806 	
       
   807 	TMsvEntry serviceEntry;
       
   808 	TRAPD(err, serviceEntry = rootEntry->ChildDataL(aEntry.iServiceId));
       
   809 	CMsgMailPreferences& pref = aDocument.SendOptions();
       
   810 	if (err == KErrNotFound) // mailbox deleted, look for default
       
   811 		{
       
   812 		const TMsvId defaultId(
       
   813             MsvUiServiceUtilitiesInternal::DefaultServiceForMTML(
       
   814 				aDocument.Session(), KUidMsgTypeSMTP, ETrue));
       
   815 		if (defaultId == KMsvUnknownServiceIndexEntryId)
       
   816 			{ // no mailboxes defined
       
   817 			returnValue = EFalse;
       
   818 			}
       
   819 		else // set default mailbox's values to entry
       
   820 			{
       
   821 			serviceEntry = rootEntry->ChildDataL(defaultId);
       
   822 			aEntry.iServiceId = defaultId;
       
   823 			pref.SetServiceId(defaultId);
       
   824 			}
       
   825 		}
       
   826     aEntry.iRelatedId = serviceEntry.iRelatedId;        
       
   827 
       
   828 	CleanupStack::PopAndDestroy(); // rootEntry
       
   829 	return returnValue;
       
   830 	}
       
   831 
       
   832 // -----------------------------------------------------------------------------
       
   833 // CMsgMailAppUi::SetEntryTimeL()
       
   834 // -----------------------------------------------------------------------------
       
   835 //
       
   836 void CMsgMailAppUi::SetEntryTimeL( TMsvEntry& aEntry )
       
   837     {
       
   838     TInt muiuFlags(0);
       
   839 	MailDocument()->MailCRHandler()->GetCRInt(
       
   840 		KCRUidMuiuVariation, 
       
   841 		KMuiuMceFeatures, muiuFlags);
       
   842 	
       
   843 	if ( (muiuFlags & KMceFeatureIdUseUtcTime) )
       
   844 		{
       
   845 		LOG( "CMsgMailAppUi::SetEntryTimeL UTC" );
       
   846 		aEntry.iDate.UniversalTime();
       
   847 		}
       
   848 	else
       
   849 		{
       
   850 		aEntry.iDate.HomeTime(); 
       
   851 		}    
       
   852     }
       
   853 
       
   854 // -----------------------------------------------------------------------------
       
   855 // CMsgMailAppUi::SetEntryFlagsL()
       
   856 // -----------------------------------------------------------------------------
       
   857 //
       
   858 void CMsgMailAppUi::SetEntryFlagsL( 
       
   859     TMsvEmailEntry& aEntry, TMsvId aOrigMessageId )
       
   860     {
       
   861     CMsgMailDocument* doc = MailDocument();
       
   862     // buf must be available when ChangeL() is called
       
   863     HBufC* buf = NULL;
       
   864     // update entry details
       
   865     CMsgAddressControl* control = AddressControl( EMsgComponentIdTo );    
       
   866     if( control )
       
   867         {
       
   868         buf = MakeDetailsLC( *control );
       
   869         aEntry.iDetails.Set( *buf );
       
   870         }
       
   871     else 
       
   872         {
       
   873         control = AddressControl( EMsgComponentIdFrom );
       
   874         if( control )
       
   875             {
       
   876             buf = MakeDetailsLC( *control );
       
   877             TPtr bufPtr( buf->Des() );
       
   878             StripIllegalCharsL( bufPtr );    
       
   879             aEntry.iDetails.Set( bufPtr );
       
   880             }
       
   881         }
       
   882     
       
   883     // calculate new message size 
       
   884     aEntry.iSize = MessageSizeL( ETrue );
       
   885     //aEntry.iSize += doc->Header().DataSize();
       
   886     LOG1( "CMsgMailAppUi::SetEntryFlagsL entry size: %d", aEntry.iSize );
       
   887     
       
   888     // changed flag
       
   889     doc->SetChanged(EFalse);
       
   890 
       
   891     if (aOrigMessageId != doc->Entry().Id())
       
   892         {
       
   893         doc->SetEntryL( aOrigMessageId );
       
   894         }
       
   895     doc->CurrentEntry().ChangeL( aEntry );
       
   896     //  LockEntryL();
       
   897 
       
   898     // buf must be available when ChangeL() is called
       
   899     if (buf)
       
   900         {
       
   901         CleanupStack::PopAndDestroy();
       
   902         }
       
   903     LOG1( "CMsgMailAppUi::SetEntryFlagsL entry size final: %d", aEntry.iSize );        
       
   904     }
       
   905 
       
   906 // -----------------------------------------------------------------------------
       
   907 // CMsgMailAppUi::SetHeaderFieldsL()
       
   908 // -----------------------------------------------------------------------------
       
   909 //
       
   910 void CMsgMailAppUi::SetHeaderFieldsL( TMsvEmailEntry& aMessage )
       
   911     {
       
   912     CMsgMailDocument* doc = MailDocument();
       
   913     CImHeader& header = doc->HeaderL();
       
   914     // set subject to header & entry description
       
   915     if (SubjectControl())
       
   916     	{
       
   917     	CRichText& subject = SubjectControl()->TextContent();
       
   918     	header.SetSubjectL(subject.Read(0, subject.DocumentLength()));
       
   919         
       
   920         // update entry description
       
   921     	aMessage.iDescription.Set(subject.Read(0, subject.DocumentLength()));
       
   922     	}
       
   923     else
       
   924         {
       
   925         header.SetSubjectL(KNullDesC);
       
   926         aMessage.iDescription.Set(KNullDesC);
       
   927         }
       
   928 
       
   929     iNeedRefresh = EFalse;
       
   930     
       
   931     TInt recipientCount(0); 
       
   932     CMsgAddressControl* toControl = AddressControl(EMsgComponentIdTo);
       
   933     AppendRecipientsL( toControl, header.ToRecipients() );
       
   934     recipientCount += header.ToRecipients().Count();
       
   935     
       
   936 	CMsgAddressControl* ccControl = AddressControl(EMsgComponentIdCc);
       
   937 	AppendRecipientsL( ccControl, header.CcRecipients() );
       
   938     recipientCount += header.CcRecipients().Count();
       
   939             
       
   940     CMsgAddressControl* bccControl = AddressControl(EMsgComponentIdBcc);
       
   941     AppendRecipientsL( bccControl, header.BccRecipients() );
       
   942     recipientCount += header.BccRecipients().Count();
       
   943     
       
   944     // Set multiblerecipient flag 
       
   945     aMessage.SetMultipleRecipients( ( recipientCount > 1 ) );
       
   946         
       
   947     CMsgAddressControl* fromControl = AddressControl(EMsgComponentIdFrom);
       
   948     if (fromControl)
       
   949         {
       
   950         CMsgRecipientArray* fromAddress = fromControl->GetRecipientsL();
       
   951         if (fromAddress->Count() > 0)
       
   952             {
       
   953             CMsgRecipientItem* recItem = fromAddress->At(0);
       
   954             HBufC* fullAddress = ConstructAddressStringLC(recItem);
       
   955             header.SetFromL(*fullAddress);
       
   956             CleanupStack::PopAndDestroy(); // fullAddress
       
   957             }
       
   958         if (iNeedRefresh)
       
   959             {
       
   960             fromControl->RefreshL(*fromAddress);
       
   961             iNeedRefresh = EFalse;
       
   962             }
       
   963         }
       
   964 
       
   965     // save CImHeader information to current entry's store
       
   966     doc->SaveHeaderToStoreL();
       
   967     }
       
   968 
       
   969 // -----------------------------------------------------------------------------
       
   970 // CMsgMailAppUi::SetSmallIconL()
       
   971 // -----------------------------------------------------------------------------
       
   972 //
       
   973 void CMsgMailAppUi::SetSmallIconL()
       
   974     {
       
   975     CAknTitlePane* titlePane = static_cast<CAknTitlePane*>
       
   976         ( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );    
       
   977     if( titlePane )
       
   978         {
       
   979         TParse fileParse;
       
   980         fileParse.Set( KMsgMailMBMFileName, &KDC_APP_BITMAP_DIR, NULL );     
       
   981         CGulIcon* image = AknsUtils::CreateGulIconL(
       
   982             AknsUtils::SkinInstance(),
       
   983             KAknsIIDQgnPropMceEmailTitle,
       
   984             fileParse.FullName(),
       
   985             EMbmMsgmailutilsQgn_prop_mce_email_title,
       
   986             EMbmMsgmailutilsQgn_prop_mce_email_title_mask
       
   987             );
       
   988         TRect mainPane;
       
   989         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ETitlePane, mainPane );
       
   990         TAknLayoutRect titleIconPaneLayoutRect;
       
   991         titleIconPaneLayoutRect.LayoutRect(
       
   992             mainPane,
       
   993             AknLayoutScalable_Avkon::title_pane_g2( 0 ).LayoutLine() );
       
   994     	TSize iconSize = titleIconPaneLayoutRect.Rect( ).Size( );
       
   995     	AknIconUtils::SetSize( image->Bitmap(), iconSize, EAspectRatioPreserved );
       
   996 
       
   997         image->SetBitmapsOwnedExternally( ETrue );	
       
   998     	// takes ownership of bitmaps. Be sure nothing leaves before this
       
   999     	titlePane->SetSmallPicture( image->Bitmap(), image->Mask(), ETrue );
       
  1000         delete image;    	
       
  1001         }
       
  1002     }    
       
  1003 // -----------------------------------------------------------------------------
       
  1004 // CMsgMailAppUi::MailDocument()
       
  1005 // -----------------------------------------------------------------------------
       
  1006 //
       
  1007 CMsgMailDocument* CMsgMailAppUi::MailDocument()
       
  1008     {
       
  1009     return static_cast<CMsgMailDocument*> ( Document() );    
       
  1010     }
       
  1011 
       
  1012 // -----------------------------------------------------------------------------
       
  1013 // CMsgMailAppUi::DoSaveMessageL()
       
  1014 // -----------------------------------------------------------------------------
       
  1015 //
       
  1016 TBool CMsgMailAppUi::DoSaveMessageL( TBool aInPreparation, TBool aReply )
       
  1017     {
       
  1018     CMsgMailDocument* doc = MailDocument();
       
  1019     if ( doc->CurrentEntry().Entry().Id() != iMessageID )
       
  1020         {
       
  1021         doc->SetEntryL( iMessageID );
       
  1022         }
       
  1023     TMsvEmailEntry entry(doc->CurrentEntry().Entry());  
       
  1024     LOG1( "CMsgMailAppUi::DoSaveMessageL entry size: %d", entry.iSize );
       
  1025     entry.SetBodyTextComplete( ETrue );
       
  1026     
       
  1027     ASSERT( entry.Id() == iMessageID );
       
  1028     CheckStoreSpaceL( entry, aReply );
       
  1029 
       
  1030     // set preparation flag
       
  1031     if (!entry.MHTMLEmail() && !aReply)
       
  1032         {
       
  1033         entry.SetInPreparation(aInPreparation);    
       
  1034         // set visible if not in preparation state
       
  1035         entry.SetVisible(!aInPreparation);
       
  1036         UnlockEntry();
       
  1037         doc->CurrentEntry().ChangeL(entry);
       
  1038         }
       
  1039     //-------------------------------
       
  1040     // 1. set variables
       
  1041     //-------------------------------        
       
  1042     TBool returnValue(ETrue);
       
  1043         
       
  1044     //-------------------------------------
       
  1045     // 2. create new message id, if needed
       
  1046     //-------------------------------------    
       
  1047     const TMsvId origMessageId(entry.Id());
       
  1048 
       
  1049     entry.iType = KUidMsvMessageEntry;   
       
  1050 	CMsgMailPreferences& pref = doc->SendOptions();    
       
  1051 	
       
  1052         
       
  1053 	// EMail type       
       
  1054 	entry.iMtm = KUidMsgTypeSMTP;
       
  1055 	// set related service ID
       
  1056 	returnValue = SetServiceIdL( entry, *doc );
       
  1057         
       
  1058     // set Send options
       
  1059     pref.ImportSendOptionsL(entry);        
       
  1060 	// set entry time
       
  1061     SetEntryTimeL( entry );
       
  1062 
       
  1063     //-------------------------------
       
  1064     // 3. set CImHeader fields
       
  1065     //-------------------------------    
       
  1066     SetHeaderFieldsL( entry );
       
  1067 
       
  1068     // store message body
       
  1069     CMsgBodyControl* bodyControl = BodyControl();
       
  1070     if (bodyControl)
       
  1071     	{
       
  1072     	CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
  1073     	doc->MessageL().StoreBodyTextL( 
       
  1074     	    origMessageId,
       
  1075         	bodyControl->TextContent(), 
       
  1076         	wait->iStatus);
       
  1077         	
       
  1078     	wait->Start();
       
  1079     	CleanupStack::PopAndDestroy(); //wait
       
  1080     	}
       
  1081 
       
  1082     //-------------------------------
       
  1083     // 5. update the entry
       
  1084     //-------------------------------
       
  1085     SetEntryFlagsL( entry, origMessageId );
       
  1086 
       
  1087     return returnValue;
       
  1088     }
       
  1089 
       
  1090 // -----------------------------------------------------------------------------
       
  1091 // CMsgMailAppUi::ConstructAddressStringLC()
       
  1092 // -----------------------------------------------------------------------------
       
  1093 //
       
  1094 HBufC* CMsgMailAppUi::ConstructAddressStringLC(CMsgRecipientItem* aRecItem)
       
  1095     {   
       
  1096     HBufC* fullAddress = NULL;    
       
  1097 
       
  1098     // remove illegal characters from user inputted addresses
       
  1099     if (!aRecItem->Name()->Length())
       
  1100         {
       
  1101         TPtr address(aRecItem->Address()->Des());
       
  1102         // won't overflow, only removing characters
       
  1103         if (StripIllegalCharsL(address))
       
  1104             {
       
  1105             aRecItem->SetAddressL(address);
       
  1106             }
       
  1107         }
       
  1108     
       
  1109     // check that address item has alias and address and they are not the same
       
  1110     if (aRecItem->Name()->Length() &&
       
  1111         aRecItem->Name()->Compare(*(aRecItem->Address())) != 0)
       
  1112         {
       
  1113         // 2 Array for name and address
       
  1114         CDesCArrayFlat* strings = new(ELeave) CDesCArrayFlat( 2 );		// CSI: 47 # See a comment above.
       
  1115         CleanupStack::PushL( strings );
       
  1116         
       
  1117         strings->AppendL( *aRecItem->Name() );
       
  1118         strings->AppendL( *aRecItem->Address() );
       
  1119 
       
  1120         fullAddress = StringLoader::LoadL(
       
  1121             R_MAIL_ADDRESS_FORMAT_STRING, *strings, iCoeEnv);
       
  1122         CleanupStack::PopAndDestroy(); // strings
       
  1123         CleanupStack::PushL( fullAddress );
       
  1124         }
       
  1125     // otherwise return just address
       
  1126     else
       
  1127         {
       
  1128         fullAddress = aRecItem->Address()->AllocLC();
       
  1129         }
       
  1130     return fullAddress;
       
  1131     }
       
  1132     
       
  1133 // -----------------------------------------------------------------------------
       
  1134 // CMsgMailAppUi::StripIllegalCharsL()
       
  1135 // -----------------------------------------------------------------------------
       
  1136 //
       
  1137 TBool CMsgMailAppUi::StripIllegalCharsL(TDes& aString)
       
  1138     {
       
  1139     TBool returnValue(EFalse);
       
  1140     // initialise array when called for the 1st time
       
  1141     if (!iBannedChars)
       
  1142         {   
       
  1143         iBannedChars = iEikonEnv->ReadDesC16ArrayResourceL(
       
  1144             R_MAIL_BANNED_CHARS );
       
  1145         iBannedChars->Compress();
       
  1146         }
       
  1147 
       
  1148     // Check that inputted address does not contain illegal characters
       
  1149     // These characters would mess up address inputting if they were saved
       
  1150     const TInt count(iBannedChars->Count());
       
  1151     for (TInt i = 0; i < count; i++)
       
  1152         {    
       
  1153         TInt pos(aString.Find((*iBannedChars)[i]));    
       
  1154         while (pos != KErrNotFound)
       
  1155             {
       
  1156             aString.Delete(pos, 1);
       
  1157             pos = aString.Find((*iBannedChars)[i]);
       
  1158             iNeedRefresh = ETrue;
       
  1159             returnValue = ETrue;
       
  1160             }
       
  1161         }
       
  1162 
       
  1163 	aString.Trim();
       
  1164     return returnValue;
       
  1165     }
       
  1166 
       
  1167 // -----------------------------------------------------------------------------
       
  1168 // CMsgMailAppUi::AppendRecipientsL()
       
  1169 // -----------------------------------------------------------------------------
       
  1170 //
       
  1171 void CMsgMailAppUi::AppendRecipientsL( 
       
  1172     CMsgAddressControl* aField, CDesCArray& aArray )
       
  1173 	{
       
  1174     aArray.Reset();	
       
  1175 	
       
  1176 	if ( aField )
       
  1177 	    {
       
  1178     	const CMsgRecipientArray* recipients = aField->GetRecipientsL();
       
  1179     	const TInt count(recipients->Count());
       
  1180     	for (TInt i=0; i < count; i++)
       
  1181     		{
       
  1182     		CMsgRecipientItem* recItem = recipients->At(i);
       
  1183     		HBufC* fullAddress = ConstructAddressStringLC(recItem);
       
  1184     		aArray.AppendL(*fullAddress);
       
  1185     		CleanupStack::PopAndDestroy(); // fullAddress
       
  1186     		}
       
  1187 
       
  1188     	if (iNeedRefresh)
       
  1189     		{
       
  1190     		aField->RefreshL(*recipients);
       
  1191     		iNeedRefresh = EFalse;
       
  1192     		}
       
  1193 	    }
       
  1194 	}
       
  1195 
       
  1196 // -----------------------------------------------------------------------------
       
  1197 // CMsgMailAppUi::CheckFFSL()
       
  1198 // -----------------------------------------------------------------------------
       
  1199 //
       
  1200 EXPORT_C TBool CMsgMailAppUi::CheckFFSL(const TInt aSize)
       
  1201     {
       
  1202     return MailDocument()->DiskSpaceBelowCriticalLevelL( aSize );
       
  1203     }
       
  1204 
       
  1205 // -----------------------------------------------------------------------------
       
  1206 // CMsgMailAppUi::IsBannedMimeL()
       
  1207 // -----------------------------------------------------------------------------
       
  1208 //    
       
  1209 EXPORT_C TBool CMsgMailAppUi::IsBannedMimeL(const TDesC& /*aBuf*/) const
       
  1210     {
       
  1211     // Use MailUtils::IsClosedFileL instead of this 
       
  1212     User::Leave( KErrNotSupported );
       
  1213     return EFalse;
       
  1214     }
       
  1215 // -----------------------------------------------------------------------------
       
  1216 // CMsgMailAppUi::IsValidAddress()
       
  1217 // -----------------------------------------------------------------------------
       
  1218 // 
       
  1219 EXPORT_C TBool CMsgMailAppUi::IsValidAddress( const TDesC& aAddress ) const
       
  1220 	{
       
  1221 	TLex lex( aAddress );
       
  1222 	return Address( lex ) && lex.Eos();
       
  1223 	}
       
  1224 
       
  1225 // -----------------------------------------------------------------------------
       
  1226 // CMsgMailAppUi::CheckIfBannedL()
       
  1227 // -----------------------------------------------------------------------------
       
  1228 // 
       
  1229 EXPORT_C TBool CMsgMailAppUi::CheckIfBannedL(const TDesC& /*aMimeType*/)
       
  1230     {
       
  1231     // Use MailUtils::IsClosedFileL instead of this
       
  1232     User::Leave( KErrNotSupported );
       
  1233     return EFalse;
       
  1234     }
       
  1235 
       
  1236 // -----------------------------------------------------------------------------
       
  1237 // CMsgMailAppUi::CheckIfBannedL()
       
  1238 // -----------------------------------------------------------------------------
       
  1239 // 
       
  1240 EXPORT_C TBool CMsgMailAppUi::CheckIfBannedL(RFile& /*aFile*/)
       
  1241     {
       
  1242     // Use MailUtils::IsClosedFileL instead of this
       
  1243     User::Leave( KErrNotSupported );
       
  1244     return EFalse;		
       
  1245     }    
       
  1246 
       
  1247 // -----------------------------------------------------------------------------
       
  1248 // CMsgMailAppUi::CleanupWaitNoteWrapper()
       
  1249 // -----------------------------------------------------------------------------
       
  1250 // 
       
  1251 EXPORT_C void CMsgMailAppUi::CleanupWaitNoteWrapper(TAny* aAny)
       
  1252     {
       
  1253     CAknWaitNoteWrapper** wrapper = STATIC_CAST(CAknWaitNoteWrapper**, aAny);
       
  1254     if (wrapper && *wrapper)
       
  1255         {
       
  1256         delete *wrapper;
       
  1257         *wrapper = NULL;
       
  1258         }
       
  1259     }
       
  1260 
       
  1261 // -----------------------------------------------------------------------------
       
  1262 // CMsgMailAppUi::CleanupWaitDialog()
       
  1263 // -----------------------------------------------------------------------------
       
  1264 // 
       
  1265 EXPORT_C void CMsgMailAppUi::CleanupWaitDialog(TAny* aAny)
       
  1266     {
       
  1267     CAknWaitDialog** dialog = STATIC_CAST(CAknWaitDialog**, aAny);
       
  1268     if (dialog && *dialog)
       
  1269         {
       
  1270         delete *dialog;
       
  1271         *dialog = NULL;
       
  1272         }
       
  1273     }
       
  1274 
       
  1275 // -----------------------------------------------------------------------------
       
  1276 // CMsgMailAppUi::MessageSizeL()
       
  1277 // -----------------------------------------------------------------------------
       
  1278 //     
       
  1279 EXPORT_C TInt CMsgMailAppUi::MessageSizeL( TBool aCountAttachments )	// CSI: 40 # We must return 
       
  1280 																		// the integer value although this 
       
  1281 																		// is a leaving method.
       
  1282     {
       
  1283     // calculate message size 
       
  1284     const TInt multibleByTwoForUnicode(2);
       
  1285 
       
  1286     TInt fieldSize(0);
       
  1287     TInt count;
       
  1288 
       
  1289     CMsgAddressControl* addressField;
       
  1290     
       
  1291     addressField = AddressControl( EMsgComponentIdTo );
       
  1292     if (addressField)
       
  1293         {
       
  1294         addressField->GetSizeOfAddresses(count, fieldSize);
       
  1295         }
       
  1296     TInt docSize(fieldSize);
       
  1297     addressField = AddressControl( EMsgComponentIdCc );
       
  1298     if (addressField)
       
  1299         {
       
  1300         addressField->GetSizeOfAddresses(count, fieldSize);
       
  1301         docSize += fieldSize;
       
  1302         }
       
  1303 
       
  1304     addressField = AddressControl( EMsgComponentIdBcc );
       
  1305     if (addressField)
       
  1306         {
       
  1307         addressField->GetSizeOfAddresses(count, fieldSize);
       
  1308         docSize += fieldSize;
       
  1309         }
       
  1310 
       
  1311     if( SubjectControl() )
       
  1312         {
       
  1313         docSize += SubjectControl()->TextContent().DocumentLength() 
       
  1314             * multibleByTwoForUnicode;
       
  1315         }    
       
  1316     CRichText& rtf = BodyControl()->TextContent();
       
  1317     docSize += rtf.DocumentLength() * multibleByTwoForUnicode;
       
  1318     
       
  1319     // Attachments
       
  1320     if ( aCountAttachments )
       
  1321         {        
       
  1322         CMsgAttachmentModel& attModel = Document()->AttachmentModel();
       
  1323         const TInt attCount( attModel.NumberOfItems() );    
       
  1324         
       
  1325         for (TInt cc=0; cc < attCount; cc++)
       
  1326             {
       
  1327             docSize += attModel.AttachmentInfoAt(cc).Size();
       
  1328             }
       
  1329         }    
       
  1330     
       
  1331     LOG1( "CMsgMailAppUi::MessageSizeL: %d", docSize );
       
  1332     return docSize;     
       
  1333     }
       
  1334 
       
  1335 // -----------------------------------------------------------------------------
       
  1336 // CMsgMailAppUi::SetDialerEnabled()
       
  1337 // -----------------------------------------------------------------------------
       
  1338 // 
       
  1339 EXPORT_C void CMsgMailAppUi::SetDialerEnabled( TBool aEnable )
       
  1340     {
       
  1341     if( aEnable )
       
  1342         {
       
  1343         // send key handling enabled
       
  1344         SetKeyEventFlags( 0 );
       
  1345         }
       
  1346     else
       
  1347         {
       
  1348         // send key handling disabled
       
  1349         SetKeyEventFlags( 
       
  1350             CAknAppUiBase::EDisableSendKeyShort | 
       
  1351             CAknAppUiBase::EDisableSendKeyLong );        
       
  1352         }
       
  1353     }
       
  1354 
       
  1355 // -----------------------------------------------------------------------------
       
  1356 // CMsgMailAppUi::MakeDetailsLC()
       
  1357 // -----------------------------------------------------------------------------
       
  1358 // 
       
  1359 HBufC* CMsgMailAppUi::MakeDetailsLC( CMsgAddressControl& aControl )
       
  1360     {
       
  1361     // Array is owned by the control
       
  1362     CMsgRecipientArray* recipients = aControl.GetRecipientsL();
       
  1363     TInt recipCount = recipients->Count();
       
  1364     
       
  1365     LOG1( "CMsgMailAppUi::MakeDetailsLC: %d Recipient(s)", recipCount );        
       
  1366     if( recipCount == 0 )
       
  1367         {
       
  1368         // no recipients
       
  1369         return KNullDesC().AllocLC();
       
  1370         }
       
  1371     
       
  1372     // Append recipients to text.
       
  1373     HBufC* detailsBuf = HBufC::NewLC( KMsgMaxDetailsLength );
       
  1374     TPtr details( detailsBuf->Des() );
       
  1375     TInt separatorLen = KMsgDetailsSeparator().Length();
       
  1376     
       
  1377     for( TInt i = 0; i < recipCount; ++i )
       
  1378         {
       
  1379         CMsgRecipientItem* item = recipients->At(i);
       
  1380 
       
  1381         // Select name or address (prefer name if available)
       
  1382         HBufC* textToAdd = item->Name();
       
  1383         if( !textToAdd )
       
  1384             {
       
  1385             textToAdd = item->Address();
       
  1386             }
       
  1387         else if( textToAdd->Length() == 0 )
       
  1388             {
       
  1389             textToAdd = item->Address();
       
  1390             }
       
  1391         
       
  1392         if( textToAdd )
       
  1393             {
       
  1394             TInt textSpace = KMsgMaxDetailsLength - details.Length();
       
  1395             
       
  1396             // Append separator
       
  1397             if( textSpace < separatorLen )
       
  1398                 {
       
  1399                 // no space for separator -> all done
       
  1400                 break;
       
  1401                 }
       
  1402             if( details.Length() > 0 )
       
  1403                 {
       
  1404                 // not a first recipient -> add separator
       
  1405                 details.Append( KMsgDetailsSeparator );
       
  1406                 textSpace -= separatorLen;
       
  1407                 }
       
  1408             
       
  1409             // Append recipient's name or address
       
  1410             details.Append( textToAdd->Left( textSpace ) );
       
  1411             
       
  1412             if( KMsgMaxDetailsLength - details.Length() <= 0 )
       
  1413                 {
       
  1414                 // No more space -> all done
       
  1415                 break;
       
  1416                 }
       
  1417             }
       
  1418         }
       
  1419     
       
  1420     return detailsBuf;
       
  1421     }
       
  1422 
       
  1423 
       
  1424 //  End of File