📄 engine.cpp
字号:
{
TInt count=CategoryListCount();
for (TInt i=0;i<count;i++)
{
TAppCategoryEntry& category=CategoryListAt(i);
if (category.iCategoryId==aHandle)
{ // found the category the user has updated, store the new name
category.iCategoryName=aNewName;
break;
}
}
}
TInt CAppEngine::DeleteCategoryL(const TInt aHandle)
//
// Remove the category indicated. Any of our entries that belong to that category need to be
// moved into the unfiled category
//
{
TInt i,count;
TInt ret=0;
// If the UI is displaying the category we are about to delete we need to do something about
// updating it so it displays something else - in our case the 'All' category (which cant be deleted)
if (aHandle==iCurrentCategory)
{ // create a replacement index to hold the EAppCategoryAll entries
CArrayFixFlat<TInt>* index=BuildIndexL(iFolderEntryList,EAppCategoryAll);
// now sort the array of TInts dependant on the content they refer to, in the current
// mode + ascending/descending order
TKeyEntryList key(iFolderEntryList,iSortType,iSortOrder);
index->Sort(key);
// replace the index now we have a fully contructed replacement
delete(iFolderEntryIndex);
iFolderEntryIndex=index;
// we have a new list, display from the top, if there is a top item
iCurrentEntry=0;
LimitCurrentEntryVal();
// UI will revert to display the All entries category
iCurrentCategory=EAppCategoryAll;
// the category model data has changed
ret=1;
}
// Now update the entries so none refer to the deleted category.
// If the UI was displaying the Unfiled category and we move items from the deleted category to
// the unfiled category the UI needs to rebuild its display to include the newly added items
count=EntryListCount();
// ensure we have space to be able to add all entries into the index if we have to
// this enforces an 'all or nothing' type approach to moving items between categories +
// ensuring the UI is correctly maintained.
iFolderEntryIndex->SetReserveL(count);
// see if any entries have to be moved from the deleted category to the unfiled category
TKeyEntryList key(iFolderEntryList,iSortType,iSortOrder);
for (i=0;i<count;i++)
{
TFolderEntry& entry=EntryListAt(i);
if (entry.EntryCategory()==aHandle)
{
entry.UpdateCategory(EAppCategoryUnfiled);
if (iCurrentCategory==EAppCategoryUnfiled)
{
// Since we have SetReserveL() the Insert() wont leave. Therefore all entries that
// have to be added to the index will be added sucessfully.
if (iFolderEntryIndex->InsertIsqAllowDuplicatesL(i,key)<=iCurrentEntry)
iCurrentEntry++; // see comment below.
ret=(-1);
}
}
// We have chosen to track the original iCurrentEntry - via the Isq() function.
// I.e. the same entry that was referenced by iCurrentEntry before we added any entries
// will be referenced by iCurrentEntry after weve added the entries. Whilst a minor point of
// detail, this type of functionality enhances the user experiance.
}
// housekeeping - reduce Ram used by the index to that required to hold the index.
iFolderEntryIndex->Compress();
// now we can remove the category itself
count=CategoryListCount();
for (i=0;i<count;i++)
{
TAppCategoryEntry& category=CategoryListAt(i);
if (category.iCategoryId==aHandle)
{ // found the category the user has deleted remove, it
iCategoryList->Remove(i);
break;
}
}
__TEST_INVARIANT;
return(ret);
}
void CAppEngine::ChangeCategoryL(const TInt aHandle)
//
// Change the category of items being displayed by the UI.
//
{
CArrayFixFlat<TInt>* index=BuildIndexL(iFolderEntryList,aHandle);
// now sort the array of TInts dependant on the content they refer to, in the current
// mode + ascending/descending order
TKeyEntryList key(iFolderEntryList,iSortType,iSortOrder);
index->Sort(key);
// only now weve sucessfully change over to the new category should we update property
// otherwise we cant roll back to our previous state very easily.
iCurrentCategory=aHandle;
delete(iFolderEntryIndex);
iFolderEntryIndex=index;
// we have a new list, display from the top, if there is a top item
iCurrentEntry=0;
LimitCurrentEntryVal();
// Perform a self test to verify our internal structure is still self consistent
__TEST_INVARIANT;
}
TInt CAppEngine::SetListViewZoomState(const TInt aZoomLevel)
//
// Update list view zoom state.
// Return TRUE if zoom state set is different to current level
//
{
if (aZoomLevel==iZoomLevel)
return(FALSE);
iZoomLevel=aZoomLevel;
return(TRUE);
}
const TInt KEngineStreamVersion=1;
void CAppEngine::ExternalizeL(RWriteStream& aStream) const
// Save our state so we can restore to former glory
{
// in general any sub-sections of a stream should have their own version info so we can
// expand those as required in future versions whilst maintaining backwards compatibility
aStream.WriteUint8L(KEngineStreamVersion);
// iZoomLevel
aStream.WriteInt32L(iZoomLevel);
// iPath
aStream.WriteUint16L(iPath.Length());
aStream.WriteL((TText*)(iPath.Ptr()),iPath.Length());
// category list
// This demonstrates using the << operator to call the ExternalizeL() method of the
// TAppCategoryEntry object.
TInt i;
TInt count=iCategoryList->Count();
aStream.WriteInt16L(count);
for (i=0;i<count;i++)
aStream<<((*iCategoryList)[i]);
// (*iCategoryList)[i].ExternalizeL(aStream); // you may prefer this to line above.
// the category information for the entries that exist in the current folder
// This demonstrates calling the ExternalizeL() method directly for the
// TFolderEntry object.
count=iFolderEntryList->Count();
aStream.WriteInt32L(count);
for (i=0;i<count;i++)
// aStream<<((*iFolderEntryList)[i]); // you may prefer this to next line
(*iFolderEntryList)[i].ExternalizeL(aStream);
// the current sort and category filter information
aStream.WriteInt8L(iSortType);
aStream.WriteInt8L(iSortOrder);
aStream.WriteInt32L(iCurrentCategory);
}
void CAppEngine::InternalizeL(RReadStream& aStream)
//
// Restore ourselves to former glory
//
{
TInt version=aStream.ReadUint8L();
if (version<=KEngineStreamVersion)
{ // its a version we understand how to handle.
// this implmentation chooses not to handle future versions of the stream data
// not least of which this app cannot read the stream info to the correct place
// in future versions. Clearly its possible to actually do that, this app does not support it.
// iZoomLevel
iZoomLevel=aStream.ReadInt32L();
// load a descriptor informing us of the last path used
TFileName path;
path.SetLength(aStream.ReadUint16L());
aStream.ReadL((TText*)(path.Ptr()),path.Length());
// now load the Category list we used to have
RArray<TAppCategoryEntry>* catList=new(ELeave)RArray<TAppCategoryEntry>(4);
CleanupClosePushL(*catList);
TInt i;
TInt count=aStream.ReadInt16L();
for (i=0;i<count;i++)
{
// by placing the object definition here its constructor gets called every loop
// this is often useful to ensure we reset any property each time round the loop.
TAppCategoryEntry catEntry;
// read in the TAppCategoryEntry and add to our list of categories
// we use the fact we have named our InternalizeL() method correctly so we can use the
// >> operator.
aStream>>catEntry;
// if prefered you could use
// catEntry.InternalizeL(aStream);
catList->AppendL(catEntry);
}
// create a new container to store the entries
RArray<TFolderEntry>* folderEntryList=new(ELeave)RArray<TFolderEntry>(8);
CleanupClosePushL(*folderEntryList);
// now load the entries that still exist in the folder we were origianlly viewing
TParse parse;
parse.Set(KWildCardName,&path,NULL);
CDir *dirList;
User::LeaveIfError(iFs.GetDir(parse.FullName(),KEntryAttNormal|KEntryAttReadOnly|
KEntryAttHidden|KEntryAttSystem|KEntryAttDir,0,dirList));
CleanupStack::PushL(dirList);
// add a set of entries to our new container
TFolderEntry entry;
count=dirList->Count();
for (i=0;i<count;i++)
{
// construct a new entry
entry.Construct((*dirList)[i]);
// add to the new list of entries
folderEntryList->AppendL(entry);
}
// now weve finished with the dirList + its top of cleanup stack we can delete it
CleanupStack::PopAndDestroy(dirList);
// load the list of entries we knew about before exit
count=aStream.ReadInt32L();
RArray<TFolderEntry>* savedEntryList=new(ELeave)RArray<TFolderEntry>(8);
CleanupClosePushL(*savedEntryList);
for (i=0;i<count;i++)
{
aStream>>entry;
savedEntryList->AppendL(entry);
}
// update our new entry list with saved category entry information
// Files that have been deleted wont appear in the dirList above so we handle that
// Files that have been renamed simply end up in the unfiled category
// Files that have been created end up in the unfiled category.
TInt entryCount=folderEntryList->Count();
for (i=0;i<entryCount;i++)
{
TFolderEntry& entry=(*folderEntryList)[i];
const TDesC& name=entry.EntryName();
for (TInt j=0;j<count;j++)
{
TFolderEntry& entry2=(*savedEntryList)[j];
if (name==entry2.EntryName())
{ // found the entry we saved the category info for
entry.UpdateCategory(entry2.EntryCategory());
break;
}
}
}
CleanupStack::Pop(savedEntryList);
savedEntryList->Close();
delete(savedEntryList);
TFolderEntrySortType sortType=(TFolderEntrySortType)aStream.ReadInt8L();
TFolderEntrySortOrder sortOrder=(TFolderEntrySortOrder)aStream.ReadInt8L();
TInt currentCategory=aStream.ReadInt32L();
// create a sorted index as originally setup
iCurrentEntry=0;
CArrayFixFlat<TInt>* index=BuildIndexL(folderEntryList,currentCategory);
TKeyEntryList key(folderEntryList,sortType,sortOrder);
index->Sort(key);
// since we probably dont want to auto-track when Internalize'ing
iCurrentEntry=0;
// now we have re-constructed our previous application state we can switch over to
// that state as it should all be self consistent.
iPath=path;
iSortType=sortType;
iSortOrder=sortOrder;
iCurrentCategory=currentCategory;
// replace the index
delete(iFolderEntryIndex);
iFolderEntryIndex=index;
// replace the entry list
// dont forget that you manually have to Close() RArrays to actually
// free up any storage they are using, they dont do it themselves.
if (iFolderEntryList)
iFolderEntryList->Close();
delete(iFolderEntryList);
iFolderEntryList=folderEntryList;
CleanupStack::Pop(folderEntryList);
// replace the category set
// dont forget that you manually have to Close() RArrays to actually
// free up any storage they are using, they dont do it themselves.
if (iCategoryList)
iCategoryList->Close();
delete(iCategoryList);
iCategoryList=catList;
CleanupStack::Pop(catList);
// Perform a self test to verify our internal structure is still self consistent
__TEST_INVARIANT;
}
else
User::Leave(KErrNotSupported);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -