www.pudn.com > GGBT.rar > CategoryBarWnd.cpp


// CategoryBarWnd.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "testbt.h" 
#include "CategoryBarWnd.h" 
 
 
#include "CategoryNewDlg.h" 
#include "CategoryPropertyDlg.h" 
#include "BTFormat.h" 
#include "DlgNewDownload.h" 
#include "FileTorrent.h" 
#include "FileBase.h" 
#include "FilesListCtrl.h" 
#include "bdecode.h" 
#include "download.h" 
#include "DlgFindConditions.h" 
 
#include "SINSTANCE.H" 
#include "mainfrm.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CCategoryBarWnd 
 
CCategoryBarWnd::CCategoryBarWnd() 
{ 
	m_nIDClipFormat = RegisterClipboardFormat(_T("DaoView")); 
} 
 
CCategoryBarWnd::~CCategoryBarWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CCategoryBarWnd, CCategoryDownload) 
	//{{AFX_MSG_MAP(CCategoryBarWnd) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_LBUTTONDOWN() 
	//}}AFX_MSG_MAP 
	ON_NOTIFY_REFLECT(NM_RCLICK,OnRightClick) 
	ON_NOTIFY_REFLECT(TVN_SELCHANGED,OnNodeSelect) 
	ON_COMMAND_RANGE(ID_MENUITEM_OPEN_CATEGORY, ID_MENUITEM_MOVETO_CATEGORY, OnPopupCommand) 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CCategoryBarWnd message handlers 
 
void CCategoryBarWnd::OnFileListViewInitialUpdate()  
{ 
	if (!GetSafeHwnd() || !m_curDownloading) 
	{ 
		ASSERT(FALSE); 
		return; 
	} 
 
	m_curDownloading.Select(); 
} 
 
int CCategoryBarWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) 
		return -1; 
 
 
	// 
	// Create BitmapList 
	// 
	HBITMAP hbm = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 
		MAKEINTRESOURCE(IDB_IMAGELIST_CATEGORY), 
		IMAGE_BITMAP, 
		0,0, // cx,cy 
		LR_CREATEDIBSECTION); // | LR_LOADMAP3DCOLORS ); 
	CBitmap bm; 
	bm.Attach(hbm); 
 
	m_ctlImage.Create(16,15, ILC_COLOR8|ILC_MASK, 4, 4); 
	m_ctlImage.SetBkColor(::GetSysColor(COLOR_WINDOW));  
	m_ctlImage.Add(&bm, (COLORREF)RGB(255,0,255)); 
	 
	SetImageList(&m_ctlImage); 
	 
	// 
	// Create the treeCategory.	 
	// 
	LoadDBFile(); 
	m_bNoNotifications = true; 
	GetRootItem().Select(); 
	m_bNoNotifications = false; 
 
	// 
	// Create engine. 
	// 
	assert(m_pSetupRegister); 
	m_DownloadEngine.Create(m_pSetupRegister, this); 
	 
	// 
	// Create finder and Registe dragdrop. 
	// 
	m_FindFileByConditions.Create(this); 
	BOOL bRet = m_dropTarget.Register(this); 
 
	// 
	// continue the unclosed. 
	// 
	if (m_pSetupRegister->m_bContinueUnCloseDownload) 
		ContinueTheUncloseds(); 
 
	return 0; 
} 
 
 
void CCategoryBarWnd::OnDestroy()  
{ 
	m_bNoNotifications = true; 
 
	// Quit the instance and release hot key. 
	AppReleaseInstance();	 
	UnregisterHotKey(AfxGetMainWnd()->GetSafeHwnd(), HOTKEY_ID); 
	 
	// call base function. 
	CCategoryDownload::OnDestroy();	 
} 
 
void CCategoryBarWnd::OnNodeSelect(NMHDR *pNotifyStruct,LRESULT *result) 
{ 
	if (result) *result = 0; 
 
	if (m_bNoNotifications) 
		return; 
 
	assert(m_pFilesListCtrl); 
	m_ItemSel = GetSelectedItem(); 
	m_pFilesListCtrl->LoadCatetory(m_ItemSel); 
	m_FindFileByConditions.SetNewStartLocation(m_ItemSel, 0); 
} 
 
void CCategoryBarWnd::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	 
	/* 
	UINT nFlags1; 
	CPoint curPoint; 
	GetCursorPos(&curPoint); 
	ScreenToClient(&curPoint); 
	CTreeCursor ItemSel = HitTest(curPoint, &nFlags1); 
 
	if (ItemSel) 
		ItemSel.Select(); 
		//*/ 
 
	CCategoryDownload::OnLButtonDown(nFlags, point); 
} 
 
void CCategoryBarWnd::OnRightClick(NMHDR *pNotifyStruct,LRESULT *result) 
{	 
	UINT nFlags; 
	CPoint curPoint; 
	GetCursorPos(&curPoint); 
	ScreenToClient(&curPoint); 
	m_ItemSel = HitTest(curPoint, &nFlags); 
 
	UINT nImageID = m_ItemSel.GetImageID(); 
	switch (nImageID) 
	{ 
		case IID_ROOT: 
		case IID_RECYCLE: 
		case IID_DOWNLOADING_DIRECTORY: 
		case IID_DOWNLOADED_DIRECTORY: 
		case IID_DIRECTORY: 
			DoPopupMenu(IDR_MENU_CATEGORY); 
			break; 
	} 
	*result = 0; 
} 
 
/****************************************************************** 
 
context menu command and ui. 
 
******************************************************************/ 
 
