×
Namespaces

Variants
Actions

How to implement a recent array

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Article
Created: rathodavinash (28 Jun 2007)
Last edited: hamishwillee (26 Jul 2012)

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 	__RECENT__H__
#define __RECENT__H__
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++)
{
HBufC *url = HBufC::NewL( fRead, KMaxTInt );
iRecent->AppendL(url->Des());
delete url;
}
 
CleanupStack::PopAndDestroy(&fRead);
}
else
{
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++)
{
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(i));
TInt comp =iCompStr.Compare(aUrl);
if(comp == 0)
{
iFound=ETrue;
iIndex = i;
break;
}
}
if(iFound)
{
 
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 )
{
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
{
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++ )
{
iTempRecentUrls->AppendL(iRecent->MdcaPoint(i));
}
 
iRecent->Reset();
 
for( i = 0 ; i <=KMax-2 ; i++)
{
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)
{
aFs.Delete(iFile);
iRCount = 0 ;
iRecent->Reset();
CleanupStack::PopAndDestroy(&aFs);
return ETrue;
}
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.

This page was last modified on 26 July 2012, at 06:07.
32 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×