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