messagingapp/msgutils/unidatamodel/unimmsdataplugin/src/UniTextObject.cpp
changeset 25 84d9eb65b26f
parent 23 238255e8b033
child 27 e4592d119491
child 37 518b245aa84c
child 79 2981cb3aa489
equal deleted inserted replaced
23:238255e8b033 25:84d9eb65b26f
     1 /*
       
     2 * Copyright (c) 2005 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: 
       
    15 *       CUniTextObject, Storage for single text attachment in presentation.
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // ========== INCLUDE FILES ================================
       
    22 
       
    23 #include <e32def.h>     // for basic types
       
    24 #include <eikenv.h>     // for CBase
       
    25 #include <mtclbase.h>   // for CBaseMtm
       
    26 #include <msvstd.h>     // for TMsvId
       
    27 #include <msvids.h>     // for KMsvTempIndexEntryId
       
    28 #include <msvstore.h>
       
    29 #include <mmsvattachmentmanager.h>
       
    30 #include <cmsvattachment.h>
       
    31 
       
    32 #include <eikrted.h>    // CEikRichTextEditor
       
    33 #include <charconv.h>
       
    34 
       
    35 
       
    36 #include <MsgMediaInfo.h>
       
    37 #include <MsgTextInfo.h>
       
    38 #include <MsgAttachmentUtils.h>
       
    39 
       
    40 #include "msgtextutils.h"
       
    41 #include "UniModelConst.h"
       
    42 #include "UniMimeInfo.h"
       
    43 #include "UniObject.h"
       
    44 #include "UniTextObject.h"
       
    45 #include "UniDataUtils.h"
       
    46 //rushi
       
    47 #include "MsgMimeTypes.h"
       
    48 #include "MuiuOperationWait.h"
       
    49 
       
    50 
       
    51 // ========== EXTERNAL DATA STRUCTURES =====================
       
    52 
       
    53 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    54 
       
    55 // ========== CONSTANTS ====================================
       
    56 
       
    57 // ========== MACROS =======================================
       
    58 
       
    59 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    60 const TInt KMaxFilenameLenghtForAttachment = 20;   // Characters
       
    61 
       
    62 const TInt KMaxCharSize = 3;
       
    63 const TInt KMinCharSize = 1;
       
    64 // Always count exact size
       
    65 // -> performance penalty with very long text files.
       
    66 const TInt KSyncInterval = 0;
       
    67 const TInt KForceSyncLength = KMaxTInt;
       
    68 
       
    69 _LIT16( KExtTextPlain_16, ".txt" );
       
    70 
       
    71 
       
    72 // ========== MODULE DATA STRUCTURES =======================
       
    73 
       
    74 
       
    75 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    76 
       
    77 // ========== LOCAL FUNCTIONS ==============================
       
    78 
       
    79 // ========== MEMBER FUNCTIONS =============================
       
    80 
       
    81 // ---------------------------------------------------------
       
    82 // CUniTextObject::NewLC
       
    83 //
       
    84 // Factory method.
       
    85 // ---------------------------------------------------------
       
    86 //
       
    87 CUniTextObject* CUniTextObject::NewLC( RFs& aFs,
       
    88                                                CBaseMtm& aMtm,
       
    89                                                CUniDataUtils& aData,
       
    90                                                CMsgTextInfo* aMedia,
       
    91                                                MMsvAttachmentManager& aManager,
       
    92                                                CMsvAttachment& aAttachment )
       
    93     {
       
    94     CUniTextObject* self =
       
    95         new ( ELeave ) CUniTextObject( aFs, aMtm, aData, aMedia );
       
    96     CleanupStack::PushL( self );
       
    97     self->ConstructL();
       
    98     self->ConstructFromAttachmentL( aManager, aAttachment );
       
    99     return self;
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------
       
   103 // CUniTextObject::NewL
       
   104 //
       
   105 // Factory method.
       
   106 // ---------------------------------------------------------
       
   107 //
       
   108 CUniTextObject* CUniTextObject::NewL( RFs& aFs,
       
   109                                               CBaseMtm& aMtm,
       
   110                                               CUniDataUtils& aData,
       
   111                                               CMsgTextInfo* aMedia,
       
   112                                               MMsvAttachmentManager& aManager,
       
   113                                               CMsvAttachment& aAttachment )
       
   114     {
       
   115     CUniTextObject* self = NewLC( aFs, aMtm, aData, aMedia, aManager, aAttachment );
       
   116     CleanupStack::Pop( self );
       
   117     return self;
       
   118     }
       
   119 
       
   120 // ---------------------------------------------------------
       
   121 // CUniTextObject::NewLC
       
   122 //
       
   123 // Factory method.
       
   124 // ---------------------------------------------------------
       
   125 //
       
   126 CUniTextObject* CUniTextObject::NewLC( RFs& aFs,
       
   127                                                CBaseMtm& aMtm,
       
   128                                                CUniDataUtils& aData,
       
   129                                                CMsgTextInfo* aMedia )
       
   130     {
       
   131     CUniTextObject* self =
       
   132         new ( ELeave ) CUniTextObject( aFs, aMtm, aData, aMedia );
       
   133     CleanupStack::PushL( self );
       
   134     self->ConstructL();
       
   135     self->CreateMimeInfoL();
       
   136     return self;
       
   137     }
       
   138 
       
   139 // ---------------------------------------------------------
       
   140 // CUniTextObject::NewL
       
   141 //
       
   142 // Factory method.
       
   143 // ---------------------------------------------------------
       
   144 //
       
   145 CUniTextObject* CUniTextObject::NewL( RFs& aFs,
       
   146                                               CBaseMtm& aMtm,
       
   147                                               CUniDataUtils& aData,
       
   148                                               CMsgTextInfo* aMedia )
       
   149     {
       
   150     CUniTextObject* self = NewLC( aFs, aMtm, aData, aMedia );
       
   151     CleanupStack::Pop( self );
       
   152     return self;
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------
       
   156 // CUniTextObject::NewLC
       
   157 //
       
   158 // Factory method.
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 CUniTextObject* CUniTextObject::NewLC( RFs& aFs,
       
   162                                                CBaseMtm& aMtm,
       
   163                                                CUniDataUtils& aData,
       
   164                                                CEikRichTextEditor* aTextEditor )
       
   165     {
       
   166     RFile nullHandle;
       
   167     TDataType mime( KMsgMimeTextPlain );
       
   168     CMsgTextInfo* info = CMsgTextInfo::NewL(
       
   169         nullHandle,
       
   170         mime,
       
   171         aFs );
       
   172     info->SetCharacterSet( KCharacterSetMIBEnumUtf8 );
       
   173     CleanupStack::PushL( info );
       
   174     CUniTextObject* self =
       
   175         new ( ELeave ) CUniTextObject( aFs, aMtm, aData, info );
       
   176     CleanupStack::Pop( info ); // ownership transferred
       
   177     CleanupStack::PushL( self );
       
   178     self->ConstructL();
       
   179     self->ConstructFromTextL( aTextEditor );
       
   180     self->SynchronizeSize();
       
   181     return self;
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------
       
   185 // CUniTextObject::NewL
       
   186 //
       
   187 // Factory method.
       
   188 // ---------------------------------------------------------
       
   189 //
       
   190 CUniTextObject* CUniTextObject::NewL( RFs& aFs,
       
   191                                               CBaseMtm& aMtm,
       
   192                                               CUniDataUtils& aData,
       
   193                                               CEikRichTextEditor* aTextEditor )
       
   194     {
       
   195     CUniTextObject* self = NewLC( aFs, aMtm, aData, aTextEditor );
       
   196     CleanupStack::Pop( self );
       
   197     return self;
       
   198     }
       
   199 
       
   200 
       
   201 // ---------------------------------------------------------
       
   202 // CUniTextObject::CUniTextObject
       
   203 //
       
   204 // Constructor.
       
   205 // ---------------------------------------------------------
       
   206 //
       
   207 CUniTextObject::CUniTextObject( RFs& aFs,
       
   208                                CBaseMtm& aMtm,
       
   209                                CUniDataUtils& aData,
       
   210                                CMsgTextInfo* aMedia )
       
   211         :
       
   212         CUniObject( aFs, aMtm, aData, aMedia ),
       
   213         iTextEditor( NULL )
       
   214     {
       
   215     }
       
   216 
       
   217 
       
   218 // ---------------------------------------------------------
       
   219 // CUniTextObject::CUniTextObject
       
   220 //
       
   221 // Destructor.
       
   222 // ---------------------------------------------------------
       
   223 //
       
   224 CUniTextObject::~CUniTextObject()
       
   225     {
       
   226     if ( iEditFile )
       
   227         {
       
   228         iEditFile->Close();
       
   229         delete iEditFile;
       
   230         }
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------
       
   234 // CUniTextObject::Save
       
   235 // ---------------------------------------------------------
       
   236 //
       
   237 void CUniTextObject::Save( MUniObjectSaveObserver& aObserver,
       
   238                            CMsvAttachment::TMsvAttachmentType aSaveType )
       
   239     {
       
   240     iTextSaveState = ETextSavingIdle;
       
   241     CUniObject::Save( aObserver, aSaveType );
       
   242     }
       
   243 
       
   244 // ---------------------------------------------------------
       
   245 // CUniTextObject::DoSaveL
       
   246 // ---------------------------------------------------------
       
   247 //
       
   248 void CUniTextObject::DoSaveL()
       
   249     {
       
   250     switch ( iTextSaveState )
       
   251         {
       
   252         case ETextSavingIdle:
       
   253             {
       
   254             InitializeTextSaveL();
       
   255             break;
       
   256             }
       
   257         case ETextCreatingAttachment:
       
   258             {
       
   259             CreateTextAttachmentL();
       
   260             break;
       
   261             }
       
   262         case ETextWritingToFile:
       
   263             {
       
   264             WriteToFileL();
       
   265             break;
       
   266             }
       
   267         default:
       
   268             {
       
   269             break;
       
   270             }
       
   271         }
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------
       
   275 // CUniTextObject::Size
       
   276 //
       
   277 // Accessor.
       
   278 // ---------------------------------------------------------
       
   279 //
       
   280 TInt CUniTextObject::Size( TBool aWithoutHeaders )
       
   281     {
       
   282     if ( iTextEditor && iTextEditor->TextLength() )
       
   283         {
       
   284         TInt size = 0;
       
   285         TInt length = iTextEditor->TextLength();
       
   286         TInt change = length - iPrevLength;
       
   287         if ( change )
       
   288             {
       
   289             //add absolute value
       
   290             iSyncCounter += Max( change, -change );
       
   291             iPrevLength = length;
       
   292             }
       
   293         if ( iSyncCounter > KSyncInterval ||
       
   294             length <= KForceSyncLength )
       
   295             {
       
   296             size = SynchronizeSize();
       
   297             }
       
   298         else
       
   299             {
       
   300             TInt diff = length - iSyncLength;
       
   301             TInt charSize = diff < 0
       
   302                 ? KMinCharSize
       
   303                 : KMaxCharSize;
       
   304             size = iSyncSize + charSize * diff;
       
   305             size = Max( size, 0 );
       
   306             }
       
   307         return ( aWithoutHeaders ? size : size + iMimeInfo->Size() );
       
   308         }
       
   309     else
       
   310         {
       
   311         return CUniObject::Size( aWithoutHeaders );
       
   312         }
       
   313     }
       
   314 
       
   315 // ---------------------------------------------------------
       
   316 // CUniTextObject::SyncronizeSize
       
   317 //
       
   318 // Counts real buffer size and syncronizes internal
       
   319 // size variables.
       
   320 // ---------------------------------------------------------
       
   321 //
       
   322 TInt CUniTextObject::SynchronizeSize()
       
   323     {
       
   324     iSyncCounter = 0;
       
   325     if ( iTextEditor )
       
   326         {
       
   327         iSyncLength = iTextEditor->TextLength();
       
   328         iPrevLength = iSyncLength;
       
   329         TPtrC ptr = iTextEditor->Text()->Read( 0, iTextEditor->Text()->DocumentLength() );
       
   330         iSyncSize = CUniDataUtils::UTF8Size( ptr );
       
   331         }
       
   332     else
       
   333         {
       
   334         iSyncSize = 0;
       
   335         iSyncLength = 0;
       
   336         iPrevLength = 0;
       
   337         }
       
   338     return iSyncSize;
       
   339     }
       
   340 
       
   341 // ---------------------------------------------------------
       
   342 // CUniTextObject::ConstructL
       
   343 //
       
   344 // 2nd phase constructor.
       
   345 // ---------------------------------------------------------
       
   346 //
       
   347 void CUniTextObject::ConstructL()
       
   348     {
       
   349     CUniObject::ConstructL();
       
   350     }
       
   351 
       
   352 // ---------------------------------------------------------
       
   353 // CUniTextObject::ConstructFromTextL
       
   354 //
       
   355 // 2nd phase constructor.
       
   356 // ---------------------------------------------------------
       
   357 //
       
   358 void CUniTextObject::ConstructFromTextL( CEikRichTextEditor* aTextEditor )
       
   359     {
       
   360     iAttachmentId = KMsvNullIndexEntryId;
       
   361     iTextEditor = aTextEditor;
       
   362     //iStoreState = EMmsStoreStateTemporary;
       
   363     //Create MIME headers
       
   364     CreateMimeInfoL();
       
   365     }
       
   366 
       
   367 // ---------------------------------------------------------
       
   368 // CreateFileName
       
   369 // ---------------------------------------------------------
       
   370 //
       
   371 void CUniTextObject::CreateFileName( TFileName& aFileName )
       
   372     {
       
   373     if ( iTextEditor && iTextEditor->Text()->DocumentLength() )
       
   374         {
       
   375     	TPtrC ptr = iTextEditor->Text()->Read( 0, KMaxFilenameLenghtForAttachment );
       
   376         MsgAttachmentUtils::GetFileNameFromBuffer(
       
   377             aFileName,
       
   378             ptr,
       
   379             KMaxFilenameLenghtForAttachment,
       
   380             &KExtTextPlain_16 );
       
   381         }
       
   382     if ( aFileName.Length() == 0 ||
       
   383         !iFs.IsValidName( aFileName ) )
       
   384         {
       
   385         // No filename -> Use default
       
   386         aFileName.Zero();
       
   387         aFileName.Copy( iData.DefaultFileName() );
       
   388         aFileName.Append( KExtTextPlain_16 );
       
   389         }
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------
       
   393 // InitializeTextSaveL
       
   394 // ---------------------------------------------------------
       
   395 //
       
   396 void CUniTextObject::InitializeTextSaveL()
       
   397     {
       
   398     if ( !iTextEditor )
       
   399         {
       
   400         CUniObject::DoSaveL();
       
   401         return;
       
   402         }
       
   403 
       
   404     // Remove possibly already existing attachment from store
       
   405     RemoveFromStoreL();
       
   406 
       
   407     if ( !iTextEditor->TextLength() )
       
   408         {
       
   409         //Nothing to save. (Shouldn't really get here
       
   410         //since there shouldn't be "empty" text objects
       
   411         //in the smil model.)
       
   412         iObserver->ObjectSaveReady( KErrNone );
       
   413         return;
       
   414         }
       
   415     iTextSaveState = ETextCreatingAttachment;
       
   416     //CompleteSelf();
       
   417     RunL();
       
   418     }
       
   419 
       
   420 // ---------------------------------------------------------
       
   421 // CreateTextAttachmentL
       
   422 // ---------------------------------------------------------
       
   423 //
       
   424 void CUniTextObject::CreateTextAttachmentL()
       
   425     {
       
   426     TFileName fileName;
       
   427     CreateFileName( fileName );
       
   428 
       
   429     TFileName contentLocation( fileName );
       
   430     CMsgTextUtils::TrimAndRemoveNonAlphaDigit( contentLocation );
       
   431     iMimeInfo->SetContentLocationL( contentLocation );
       
   432     iMimeInfo->SetContentTypeL( KMsgMimeTextPlain );
       
   433     iMimeInfo->SetCharset( KCharacterSetMIBEnumUtf8 );
       
   434 
       
   435     iEditStore = iMtm.Entry().EditStoreL();
       
   436     iManager = &( iEditStore->AttachmentManagerL() );
       
   437     CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   438     CleanupStack::PushL( attachment );
       
   439 
       
   440     attachment->SetMimeTypeL( KMsgMimeTextPlain );
       
   441     attachment->SetSize( SynchronizeSize() );
       
   442     //TODO: Set complete flag?
       
   443     //attachment->SetComplete( EFalse );
       
   444 
       
   445     attachment->SetIntAttributeL( KUidAttachmentIndication, Attachment() );
       
   446 
       
   447     iEditFile = new ( ELeave ) RFile;
       
   448 
       
   449     //Make this synchronous process
       
   450     CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
   451     
       
   452     iManager->CreateAttachmentL( fileName, *iEditFile, attachment, wait->iStatus );
       
   453     wait->Start();
       
   454     
       
   455     CleanupStack::PopAndDestroy( wait );
       
   456     	
       
   457     CleanupStack::Pop( attachment );
       
   458     iAttachment = attachment;
       
   459     iTextSaveState = ETextWritingToFile;
       
   460     
       
   461     //SetActive();
       
   462     RunL();
       
   463     }
       
   464 
       
   465 // ---------------------------------------------------------
       
   466 // WriteToFileL
       
   467 // ---------------------------------------------------------
       
   468 //
       
   469 void CUniTextObject::WriteToFileL()
       
   470     {
       
   471     RFileWriteStream writer( *iEditFile );
       
   472     delete iEditFile;
       
   473     iEditFile = NULL;
       
   474 
       
   475     // Write the text to a file
       
   476 
       
   477     // UTF-8 signature
       
   478     // Taken out because not all terminals can deal with it.
       
   479     // Maybe taken back into use in the future
       
   480     //writer.WriteInt8L( 0xEF );
       
   481     //writer.WriteInt8L( 0xBB );
       
   482     //writer.WriteInt8L( 0xBF );
       
   483 
       
   484     HBufC* buffer = iTextEditor->GetTextInHBufL();
       
   485     CleanupStack::PushL( buffer );
       
   486 
       
   487     // Convert the text to utf8
       
   488     CCnvCharacterSetConverter* converter = CCnvCharacterSetConverter::NewLC();
       
   489 
       
   490     if ( converter->PrepareToConvertToOrFromL( KCharacterSetIdentifierUtf8, iFs )
       
   491         != CCnvCharacterSetConverter::EAvailable )
       
   492         {
       
   493         User::Leave( KErrNotSupported );
       
   494         }
       
   495 
       
   496     TBuf8<128> outputBuffer;
       
   497     TPtrC16 remainderOfUnicodeText( *buffer );
       
   498     FOREVER
       
   499         {
       
   500         TInt returnValue = converter->ConvertFromUnicode(
       
   501             outputBuffer, remainderOfUnicodeText );
       
   502         if ( returnValue == CCnvCharacterSetConverter::EErrorIllFormedInput )
       
   503             {
       
   504             User::Leave( KErrCorrupt );
       
   505             }
       
   506         else if ( returnValue<0 ) // future-proof against "TError" expanding
       
   507             {
       
   508             User::Leave( KErrGeneral );
       
   509             }
       
   510 
       
   511         // ? - do something here with outputBuffer
       
   512         writer.WriteL( outputBuffer );
       
   513 
       
   514         if ( returnValue == 0 )
       
   515             {
       
   516             break; // all of aUnicodeText has been converted and handled
       
   517             }
       
   518         remainderOfUnicodeText.Set( remainderOfUnicodeText.Right(
       
   519             returnValue ) );
       
   520         }
       
   521 
       
   522     CleanupStack::PopAndDestroy( 2, buffer ); //converter, buffer
       
   523 
       
   524     // Close handles
       
   525     writer.Close();
       
   526     //TInt fileSize( 0 );
       
   527     //iEditFile->Size( fileSize );
       
   528     //iAttachment->SetSize( fileSize );
       
   529     //iEditFile->Close();
       
   530     //delete iEditFile;
       
   531     //iEditFile = NULL;
       
   532 
       
   533     // Closes & destroys other "attachment handling" members
       
   534     // Sends callback to observer
       
   535     FinalizeObjectSaveL();
       
   536     }
       
   537 
       
   538 
       
   539 // End of file