How to implement a recent array
Consider the following two scenarios
- We need a list of the recent URL's that the user entered OR
- We need a list of recent search keywords that the user entered.
There can be many more like this, these keywords/URL's/Files opened etc... can be sorted in the recent used order in an array.
The following class is very handy in such situations, not only it maintains a recent list it also stores it into a file so that the recent list is available the next time the application starts.
Header File
Recent.h #ifndef _RECENTH_
#define _RECENTH_
class CRecent : public CBase
{
public:
virtual ~CRecent();
void ReadFromFileL();
void WriteToFileL();
CRecent();
TInt RecentCount();
void AppendToRecTitle(TDesC& aUrl);
void RecentSelected(TInt aIndex, TDes& aRet);
void MoveArrayElementsL(TDesC& aUrl);
TBool ResetAll();
TBool ItemElseWhere(TDesC& aUrl);
TBool ItemAtZeroth(TDesC& aUrl);
void SetFile(TFileName& aFile);
private:
void ConstructL();
private:
CDesCArray *iRecent;
TUint iRCount;
TFileName iFile;
};
#endif
Cpp File
Recent.cpp #include <bautils.h>
#include <s32file.h>
#include <eikspane.h>
#include <akntitle.h>
#include <avkon.hrh>
#include "Recent.h"
_LIT(KFile,".dat");
_LIT(KFormat,"%S");
const TInt KMax = 5;
CRecent::CRecent()
{
iRecent = new (ELeave) CDesCArrayFlat(10);
}
void CRecent::SetFile(TFileName& aFile)
{
iFile.Copy(aFile);
iFile.Append(KFile);
ReadFromFileL();
}
//clean up
CRecent::~CRecent()
{
delete iRecent;
}
//read recent urls line by line from file
void CRecent::ReadFromFileL()
{
RFs aFs;
User::LeaveIfError(aFs.Connect());
CleanupClosePushL(aFs);
TBool iBool;
iBool=BaflUtils::FileExists(aFs,iFile);
if(iBool)
{
iRecent->Reset();
TBuf<128> urlbuf;
RFileReadStream fRead;
User::LeaveIfError(fRead.Open(aFs,iFile, EFileRead));
CleanupClosePushL(fRead);
TInt count = fRead.ReadInt16L();
iRCount=count; //added now
for(TInt i=0;i<count;i++)
Unknown macro: { HBufC *url = HBufC}
CleanupStack::PopAndDestroy(&fRead);
}
else
Unknown macro: { iRCount = 0; }
aFs.Close();
CleanupStack::PopAndDestroy(&aFs);
}
//write files line by line to the file
void CRecent::WriteToFileL()
{
RFs aFs;
User::LeaveIfError(aFs.Connect());
CleanupClosePushL(aFs);
aFs.Delete(iFile);
RFileWriteStream fWrite;
User::LeaveIfError(fWrite.Create(aFs, iFile, EFileWrite));
CleanupClosePushL(fWrite);
fWrite.WriteInt16L( static_cast<TInt16>(iRecent->Count() ) );
for(TInt i =0 ; i < iRecent->Count() ; i++)
Unknown macro: { fWrite << iRecent->MdcaPoint(i); // Warning, this _CAN_ leave }
fWrite.CommitL();
CleanupStack::PopAndDestroy(&fWrite);
CleanupStack::PopAndDestroy(&aFs);
}
TInt CRecent::RecentCount()
{
return iRCount;
}
//new file to list
void CRecent::AppendToRecTitle(TDesC& aUrl)
{
//the first element is selected , dont do anything
if(ItemAtZeroth(aUrl))
return;
//a file that already exists in the list , bring it to top
if(ItemElseWhere(aUrl))
return;
//else append to recent list
if(iRecent->Count() == KMax)
MoveArrayElementsL(aUrl);
else
iRCount++;
iRecent->AppendL(aUrl);
WriteToFileL();
ReadFromFileL();
}
//a file that already exists in the list , bring it to top
TBool CRecent::ItemElseWhere(TDesC& aUrl)
{
TBuf<128> iCompStr;
TInt iIndex;
TBool iFound;
iFound = EFalse;
for(TInt i=0; i < iRecent->Count();i++)
{
iCompStr.Zero();
iCompStr.Copy(iRecent->MdcaPoint

);
TInt comp =iCompStr.Compare(aUrl);
if(comp == 0)
Unknown macro: { iFound=ETrue; iIndex = i; break; }
}
if(iFound)
Unknown macro: { TBuf<128> item; item.Copy(iRecent->MdcaPoint(iIndex)); iRecent->Delete(iIndex); iRecent->AppendL(item); WriteToFileL(); ReadFromFileL(); return ETrue; }
else
return EFalse;
}
//item already is at the recent position or not
TBool CRecent::ItemAtZeroth(TDesC& aUrl)
{
if(iRecent->Count() > 0 )
Unknown macro: { TBuf<128> iCompStr; if(iRecent->Count() == 1) iCompStr.Copy(iRecent->MdcaPoint(0)); else iCompStr.Copy(iRecent->MdcaPoint(iRCount-1)); TInt comp =iCompStr.Compare(aUrl); if(comp != 0) return EFalse; else return ETrue; }
else
Unknown macro: { return EFalse; }
}
//return selected item
void CRecent::RecentSelected(TInt aIndex, TDes& aRet)
{
aRet.Copy(iRecent->MdcaPoint(aIndex));
}
//move elements in case of list full
void CRecent::MoveArrayElementsL(TDesC& aUrl)
{
TInt i;
CDesCArrayFlat* iTempRecentUrls = new (ELeave) CDesCArrayFlat(10);
for( i=1 ; i <= KMax-1 ; i++ )
Unknown macro: { iTempRecentUrls->AppendL(iRecent->MdcaPoint(i)); }
iRecent->Reset();
for( i = 0 ; i <=KMax-2 ; i++)
Unknown macro: { iRecent->AppendL(iTempRecentUrls->MdcaPoint(i)); }
delete iTempRecentUrls;
}
//reset all
TBool CRecent::ResetAll()
{
RFs aFs;
User::LeaveIfError(aFs.Connect());
CleanupClosePushL(aFs);
TBool iBool;
iBool=BaflUtils::FileExists(aFs, iFile);
if(iBool)
Unknown macro: { aFs.Delete(iFile); iRCount = 0 ; iRecent->Reset(); CleanupStack}
CleanupStack::PopAndDestroy(&aFs);
return EFalse;
}
PS: The url/search mentioned in the above scenarios are not the external applications data,like the browsers urls , all scenarios are for the same applications data.
Name : Avinash
Surname :Rathod
Email :avinashrathod@gmail.com
Article :How to implement a recent array
Address :Western Rly. Colony,
175-15, S.V.Road,
Bandra(West)
Mumbai 400050.
Maharashtra.
India.
Date of Cr : 20 Aug 2007