⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine.cpp

📁 《UIQ 3 The Complete Guide》书的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
TInt CAppEngine::EntryListCount() const
// Report number of TFolderEntry's we have
	{
	return(iFolderEntryList->Count());
	}

TFolderEntry& CAppEngine::EntryListAt(const TInt aIndex) const
// Report the TFolderEntry at the indicated place within the
	{
	return((*iFolderEntryList)[aIndex]);
	}

CArrayFixFlat<TInt>* CAppEngine::BuildIndexL(RArray<TFolderEntry>* aList,const TInt aCategory)
//
// Create an index into the list of entries. Indicies often have many superior properties, in this
// case we can easily filter and sort our underlying content simply by changing the index. Sorting 
// entries consists of moving single TInts, compared to sizeof(TFolderEntry). Filtering is performed
// by putting a value in the index (or not as the case may be)
//
	{
	TInt count=aList->Count();
	TInt granularity=count;
	if (!count)
		granularity=1; // ensure we cant generate a granularity of zero 

	// by creating the array at the granularity of the primary list we will only cause one
	// alloc to occur when we add entries = signficantly faster adding entries.
	CArrayFixFlat<TInt>* index=new(ELeave)CArrayFixFlat<TInt>(granularity);  
	CleanupStack::PushL(index);
	for (TInt i=0;i<count;i++)	
		{
		if (aCategory==EAppCategoryAll || (*aList)[i].EntryCategory()==aCategory)
			index->AppendL(i);
		}
	// reduce ram used if not all entries are added to the index
	index->Compress();

	// caller is expected to take ownership of the created list
	CleanupStack::Pop(index);
	return(index);
	}

_LIT(KWildCardName,"*");
void CAppEngine::BuildDirectoryListL(const TDesC& aPath)
//
// Get a list of the files and folders within the indicated folder
//
	{
	TParse parse;
	parse.Set(KWildCardName,&aPath,NULL);
	CDir *dirList;
	User::LeaveIfError(iFs.GetDir(parse.FullName(),KEntryAttNormal|KEntryAttReadOnly|
									KEntryAttHidden|KEntryAttSystem|KEntryAttDir,0,dirList));

	// ensure some part of the app takes ownership of the dirList before we can leave later on
	CleanupStack::PushL(dirList);

	// create a new container to store the entries
	RArray<TFolderEntry>* folderEntryList=new(ELeave)RArray<TFolderEntry>(8);

	// not only do we need to ensure we delete the actual allocated Rarray
	CleanupDeletePushL(folderEntryList);

	// but we also have to ensure we call Close() before the delete to release any resources
	CleanupClosePushL(*folderEntryList);
	
	// add a set of entries to our new container
	TFolderEntry entry;
	TInt count=dirList->Count();
	for (TInt i=0;i<count;i++)
		{
		// construct a new entry
		entry.Construct((*dirList)[i]);
		
		// add to the new list of entries
		folderEntryList->AppendL(entry);
		}

	// we need an index onto the entries to perform efficient processing
	CArrayFixFlat<TInt>* index=BuildIndexL(folderEntryList,iCurrentCategory);

	// now sort the array of TInts dependant on the content they refer to, in the current
	// mode + ascending/descending order
	TKeyEntryList key(folderEntryList,iSortType,iSortOrder);
	index->Sort(key);

	// replace any existing list with the new list
	if (iFolderEntryList)
		{
		iFolderEntryList->Close();
		delete(iFolderEntryList);
		}
	iFolderEntryList=folderEntryList;

	// firstly the Cleanup stack item that calls close()
	CleanupStack::Pop(folderEntryList);	

	// then the cleanup stack item that deletes the actual object
	CleanupStack::Pop(folderEntryList);	

	// replace the index
	delete(iFolderEntryIndex);
	iFolderEntryIndex=index;

	// we have a new list, display from the top, if there is a top item
	iCurrentEntry=0;
	LimitCurrentEntryVal();

	// update the path our entries exist within now all constructed
	iPath=aPath;

	// whilst it may have been tempting to perform this immedately after the end of the loop above
	// it is very important to match Push/Pops on the cleanup stack, so we simply defer to here
	CleanupStack::PopAndDestroy(dirList);

	// Perform a self test to verify our internal structure is still self consistent
	__TEST_INVARIANT;
	}

void CAppEngine::UpdateCurrentEntryL(const TFolderEntry& aUpdate)
//
// The current entry is being updated. Apply the changes. Update the index as appropriate.
// The expectation is that upon completion of this function the UI will return to a list view.
//
	{
	TFolderEntry& curEntry=EntryListAt(iFolderEntryIndex->At(iCurrentEntry));

	TParse srcName;
	srcName.Set(curEntry.EntryName(),&iPath,NULL);

	TBool sortReqd=EFalse;
	if (curEntry.EntryName()!=aUpdate.EntryName())
		{ // names being changed
		TParse destName;
		destName.Set(aUpdate.EntryName(),&iPath,NULL);

		// attempt to rename the file on disk
		User::LeaveIfError(iFs.Rename(srcName.FullName(),destName.FullName()));

		// now update the internal representation
		curEntry.UpdateName(aUpdate.EntryName());

		// whilst not strictly true in all circumstances, in majority of cases it is requried
		// so we ignore a possible optimization here
		sortReqd=ETrue;
		}

	if (curEntry.EntryModified()!=aUpdate.EntryModified())
		{ // file last modification date being updated
		User::LeaveIfError(iFs.SetModified(srcName.FullName(),aUpdate.EntryModified()));

		// update the internal representation
		curEntry.UpdateModified(aUpdate.EntryModified());

		// modification dates only involved in EFolderEntrySortByModified sorts 
		// so we can optimize quite easily.
		if (iSortType==EFolderEntrySortByModified)
			sortReqd=ETrue;
		}

	if (curEntry.EntryCategory()!=aUpdate.EntryCategory())
		{
		// firstly update the category associated with the current item
		TInt oldCategory=curEntry.EntryCategory();
		curEntry.UpdateCategory(aUpdate.EntryCategory());

		if (iCurrentCategory==oldCategory)
			{ // the index shows items from the categry weve just left, remove our entry
			iFolderEntryIndex->Delete(iCurrentEntry);

			// ensure we are still referencing a valid entry within the index
			LimitCurrentEntryVal();
			}

		// in our model it is not possible to move an entry from outside our category to within the
		// current category - as its not possible to select such an item within the UI..
		}

	if (sortReqd)
		SortEntries(iSortType,iSortOrder);

	// Perform a self test to verify our internal structure is still self consistent
	__TEST_INVARIANT;
	}

