examples/ForumNokia/S60_3rd_Edition_TextMTM_Example/modules/Server/src/TXTMBOX.CPP

00001 // TXTMBOX.CPP
00002 //
00003 // Copyright (c) 1999 Symbian Ltd.  All rights reserved.
00004 //
00005 
00006 #if !defined(__TXTSPAN_H__)
00007 #include "TXTSPAN.H"
00008 #endif
00009 
00010 #if !defined(__MSVUIDS_H__)
00011 #include <MSVUIDS.H>
00012 #endif
00013 
00014 #if !defined(__MSVIDS_H__)
00015 #include <MSVIDS.H>
00016 #endif
00017 
00018 #include "txtmbox.h"
00019 #include "badesca.h"
00020 //#include <mncnnotification.h> 
00021 
00022 #include <TXTRICH.H>
00023 #include <S32FILE.H>
00024 
00025 //
00026 //      CTxtRefreshMBox: refresher class to synchronise real file system and service
00027 //
00028 
00029 
00030 
00031 CTxtRefreshMBox* CTxtRefreshMBox::NewL(RFs& aFs, TFileName& aRelativePath, TMsvId aCurrentRootEntryId, 
00032                                                                            CMsvServerEntry *aEntry, TMsvId aServiceEntryId,
00033                                                                            const TMTMTxtSettings& aTxtSettings)
00034 //
00035 //  1. sort files and entries by description.
00036 //
00037         {
00038         CTxtRefreshMBox* self = new (ELeave)CTxtRefreshMBox(aFs, aRelativePath, 
00039                 aCurrentRootEntryId, aEntry, aServiceEntryId, aTxtSettings);
00040         CleanupStack::PushL(self);
00041         self->ConstructL();
00042         CleanupStack::Pop(); // self
00043         return self;
00044         }       
00045         
00046 void CTxtRefreshMBox::ConstructL()
00047         {
00048         // Find absolute path of folder to refresh
00049         TFileName fullPath = iTxtSettings.RootFolder();         
00050         fullPath.Append(iRelativePath);
00051         
00052         // Get directory list
00053         User::LeaveIfError(iFs.GetDir(fullPath, KEntryAttDir | KEntryAttNormal,ESortByName 
00054                 | EDirsAnyOrder | EAscending, iFilelist));
00055 
00056         // Get sorted list of current entries
00057         iExistingEntries = new (ELeave) CMsvEntrySelection;
00058         TMsvSelectionOrdering order(KMsvNoGrouping, EMsvSortByDescription);    
00059     User::LeaveIfError(iEntry->SetEntry(iCurrentRootEntryId));
00060         iEntry->SetSort( order );
00061         iEntry->GetChildren(*iExistingEntries);
00062 
00063         iCurrentFile  = 0;
00064         iCurrentEntry = 0;
00065         }
00066 
00067 CTxtRefreshMBox::~CTxtRefreshMBox()
00068         {
00069         delete iExistingEntries;
00070         delete iFilelist;
00071         }
00072 
00073 
00074 void CTxtRefreshMBox::DeleteEntryL()
00075 // Delete current entry
00076         {
00077 
00078         __ASSERT_DEBUG(iCurrentEntry < iExistingEntries->Count(), gPanic(ETxtsInvalidEntryIndex));
00079 
00080         User::LeaveIfError(iEntry->SetEntry(iCurrentRootEntryId));
00081         iEntry->DeleteEntry((*iExistingEntries)[iCurrentEntry]); // deletes recursively
00082         }
00083 
00084 
00085 // This function does not work
00086 /*      
00087 void CTxtRefreshMBox::CallNewMessagesL() 
00088         {
00089         MNcnNotification* notification = NULL;
00090 
00091     CDesCArrayFlat* dummyArray = new (ELeave) CDesCArrayFlat( 1 );
00092     CleanupStack::PushL( dummyArray );
00093 
00094     //Connect to NCN
00095     TRAP_IGNORE( notification =
00096         MNcnNotification::CreateMNcnNotificationL() );
00097 
00098     if ( notification )
00099         {
00100         TInt result = notification->NewMessages(
00101             iServiceEntryId,  MNcnNotification::EIndicationToneAndIcon , *dummyArray );
00102         }
00103   
00104     CleanupStack::PopAndDestroy( dummyArray );
00105     dummyArray = NULL;
00106     delete notification;
00107     notification = NULL;        
00108         }
00109 */      
00110 TInt CTxtRefreshMBox::CreateChild(const TDesC& aDescription, const TDesC& aDetails, TUid aMessageType, 
00111                                                                   const TTime& aDate, const TInt aSize)
00112 //
00113 // Create a child. return its Id.
00114 //
00115         {
00116         TMsvEntry newChildEntry;
00117         newChildEntry.iType= aMessageType;
00118         newChildEntry.iMtm = KUidMsgTypeText;
00119         newChildEntry.iDescription.Set(aDescription);
00120         newChildEntry.iDetails.Set(aDetails);              
00121         newChildEntry.iServiceId = iServiceEntryId;
00122         newChildEntry.iSize = aSize;
00123         newChildEntry.iDate=aDate;
00124 
00125         newChildEntry.SetUnread(ETrue);
00126     newChildEntry.SetNew(ETrue);
00127     newChildEntry.SetInPreparation( EFalse );
00128     newChildEntry.SetVisible( ETrue ); // create invisible entry first.
00129 
00130     iEntry->CreateEntry(newChildEntry);
00131         // Notification
00132 //      CallNewMessagesL();
00133         
00134         return newChildEntry.Id();
00135 
00136 
00137         }
00138 
00139 TMsvId CTxtRefreshMBox::InsertFileL()
00140 // Insert file in entries list
00141 //
00142 // Return the new id if this is a folder entry, or KMsvNullIndexEntryId if it isn't
00143 //
00144         {
00145         __ASSERT_DEBUG(iCurrentFile < iFilelist->Count(), gPanic(ETxtsInvalidEntryIndex));
00146         User::LeaveIfError(iEntry->SetEntry( iCurrentRootEntryId ));
00147         TEntry fileEntry = (*iFilelist)[iCurrentFile];
00148         TTime date;
00149         TInt size;
00150         if (fileEntry.IsDir())
00151                 {
00152                 date.HomeTime();
00153                 size=0;
00154                 return CreateChild(fileEntry.iName, fileEntry.iName, KUidMsvFolderEntry, date, size);
00155                 }
00156         else
00157                 {
00158                 TFileName filename = iTxtSettings.RootFolder();
00159                 filename.Append(iRelativePath);
00160                 filename.Append(fileEntry.iName);
00161                 RFile file;
00162                 User::LeaveIfError(file.Open(iFs,filename,EFileRead));
00163 
00164         // get time from HomeTime instead of file.Modified because old files cannot be notified. 
00165         // Date must be higher than previous notification time
00166                 //file.Modified(date);
00167         date.HomeTime();
00168                 file.Size(size);
00169         CleanupClosePushL( file );
00170 
00171         TMsvId aId( CreateChild(fileEntry.iName, iRelativePath, KUidMsvMessageEntry, date, size) );
00172 
00173         SetBodyFromFileL( aId, file );
00174 
00175         CleanupStack::PopAndDestroy(); 
00176 
00177                 return KMsvNullIndexEntryId;
00178                 }
00179         }
00180 
00181 TBool CTxtRefreshMBox::DoStepL()
00182 // Main method
00183 //
00184 //  2. walk over the list: 
00185 //  3.   if file name smaller than that in current pos in list:
00186 //  4.     if file doesn't exist in list, insert it in list, and move to next file.
00187 //  5.   else if file equals description
00188 //  6.     skip both
00189 //  7.   else delete TMsvEntry on the other side, and go to next in list.
00190 //  =
00191 //  a. at the end of either list: if the file list was finished, delete all in the entry list from 
00192 //     current position. if entry list was finished, insert all files starting at current.
00193 //  b. when skipping a entry, and the entry is a folder, do the folder also.
00194 //
00195         {
00196         // If both file list and entry list are done, task is done.
00197     TInt nrFiles = iFilelist->Count();
00198     TInt existingEntries = iExistingEntries->Count();
00199     if (iCurrentFile  == nrFiles && iCurrentEntry == existingEntries)
00200         {
00201                 return ETrue;
00202         }
00203 
00204         TMsvId folderId = KMsvNullIndexEntryId;
00205 
00206         // End of the file list: delete all entries following.
00207         if (iCurrentFile == nrFiles)
00208                 {
00209                 // Delete current entry.
00210                 DeleteEntryL();
00211                 // Step to next entry.
00212                 iCurrentEntry++;
00213                 }
00214         // End of entries list. Append current file to end of list.
00215         else if (iCurrentEntry == existingEntries)
00216                 {
00217                 // Insert file in entries list.
00218                 // if file is folder, do the folder recursively
00219                 folderId = InsertFileL();
00220                 // step to next file
00221                 iCurrentFile++;
00222                 }
00223         else
00224                 {
00225                 // Continue walking
00226                 User::LeaveIfError(iEntry->SetEntry( (*iExistingEntries)[iCurrentEntry] ));
00227 
00228                 TInt compare = (*iFilelist)[iCurrentFile].iName.CompareF(iEntry->Entry().iDescription);
00229 
00230                 // If current file name smaller than name of current entry, then the file doesn't yet
00231                 // exist in the list, and needs to be added.
00232                 if ( compare < 0 )
00233                         {
00234                         // Insert file in entries list.
00235                         // if file is folder, do the folder recursively
00236                         folderId = InsertFileL();
00237                         // step to next file
00238                         iCurrentFile++;
00239                         }
00240                 // Files are equal. Both should be the same.
00241                 else if (compare == 0)
00242                         {
00243                         // if file is folder, do the folder recursively
00244                         if (iEntry->Entry().iType == KUidMsvFolderEntry)
00245                                 folderId = (*iExistingEntries)[iCurrentEntry];
00246                         // Skip both file and entry
00247                         iCurrentFile++;
00248                         iCurrentEntry++;
00249                         }
00250                 // File name is greater than name of current entry, so the current entry 
00251                 // shouldn't be there.
00252                 else
00253                         {
00254                         // Delete entry.
00255                         DeleteEntryL();
00256                         // Step to next entry.
00257                         iCurrentEntry++;
00258                         }
00259                 }
00260 
00261         // If just passing folder, do the folder recursively.
00262         if (folderId != KMsvNullIndexEntryId)
00263                 {
00264                 User::LeaveIfError(iEntry->SetEntry(folderId));
00265                 
00266                 // Set absolute name
00267                 TFileName subDir = iRelativePath;
00268                 subDir.Append(iEntry->Entry().iDescription);
00269                 subDir.Append(KPathDelimiter);
00270 
00271                 CTxtRefreshMBox *folderSynchroniser = CTxtRefreshMBox::NewL(iFs, subDir, folderId, iEntry, iServiceEntryId, iTxtSettings);
00272                 CleanupStack::PushL(folderSynchroniser);
00273                 while (!folderSynchroniser->DoStepL()) ;
00274                 CleanupStack::PopAndDestroy(); //folderSynchroniser
00275                 }
00276 
00277 
00278         return EFalse;
00279         }
00280 
00281 void CTxtRefreshMBox::SetBodyFromFileL( const TMsvId& aId,  RFile& afile  )
00282     {
00283     iEntry->SetEntry( aId );
00284 
00285     CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
00286     CleanupStack::PushL(paraLayer);
00287     CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
00288     CleanupStack::PushL(charLayer);
00289     CRichText* body = CRichText::NewL(paraLayer, charLayer);
00290     CleanupStack::PushL(body);
00291  
00292     CMsvStore* writeStore = iEntry->EditStoreL();
00293     CleanupStack::PushL(writeStore);
00294 
00295     RFileReadStream myReadStream;
00296 
00297     myReadStream.Attach( afile );
00298 
00299     myReadStream.PushL();
00300 
00301     TRAPD( err, body->InternalizePlainTextL( myReadStream ) );
00302 
00303     myReadStream.Close();
00304 
00305     myReadStream.Pop();
00306 
00307     // this method performs a commit for us
00308     writeStore->StoreBodyTextL(*body);
00309     writeStore->CommitL();
00310 
00311     CleanupStack::PopAndDestroy( 4 ); 
00312     }   
00313 
00314 
00315 

Generated by  doxygen 1.6.2