void CCategoryBarWnd::DoPopupMenu(UINT nMenuID) 
{ 
	CMenu popMenu; 
	popMenu.LoadMenu(nMenuID); 
	 
	// 
	// command ui.  
	// 
	bool bOpenSubCategory = true; 
	bool bNewSubCategory = true; 
	bool bMoveTo = true; 
	bool bDeleted = true; 
 
	if (m_ItemSel == m_curRoot || m_ItemSel == m_curDownloading ||  
		m_ItemSel == m_curDownloaded || m_ItemSel == m_curRecycle) 
	{ 
		bDeleted = false; 
		bMoveTo = false; 
	} 
 
	if (m_ItemSel == m_curDownloading || m_ItemSel == m_curRecycle) 
		bOpenSubCategory = false; 
 
	// downloading can't create sub category. 
	if (m_ItemSel == m_curDownloading) 
		bNewSubCategory = false; 
	 
	popMenu.EnableMenuItem(ID_MENUITEM_OPEN_CATEGORY, MF_BYCOMMAND |  
		(bOpenSubCategory ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); 
	 
	popMenu.EnableMenuItem(ID_MENUITEM_PORPERTY_CATEGORY, MF_BYCOMMAND |  
		(bOpenSubCategory ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); 
	 
 
	popMenu.EnableMenuItem(ID_MENUITEM_DEL_CATEGORY, MF_BYCOMMAND |  
		(bDeleted ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); 
 
	popMenu.EnableMenuItem(ID_MENUITEM_MOVETO_CATEGORY, MF_BYCOMMAND |  
		(bDeleted ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); 
 
	popMenu.EnableMenuItem(ID_MENUITEM_NEW_CATEGORY, MF_BYCOMMAND |  
		(bNewSubCategory? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));		 
 
	CPoint posMouse; 
	GetCursorPos(&posMouse); 
	popMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, posMouse.x,posMouse.y,this); 
} 
 
void CCategoryBarWnd::OnUpdateMenuitem(CCmdUI* pCmdUI)  
{ 
	if (!GetSafeHwnd()) return; 
	 
	// 
	// command ui.  
	// 
	bool bNewSubCategory = true; 
	bool bMoveTo = true; 
	bool bDeleted = true; 
 
	if (GetSelectedItem()== m_curRoot || GetSelectedItem() == m_curDownloading ||  
		GetSelectedItem() == m_curDownloaded || GetSelectedItem() == m_curRecycle) 
	{ 
		bDeleted = false; 
		bMoveTo = false; 
	} 
 
	// downloading can't create sub category. 
	if (GetSelectedItem() == m_curDownloading) 
		bNewSubCategory = false; 
	 
	if (!GetSelectedItem()) 
	{ 
		bNewSubCategory = false; 
		bDeleted = false; 
		bMoveTo = false; 
	} 
		 
	switch (pCmdUI->m_nID) 
	{ 
	case ID_MENUITEM_FIND_NEXT: 
		 pCmdUI->Enable(m_FindFileByConditions.CanFindNext()); 
		break; 
	case ID_MENUITEM_OPEN_CATEGORY: 
		pCmdUI->Enable(bNewSubCategory); 
		break; 
	case ID_MENUITEM_MOVETO_CATEGORY: 
		pCmdUI->Enable(bMoveTo); 
		break; 
	case ID_MENUITEM_NEW_CATEGORY: 
		pCmdUI->Enable(bNewSubCategory); 
		break; 
	case ID_MENUITEM_DEL_CATEGORY:		 
		pCmdUI->Enable(bDeleted); 
		break; 
	case ID_MENUITEM_PORPERTY_CATEGORY: 
		pCmdUI->Enable(bDeleted); 
		break; 
	} 
} 
 
 
void CCategoryBarWnd::OnCommandMenuitem(UINT iID)  
{ 
	m_ItemSel = GetSelectedItem(); 
	assert(m_ItemSel); 
	OnPopupCommand(iID); 
} 
 
void CCategoryBarWnd::OnPopupCommand(UINT nMenuID) 
{ 
	assert(m_ItemSel); 
	switch (nMenuID) 
	{ 
	case ID_MENUITEM_OPEN_CATEGORY: 
		{ 
			// m_pFilesListCtrl->LoadCatetory(m_ItemSel); 
			CCategoryDBItem* pItem = (CCategoryDBItem*)m_ItemSel.GetData(); 
			assert(pItem); 
			HINSTANCE iRet = ShellExecute(NULL, "open" , pItem->m_strDefaultDirectory.data(), 0, 0, SW_SHOW);			 
			if ((UINT)iRet <= HINSTANCE_ERROR) 
				AfxMessageBox(WSAShowError().data()); 
		} 
		break; 
 
	case ID_MENUITEM_NEW_CATEGORY: 
		{ 
			assert(m_ItemSel != m_curDownloading); 
 
			CCategoryNewDlg dlg(&m_ctlImage, this, true, m_ItemSel); 
			/* 
			dlg.m_pctlImage = &m_ctlImage; 
			dlg.m_ItemSel = m_ItemSel; 
			dlg.m_pCategoryBarWnd = this; 
			//*/ 
			if (dlg.DoModal() == IDOK) 
			{ 
				CTreeCursor curItem(dlg.m_ItemSel, this); 
				CTreeCursor curNew = curItem.AddTail(dlg.m_strCategoryName, IID_DIRECTORY); 
				curNew.SetData((long) new CCategoryDBItem(dlg.m_strCategoryDir.GetBuffer(0), m_lDirectoryIDMax++)); 
				curItem.Expand(); 
			} 
			break; 
		}		 
	case ID_MENUITEM_PORPERTY_CATEGORY: 
		{ 
			bool bChangeName = true;			 
			if (m_ItemSel == m_curRoot || m_ItemSel == m_curDownloading ||  
				m_ItemSel == m_curDownloaded || m_ItemSel == m_curRecycle) 
			{ 
				bChangeName = false; 
			} 
 
			long lCategories = 0, lTotalFiles = 0; 
			GetChildCount(m_ItemSel, lCategories, lTotalFiles); 
 
			CCategoryPropertyDlg dlg; 
			dlg.m_bChangeName = bChangeName; 
			dlg.m_lSubCategory = lCategories; 
			dlg.m_lTotalFiles = lTotalFiles; 
			dlg.m_strCategoryName = m_ItemSel.GetText(); 
 
			CCategoryDBItem* pItem = (CCategoryDBItem*)m_ItemSel.GetData(); 
			dlg.m_strCategoryDir = pItem->m_strDefaultDirectory.data(); 
			if (dlg.DoModal() == IDOK) 
			{ 
				if (bChangeName) 
					m_ItemSel.SetText(dlg.m_strCategoryName); 
				pItem->m_strDefaultDirectory = dlg.m_strCategoryDir; 
			} 
		} 
		break; 
 
	case ID_MENUITEM_DEL_CATEGORY: 
		{ 
			int iRet = AfxMessageBox("删除该类别以及包括的子类别和文件?", MB_OKCANCEL|MB_ICONQUESTION); 
			if (iRet == IDOK) 
			{ 
				DeleteAllData(m_ItemSel); 
				m_ItemSel.Delete(); 
			} 
		} 
		break; 
 
	case ID_MENUITEM_MOVETO_CATEGORY: 
		{ 
			CCategoryNewDlg dlg(&m_ctlImage, this, false, m_ItemSel); 
			/* 
			dlg.m_pctlImage = &m_ctlImage; 
			dlg.m_ItemSel = m_ItemSel; 
			dlg.m_bNewOrMoveto = false; 
			dlg.m_pCategoryBarWnd = this; 
			//*/ 
			if (dlg.DoModal() == IDOK) 
			{ 
				CTreeCursor curMovetoItem(dlg.m_ItemSel, this); 
				if (!MoveTreeEx(m_ItemSel, curMovetoItem)) 
					AfxMessageBox("Can't move Category"); 
			} 
		} 
		break; 
	} 
 
	SetFocus(); 
} 
 
/************************************************************** 
 
  catogory manipulate helper function. 
 
**************************************************************/ 
 
bool CCategoryBarWnd::CreateNewCategory(CTreeCursor curSel, CTreeCursor& curNew) 
{ 
	CCategoryNewDlg dlg(&m_ctlImage, this, true, curSel); 
	if (dlg.DoModal() == IDOK) 
	{ 
		CTreeCursor curItem(dlg.m_ItemSel, this); 
		curNew = curItem.AddTail(dlg.m_strCategoryName, CCategoryBarWnd::IID_DIRECTORY); 
		curNew.SetData((long) new CCategoryDBItem(dlg.m_strCategoryDir.GetBuffer(0), m_lDirectoryIDMax++));	 
		return true; 
	} 
	return false; 
} 
 
CTreeCursor CCategoryBarWnd::MoveTree(CTreeCursor curSrc, CTreeCursor curTarget) 
{ 
	CTreeCursor curTemp = curTarget.AddTail(curSrc.GetText(), curSrc.GetImageID()); 
	curTemp.SetData(curSrc.GetData()); 
 
	if (curSrc.HasChildren()) 
	{ 
		CTreeCursor curChild = curSrc.GetChild(); 
		while (curChild) 
		{ 
			MoveTree(curChild, curTemp); 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
	return curTemp; 
} 
 
bool CCategoryBarWnd::MoveTreeEx(CTreeCursor curSrc, CTreeCursor curTarget) 
{ 
 
	if (IsChild(curTarget, curSrc)) 
		return false; 
 
	MoveTree(curSrc, curTarget).Select(); 
	curSrc.Delete(); 
	return true; 
} 
 
 
bool CCategoryBarWnd::GetChildCount(CTreeCursor& curSrc, long& lCategoryCount, long& lFilesCount) 
{ 
	if (curSrc == m_curDownloading) 
		return false; 
 
	lCategoryCount ++; 
	CCategoryDBItem* pItem = (CCategoryDBItem*)curSrc.GetData(); 
	lFilesCount += pItem->m_vFileDBItems.size(); 
 
	if (curSrc.HasChildren()) 
	{ 
		CTreeCursor curChild = curSrc.GetChild(); 
		while (curChild) 
		{ 
			GetChildCount(curChild, lCategoryCount, lFilesCount); 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
	 
	return true; 
} 
 
bool CCategoryBarWnd::IsChild(CTreeCursor curSrc, CTreeCursor curTarget) 
{	 
	if (curTarget == curSrc) 
		return true; 
 
	if (curTarget.HasChildren()) 
	{ 
		CTreeCursor curChild = curTarget.GetChild(); 
		while (curChild) 
		{ 
			if (IsChild(curSrc, curChild)) 
				return true; 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
 
	return false; 
} 
 
 
/************************************************************************ 
 
  filedbitem drag and drop. 
 
************************************************************************/ 
 
DROPEFFECT CCategoryBarWnd::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{ 
	if (pDataObject->IsDataAvailable(m_nIDClipFormat)) 
		return DROPEFFECT_MOVE; 
 
	return DROPEFFECT_NONE; 
} 
 
 
DROPEFFECT CCategoryBarWnd::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{	 
	if (!pDataObject->IsDataAvailable(m_nIDClipFormat)) 
		return DROPEFFECT_NONE; 
 
	UINT nFlags; 
	CPoint curPoint; 
	GetCursorPos(&curPoint); 
	ScreenToClient(&curPoint); 
	CTreeCursor curHit = HitTest(curPoint, &nFlags); 
	 
	if (!(HTREEITEM)curHit || curHit == m_curDownloading) 
		return DROPEFFECT_NONE; 
 
	return DROPEFFECT_MOVE; 
} 
 
BOOL CCategoryBarWnd::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) 
{ 
	if (!pDataObject->IsDataAvailable(m_nIDClipFormat)) 
		return FALSE; 
	 
	UINT nFlags; 
	CPoint curPoint; 
	GetCursorPos(&curPoint); 
	ScreenToClient(&curPoint); 
	CTreeCursor curHit = HitTest(curPoint, &nFlags); 
 
	if (!(HTREEITEM)curHit || curHit == m_curDownloading) 
		return FALSE; 
 
	if (m_pFilesListCtrl->m_curCursor == curHit) 
		return FALSE; 
 
	return FileDBItemMovetoArray(m_pFilesListCtrl->m_curCursor, curHit, m_pFilesListCtrl->m_vDragFileDBItems); 
	/* 
	// 
	// if target category is recycle, don't move file. else prompt user. 
	// 
	bool bMoveFile = false; 
	if (curHit == m_curRecycle) 
	{ 
		vector vToStopFileDBItems; 
 
		for (int i=0; i< m_pFilesListCtrl->m_vDragFileDBItems.size(); i++) 
		{ 
			CFileDBItem* pFileDBItem = m_pFilesListCtrl->m_vDragFileDBItems[i]; 
			if (pFileDBItem->m_pDownload) 
				vToStopFileDBItems.push_back(pFileDBItem); 
		} 
		 
		if (!vToStopFileDBItems.empty()) 
		{ 
			if (AfxMessageBox("有下载正在进行中, 您是否确定删除?", MB_YESNO) != IDYES)			 
				return FALSE; 
		} 
		 
		// if is downloading, popup it from starting engine deque. 
		StopDBFiles(vToStopFileDBItems); 
	} 
	else 
	{ 
		if (AfxMessageBox("是否移动已下载文件?", MB_YESNO|MB_ICONQUESTION) == IDYES) 
			bMoveFile = true; 
	} 
 
	bool bMoveCategory = true; 
	if (m_pFilesListCtrl->m_curCursor == m_curDownloading && curHit != m_curRecycle) 
		bMoveCategory = false; 
 
	assert(m_pFilesListCtrl->m_curCursor); 
 
	for (int i=0; i< m_pFilesListCtrl->m_vDragFileDBItems.size(); i++) 
	{ 
		CFileDBItem* pFileDBItem = m_pFilesListCtrl->m_vDragFileDBItems[i];		 
		FileDBItemMoveto(m_pFilesListCtrl->m_curCursor, curHit, pFileDBItem, bMoveFile, bMoveCategory); 
	} 
 
	return bMoveCategory; 
	//*/ 
} 
 
/************************************************************************ 
	OpenTorrentFile() 
 
	paramerter : 
	bOverwrite - if called by makemetafile() then don't alert user, if exist 
				 only overwrite silently. 
************************************************************************/ 
 
void CCategoryBarWnd::OpenTorrentFile(string strTorrentFileName, HTREEITEM hItemSel, string strDirectorySave, bool bOverwrite) 
{	 
	assert(!strTorrentFileName.empty()); 
 
	try 
	{ 
		string strComment; 
		int iStartMode = 0; // start immediately. 
		vector vNoNeededFileInxs; 
 
 
		CFileTorrent filetorrent; 
		if (!filetorrent.OpenFile(strTorrentFileName)) 
		{ 
			CString strBadMsg = filetorrent.GetBadMsg().data(); 
			if (!strBadMsg.IsEmpty()) 
				AfxMessageBox(strBadMsg); 
			return; 
		} 
		filetorrent.QueryDir(); 
 
		CFileDBItem* pExistFileDBItem = 0; 
		CTreeCursor curExistFileCategory = findFileExist(GetRootItem(), filetorrent.GetInfohashString(), pExistFileDBItem); 
		if (curExistFileCategory) 
		{ 
			assert(pExistFileDBItem); 
			m_bNoNotifications = true; 
			curExistFileCategory.Select(); 
			curExistFileCategory.EnsureVisible(); 
			m_pFilesListCtrl->LoadCatetory(curExistFileCategory, pExistFileDBItem); 
			m_bNoNotifications = false; 
			 
			bool bContinue = false; 
			if (bOverwrite) 
			{ 
				if (AfxMessageBox("该下载已存在,是否覆盖", MB_YESNO) == IDYES) 
					bContinue = true; 
			} 
			else 
				AfxMessageBox("该下载已存在"); 
 
			if (!bContinue) 
				return; 
		} 
 
		if (hItemSel) 
		{			 
			DWORD dwAttr = GetFileAttributes(strDirectorySave.data()); 
			if (dwAttr ==  0xffffffff) 
			{ 
				assert(false); 
				return; 
			} 
		} 
		else 
		{ 
			CDlgNewDownload dlg(&m_ctlImage, &filetorrent, this, true); 
			if (dlg.DoModal() != IDOK) 
				return; 
 
			hItemSel = dlg.m_ItemSel; 
			strDirectorySave = dlg.m_strDirectorySave; 
			iStartMode = dlg.m_iStartMode; 
			vNoNeededFileInxs = dlg.m_treeSubFiles.m_vChecks; 
			strComment = dlg.m_strComment.GetBuffer(0); 
		} 
 
		string strTorrentFileNameNoPath = filetorrent.GetInfohashString(); 
		if (!CopyFileTorrent(strTorrentFileName, strTorrentFileNameNoPath)) 
		{ 
			AfxMessageBox("import torrent to db path error"); 
			return; 
		} 
		 
		// if param Overwrite is set, only overwrite torrent file then return so don't add new filedbitem. 
		if (curExistFileCategory && bOverwrite) 
		{ 
			if (!pExistFileDBItem) 
			{ 
				assert(false); 
				return; 
			} 
 
			pExistFileDBItem->m_fComplete = 1; 
			pExistFileDBItem->m_strTorrentFileName = strTorrentFileNameNoPath; 
			pExistFileDBItem->m_strFileName = strDirectorySave;			 
			m_pFilesListCtrl->LoadCatetory(curExistFileCategory, pExistFileDBItem); 
			return; 
		} 
		 
		// 
		// Create new filedbitem 
		// 
		time_t tnow; 
		time(&tnow); 
		float fComplete = bOverwrite ? 1 : 0; 
		 
		CTreeCursor curItem(hItemSel, this); 
		CCategoryDBItem* pItem = (CCategoryDBItem*)curItem.GetData(); 
		assert(pItem); 
 
		CFileDBItem* pNewFileDBItem = new CFileDBItem( 
			strTorrentFileNameNoPath, 
			strDirectorySave, 
			filetorrent.GetFileLength(), fComplete, tnow,  
			filetorrent.GetInfohashString(), pItem->m_lDirectoryID, tnow,  
			filetorrent.GetPieces().size(), strComment); 
 
		pNewFileDBItem->m_vUnneededFileInx = vNoNeededFileInxs; 
		int iii = pNewFileDBItem->m_vUnneededFileInx.size(); 
		 
		// 
		// Append the new create filedbitem in downloading category. 
		// 
 
		if (curItem != m_curDownloading) 
		{ 
			CCategoryDBItem* pDownloadingItem = (CCategoryDBItem*)m_curDownloading.GetData(); 
			pDownloadingItem->m_vFileDBItems.push_back(pNewFileDBItem); 
		}	 
		// pItem->m_vFileDBItems.push_back(pNewFileDBItem); 
 
 
		// 
		// if download immediately, start it. 
		// 
		if (iStartMode == 0) // start immediately. 
			Download(m_curDownloading, pNewFileDBItem); 
 
		// 
		// show downloading category. 
		// 
 
		m_bNoNotifications = true; 
		m_curDownloading.Select(); 
		m_curDownloading.EnsureVisible(); 
		m_pFilesListCtrl->LoadCatetory(m_curDownloading, pNewFileDBItem); 
		m_bNoNotifications = false; 
 
	} 
	catch (string& e) 
	{ 
		AfxMessageBox(e.data()); 
		return; 
	} 
} 
 
 
bool CCategoryBarWnd::CopyFileTorrent(string strTorrentFileName, string& strTorrentFileNameNoPath) 
{	 
	// copy file to db directory. 
	assert(strTorrentFileNameNoPath.size() == 40); 
 
	 
	char drive[_MAX_DRIVE]; 
	char dir[_MAX_DIR]; 
	char fname[_MAX_FNAME]; 
	char ext[_MAX_EXT];	 
	_splitpath(strTorrentFileName.data(), drive, dir, fname, ext); 
	// strTorrentFileNameNoPath = string(fname) + ext; 
 
	string strName = fname;	 
	strName = strName.substr(0, MAX_PATH - 100); 
	strTorrentFileNameNoPath = strName + "(" + strTorrentFileNameNoPath + ").torrent"; 
	 
	if (_access(GetDBSavePath().data(), 0)) 
	{ 
		if (!MakeDirecotry(GetDBSavePath().data())) 
		{ 
			AfxMessageBox(("create db direcotry (" + GetDBSavePath()+ ")failed").data()); 
			return false; 
		} 
	} 
 
	string strTargetFileName = formatDir(GetDBSavePath().data()) + strTorrentFileNameNoPath; 
	if (!CopyFile(strTorrentFileName.data(), strTargetFileName.data(), false)) 
	{ 
		if (_access(strTargetFileName.data(), 0)) 
		{ 
			DWORD dwerr = GetLastError(); 
			return false; 
		} 
	} 
 
	return true; 
} 
 
/************************************************************************ 
 
  find files. 
 
************************************************************************/ 
 
void CCategoryBarWnd::OnFindFile()  
{ 
	CDlgFindConditions dlg; 
	if (dlg.DoModal() == IDOK) 
	{ 
		if (dlg.m_strFindCondition.IsEmpty()) 
			return ; 
		 
		findFileByConditions(true, dlg.m_strFindCondition.GetBuffer(0)); 
	} 
	return ; 
 
} 
void CCategoryBarWnd::OnFindNext()  
{ 
	findFileByConditions(false); 
} 
 
CTreeCursor CCategoryBarWnd::findFileExist(CTreeCursor& curItem, string strInfohash, CFileDBItem*& pExistFileDBItem) 
{ 
 
	CCategoryDBItem* pItem = (CCategoryDBItem*)curItem.GetData(); 
	assert(pItem && curItem); 
 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (strInfohash == pItem->m_vFileDBItems[i]->m_strHash) 
		{ 
			// if (IsLinkFileDBItem(curItem, pItem->m_vFileDBItems[i])) 
			//	continue; 
 
			pExistFileDBItem = pItem->m_vFileDBItems[i]; 
			return curItem; 
		} 
	} 
 
	if (curItem.HasChildren()) 
	{ 
		CTreeCursor curChild = curItem.GetChild(); 
		while (curChild) 
		{ 
			CTreeCursor curRet = findFileExist(curChild, strInfohash, pExistFileDBItem); 
			if (curRet) 
				return curRet; 
 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
 
	return CTreeCursor(); 
} 
 
void CCategoryBarWnd::findFileByConditions(bool bRefind, string strFindContion) 
{ 
	int iRet = m_FindFileByConditions.findFileByConditions(bRefind, strFindContion); 
	if (!iRet) 
	{ 
		AfxMessageBox("can't find files"); 
		m_pFilesListCtrl->SetFocus(); 
		return; 
	} 
 
	if (!m_FindFileByConditions.m_curLast) 
	{ 
		assert(false); 
		return; 
	} 
 
	m_bNoNotifications = true; 
	m_FindFileByConditions.m_curLast.Select(); 
	m_FindFileByConditions.m_curLast.EnsureVisible(); 
	m_pFilesListCtrl->LoadCatetory(m_FindFileByConditions.m_curLast, m_FindFileByConditions.m_pFileItem); 
	m_bNoNotifications = false; 
 
	if (iRet == 2) 
	{ 
		AfxMessageBox("can't find files"); 
		m_pFilesListCtrl->SetFocus(); 
	} 
} 
 
/////////////////////////////////////////////////////////////////// 
//  CFindFileByConditions 
 
CCategoryBarWnd::CFindFileByConditions::CFindFileByConditions() 
{ 
	m_pCategoryBarWnd = 0; 
	m_bStart = false; 
	m_pFileItem = 0; 
} 
 
void CCategoryBarWnd::CFindFileByConditions::Create(CCategoryBarWnd* pCategoryBarWnd) 
{ 
	m_pCategoryBarWnd = pCategoryBarWnd; 
} 
 
void CCategoryBarWnd::CFindFileByConditions::SetNewStartLocation(CTreeCursor curLocate, CFileDBItem* pFileDBItem) 
{ 
	m_curLast = curLocate; 
	m_pFileItem = pFileDBItem; 
} 
 
bool CCategoryBarWnd::CFindFileByConditions::CanFindNext() 
{ 
	return !m_strCondition.empty(); 
} 
 
int CCategoryBarWnd::CFindFileByConditions::findFileByConditions(bool bRefind, string strCondition ) 
{ 
	if (bRefind) 
	{ 
		// m_curLast = CTreeCursor(); 
		// m_pFileItem = 0; 
		CString strUpper = strCondition.data(); 
		strUpper.MakeUpper(); 
		m_strCondition = strUpper; 
	} 
 
	if (m_strCondition.empty()) 
		return false; 
	 
	m_bStart = bRefind = !m_pFileItem && !m_curLast;	 
 
	if (!findFileByConditionsrec(m_pCategoryBarWnd->GetRootItem(), m_strCondition)) 
	{ 
		if (bRefind) 
			return false; 
		 
		CFileDBItem* pOldItem = m_pFileItem; 
		CTreeCursor curOld = m_curLast; 
		if (findFileByConditionsrec(m_pCategoryBarWnd->GetRootItem(), m_strCondition)) 
		{ 
			if (pOldItem == m_pFileItem && curOld == m_curLast) 
				return 2; 
		} 
		else 
		{ 
			m_curLast = CTreeCursor(); 
			m_pFileItem = 0; 
			return false; 
		} 
	} 
 
	return true; 
} 
 
CTreeCursor CCategoryBarWnd::CFindFileByConditions::findFileByConditionsrec(CTreeCursor& curItem, string strCondition) 
{ 
	CCategoryDBItem* pItem = (CCategoryDBItem*)curItem.GetData(); 
	assert(pItem && curItem); 
 
	bool bCategory = m_bStart; 
	if (!m_bStart) 
	{ 
		assert(m_curLast); 
		if (curItem == m_curLast ) 
		{ 
			bCategory = true; 
			if (!m_pFileItem) 
				m_bStart = true; 
		}		 
	} 
 
	if (bCategory) 
	{ 
		for (int i=0; im_vFileDBItems.size(); i++) 
		{		 
			if (!m_bStart) 
			{ 
				assert(m_curLast); 
				assert(curItem == m_curLast); 
				assert(m_pFileItem); 
				 
				if (m_pFileItem == pItem->m_vFileDBItems[i]) 
					m_bStart = true; 
				continue; 
			} 
			 
			CFileDBItem* pFileDBItem = pItem->m_vFileDBItems[i]; 
 
			CString strFileNameUpper = pFileDBItem->m_strFileName.data(); 
			CString strTorrentFileNameUpper = pFileDBItem->m_strTorrentFileName.data(); 
			CString strHashUpper = pFileDBItem->m_strHash.data(); 
			strFileNameUpper.MakeUpper(); 
			strTorrentFileNameUpper.MakeUpper(); 
			strHashUpper.MakeUpper(); 
			 
			if (strFileNameUpper.Find(strCondition.data()) != -1 || 
				strTorrentFileNameUpper.Find(strCondition.data()) != -1 || 
				strHashUpper.Find(strCondition.data()) != -1 ) 
			{ 
				m_curLast = curItem; 
				m_pFileItem = pItem->m_vFileDBItems[i]; 
				return curItem; 
			} 
		} 
	} 
 
	if (curItem.HasChildren()) 
	{ 
		CTreeCursor curChild = curItem.GetChild(); 
		while (curChild) 
		{ 
			CTreeCursor curRet = findFileByConditionsrec(curChild, strCondition); 
			if (curRet) 
				return curRet;		 
 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
 
	return CTreeCursor(); 
}