TInt CAppEngine::EntryCount() const
//
// Report the number of entries visible to the UI = number of entries in our filtered list
// 
	{
	return(iFolderEntryIndex->Count());
	}

const TFolderEntry& CAppEngine::Entry(const TInt aIndex) const
//
// Report the aIndex'th entry visible to the UI. 
//
	{
	return(EntryListAt(iFolderEntryIndex->At(aIndex)));
	}

const TFolderEntry& CAppEngine::CurrentEntry() const
//
// Return the current TFolderEntry as visible to the UI
//
	{
	return(EntryListAt(iFolderEntryIndex->At(iCurrentEntry)));
	}

void CAppEngine::LimitCurrentEntryVal()
// Limit the iCurrentEntry value so its within the valid range. Set to -1 if no entries left.
	{
	if (iCurrentEntry>=iFolderEntryIndex->Count())
		iCurrentEntry--;
	}

void CAppEngine::SetCurrentEntry(const TInt aIndex)
//
// Set the current entry to the aIndex'th entry visible to the UI. 
// Note that its entirely possible for aIndex to be -ve (-1), e.g. if no
// entries in the currently filtered list. 
// 
	{
	__ASSERT_DEBUG(aIndex<iFolderEntryIndex->Count(),Panic(10));
	iCurrentEntry=aIndex;
	}

void CAppEngine::EntryFullName(TDes& aName)
// Report the full name of the currently selected entry
	{
	TParse parse;
	parse.Set(CurrentEntry().EntryName(),&iPath,NULL);
	aName=parse.FullName();
	}

void CAppEngine::DeleteCurrentEntryL()
//
// Delete the current entry. 
// i) remove from disk, ii) remove from internal representation of disk entry, iii) from index
//
	{
	// remove the file from the file store
	TFileName name;
	EntryFullName(name);
	User::LeaveIfError(iFs.Delete(name));

	// remove the entry from our list of all entries
	TInt index=iFolderEntryIndex->At(iCurrentEntry);
	iFolderEntryList->Remove(index);
	
	// remove the entry from the index + adjust all index values so they take into account
	// the fact that the iFolderEntryList contains one less entry. Any entries after the
	// 'index' th entry have moved up the list.
	iFolderEntryIndex->Delete(iCurrentEntry);
	const TInt count=EntryCount();
	for (TInt i=0;i<count;i++)
		{
		TInt val=iFolderEntryIndex->At(i);
		if (val>=index)
			(*iFolderEntryIndex)[i]=val-1;
		}

	// as an alternative to the above index updating we could have chosen to rebuild the entire
	// index, however the above is significantly more efficient + no OOM to contend with. 

	// limit the current entry index to the existing entries
	LimitCurrentEntryVal();

	// Perform a self test to verify our internal structure is still self consistent
	__TEST_INVARIANT;
	}

void CAppEngine::SortEntries(const TFolderEntrySortType aSortType,const TFolderEntrySortOrder aOrder)
//
// Sort the current entries in the index into specified order
// The engine design explitly ensures that we can sort entries without leaving being possible. This
// is to ensure we can handle any UI rollback that may be required.
//
// We also track the current entry so when the UI displays the newly sorted list the selected item
// remains the same. 
//
	{
	// as an optimization we could check to see if only the aOrder is varying. If so we can
	// generate the sorted list by simply swapping all entries in our index - which is much faster
	// than actually performing a sort. That is not implmented at this time. 

	// we want to track where the current entry has got to so when we return to the list view
	// the hlight remains on the item that was changed...
	TInt whichEntry=iFolderEntryIndex->At(iCurrentEntry);

	TKeyEntryList key(iFolderEntryList,aSortType,aOrder);
	iFolderEntryIndex->Sort(key);
	iSortType=aSortType;
	iSortOrder=aOrder;

	// scan the index to locate the original entry, so we can determine the new iCurrentEntry
	const TInt count=EntryCount();
	for (TInt i=0;i<count;i++)
		{
		if (iFolderEntryIndex->At(i)==whichEntry)	
			{
			iCurrentEntry=i;
			break;
			}
		}
	}

TInt CAppEngine::CategoryListCount() const
// Report the number of items we have in the category list
	{
	return(iCategoryList->Count());
	}

TAppCategoryEntry& CAppEngine::CategoryListAt(const TInt aIndex) const
// Report the aIndex'th item in the category list
	{
	return((*iCategoryList)[aIndex]);
	}

void CAppEngine::AddCategoryL(const TInt aHandle,const TDesC& aName)
// Add a new category.
	{
	TAppCategoryEntry category;
	category.iCategoryId=aHandle;
	category.iCategoryName=aName;
	iCategoryList->AppendL(category);
	}

void CAppEngine::UpdateCategoryName(const TInt aHandle,const TDesC& aNewName)
// Update the textual name of the category identified by the aHandle value.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -