/* TODO: This code should be coalesced with the code that
adds items as well as the code that finds their icons.
ALL changes to an items name/internal properties/icon/overlay icon
should go through a central function. */
void CFolderView::RenameItem(int iItemInternal,TCHAR *szNewFileName)
{
	IShellFolder	*pShellFolder = NULL;
	LPITEMIDLIST	pidlFull = NULL;
	LPITEMIDLIST	pidlRelative = NULL;
	SHFILEINFO		shfi;
	LVFINDINFO		lvfi;
	TCHAR			szDisplayName[MAX_PATH];
	LVITEM			lvItem;
	TCHAR			szFullFileName[MAX_PATH];
	DWORD_PTR		res;
	HRESULT			hr;
	int				iItem;

	if(iItemInternal == -1)
		return;

	StringCchCopy(szFullFileName,MAX_PATH,m_CurDir);
	PathAppend(szFullFileName,szNewFileName);

	hr = GetIdlFromParsingName(szFullFileName,&pidlFull);

	if(SUCCEEDED(hr))
	{
		hr = SHBindToParent(pidlFull,IID_IShellFolder,(void **)&pShellFolder,(LPCITEMIDLIST *)&pidlRelative);

		if(SUCCEEDED(hr))
		{
			hr = GetDisplayName(szFullFileName,szDisplayName,SHGDN_INFOLDER|SHGDN_FORPARSING);

			if(SUCCEEDED(hr))
			{
				m_pExtraItemInfo[iItemInternal].pridl = ILClone(pidlRelative);
				StringCchCopy(m_pExtraItemInfo[iItemInternal].szDisplayName,
					SIZEOF_ARRAY(m_pExtraItemInfo[iItemInternal].szDisplayName),
					szDisplayName);

				/* Need to update internal storage for the item, since
				it's name has now changed. */
				StringCchCopy(m_pwfdFiles[iItemInternal].cFileName,
					SIZEOF_ARRAY(m_pwfdFiles[iItemInternal].cFileName),
					szNewFileName);

				/* The files' type may have changed, so retrieve the files'
				icon again. */
				res = SHGetFileInfo((LPTSTR)pidlFull,0,&shfi,
					sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_ICON|
					SHGFI_OVERLAYINDEX);

				if(res != 0)
				{
					/* Locate the item within the listview. */
					lvfi.flags	= LVFI_PARAM;
					lvfi.lParam	= iItemInternal;
					iItem = ListView_FindItem(m_hListView,-1,&lvfi);

					if(iItem != -1)
					{
						lvItem.mask			= LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
						lvItem.iItem		= iItem;
						lvItem.iSubItem		= 0;
						lvItem.iImage		= shfi.iIcon;
						lvItem.pszText		= ProcessItemFileName(iItemInternal);
						lvItem.stateMask	= LVIS_OVERLAYMASK;

						/* As well as resetting the items icon, we'll also set
						it's overlay again (the overlay could change, for example,
						if the file is changed to a shortcut). */
						lvItem.state		= INDEXTOOVERLAYMASK(shfi.iIcon >> 24);

						/* Update the item in the listview. */
						ListView_SetItem(m_hListView,&lvItem);

						/* TODO: Does the file need to be filtered out? */
						if(IsFileFiltered(iItemInternal))
						{
							RemoveFilteredItem(iItem,iItemInternal);
						}
					}

					DestroyIcon(shfi.hIcon);
				}
			}

			pShellFolder->Release();
		}
void inline CShellBrowser::InsertAwaitingItems(BOOL bInsertIntoGroup)
{
	LVITEM lv;
	ULARGE_INTEGER ulFileSize;
	unsigned int nPrevItems;
	int nAdded = 0;
	int iItemIndex;

	nPrevItems = ListView_GetItemCount(m_hListView);

	m_nAwaitingAdd = (int)m_AwaitingAddList.size();

	if((nPrevItems + m_nAwaitingAdd) == 0)
	{
		if(m_bApplyFilter)
			SendMessage(m_hOwner,WM_USER_FILTERINGAPPLIED,m_ID,TRUE);
		else
			SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,TRUE);

		m_nTotalItems = 0;

		return;
	}
	else if(!m_bApplyFilter)
	{
		SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,FALSE);
	}

	/* Make the listview allocate space (for internal data structures)
	for all the items at once, rather than individually.
	Acts as a speed optimization. */
	ListView_SetItemCount(m_hListView,m_nAwaitingAdd + nPrevItems);

	lv.mask			= LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

	if(bInsertIntoGroup)
		lv.mask		|= LVIF_GROUPID;

	/* Constant for each item. */
	lv.iSubItem		= 0;

	if(m_bAutoArrange)
		NListView::ListView_SetAutoArrange(m_hListView,FALSE);

	for(auto itr = m_AwaitingAddList.begin();itr != m_AwaitingAddList.end();itr++)
	{
		if(!IsFileFiltered(itr->iItemInternal))
		{
			lv.iItem	= itr->iItem;
			lv.pszText	= ProcessItemFileName(itr->iItemInternal);
			lv.iImage	= I_IMAGECALLBACK;
			lv.lParam	= itr->iItemInternal;

			if(bInsertIntoGroup)
			{
				lv.iGroupId	= DetermineItemGroup(itr->iItemInternal);
			}

			/* Insert the item into the list view control. */
			iItemIndex = ListView_InsertItem(m_hListView,&lv);

			if(itr->bPosition && m_ViewMode != VM_DETAILS)
			{
				POINT ptItem;

				if(itr->iAfter != -1)
				{
					ListView_GetItemPosition(m_hListView,itr->iAfter,&ptItem);
				}
				else
				{
					ptItem.x = 0;
					ptItem.y = 0;
				}

				/* The item will end up in the position AFTER iAfter. */
				ListView_SetItemPosition32(m_hListView,iItemIndex,ptItem.x,ptItem.y);
			}

			if(m_ViewMode == VM_TILES)
			{
				SetTileViewItemInfo(iItemIndex,itr->iItemInternal);
			}

			if(m_bNewItemCreated)
			{
				LPITEMIDLIST pidlComplete = NULL;

				pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[(int)itr->iItemInternal].pridl);

				if(CompareIdls(pidlComplete,m_pidlNewItem))
					m_bNewItemCreated = FALSE;

				m_iIndexNewItem = iItemIndex;

				CoTaskMemFree(pidlComplete);
			}

			/* If the file is marked as hidden, ghost it out. */
			if(m_pwfdFiles[itr->iItemInternal].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
			{
				ListView_SetItemState(m_hListView,iItemIndex,LVIS_CUT,LVIS_CUT);
			}
			
			/* Add the current file's size to the running size of the current directory. */
			/* A folder may or may not have 0 in its high file size member.
			It should either be zeroed, or never counted. */
			ulFileSize.LowPart = m_pwfdFiles[itr->iItemInternal].nFileSizeLow;
			ulFileSize.HighPart = m_pwfdFiles[itr->iItemInternal].nFileSizeHigh;

			m_ulTotalDirSize.QuadPart += ulFileSize.QuadPart;

			nAdded++;
		}
		else
		{
			m_FilteredItemsList.push_back(itr->iItemInternal);
		}
	}

	if(m_bAutoArrange)
		NListView::ListView_SetAutoArrange(m_hListView,TRUE);

	m_nTotalItems = nPrevItems + nAdded;

	if(m_ViewMode == VM_DETAILS)
	{
		TCHAR szDrive[MAX_PATH];
		BOOL bNetworkRemovable = FALSE;

		QueueUserAPC(SetAllColumnDataAPC,m_hThread,(ULONG_PTR)this);

		StringCchCopy(szDrive,SIZEOF_ARRAY(szDrive),m_CurDir);
		PathStripToRoot(szDrive);

		if(GetDriveType(szDrive) == DRIVE_REMOVABLE ||
			GetDriveType(szDrive) == DRIVE_REMOTE)
		{
			bNetworkRemovable = TRUE;
		}

		/* If the user has selected to disable folder sizes
		on removable drives or networks, and we are currently
		on such a drive, do not calculate folder sizes. */
		if(m_bShowFolderSizes && !(m_bDisableFolderSizesNetworkRemovable && bNetworkRemovable))
			QueueUserAPC(SetAllFolderSizeColumnDataAPC,m_hFolderSizeThread,(ULONG_PTR)this);
	}

	PositionDroppedItems();

	m_AwaitingAddList.clear();
	m_nAwaitingAdd = 0;
}