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


// CategoryDownload1.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "testbt.h" 
#include "CategoryDownload.h" 
 
#include "download.h" 
#include "FilesListCtrl.h" 
#include "DlgNewDownload.h" 
#include "FileBase.h" 
#include "SetupRegister.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CCategoryDownload 
 
CCategoryDownload::CCategoryDownload() 
{ 
	// BOOL bRet  = DeleteDiretory("d:\\复件 Downloads"); 
	m_pFilesListCtrl = 0; 
} 
 
CCategoryDownload::~CCategoryDownload() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CCategoryDownload, CTreeCtrl) 
	//{{AFX_MSG_MAP(CCategoryDownload) 
	ON_WM_DESTROY() 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(DOWNLOAD_TERMINATED, OnDownloadTerminated) 
	ON_MESSAGE(STORAGE_CHECK_COMPLETE, OnStorageCheckComplete) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CCategoryDownload message handlers 
 
void CCategoryDownload::SetFilesListCtrl(CFilesListCtrl* pFilesListCtrl) 
{ 
	assert(pFilesListCtrl); 
	m_pFilesListCtrl = pFilesListCtrl; 
} 
 
int CCategoryDownload::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	return 0; 
} 
 
void CCategoryDownload::GetRateTotals(long& lUpRate, long& lDownRate) 
{ 
	lUpRate = 0, lDownRate = 0; 
	for (int i=0; im_pDownload) 
		{ 
			assert(false); 
			m_vRuninings.erase(m_vRuninings.begin() + i); 
			break; 
		} 
 
		if (m_vRuninings[i]->m_pDownload &&  
			m_vRuninings[i]->m_pDownload->IsDownloading() &&  
			!m_vRuninings[i]->m_pDownload->IsPause()) 
		{ 
			lUpRate += m_vRuninings[i]->m_pDownload->GetStatics().m_lUpRate; 
			lDownRate  += m_vRuninings[i]->m_pDownload->GetStatics().m_lDownRate; 
		} 
	} 
} 
/********************************************************************** 
 
base . 
 
**********************************************************************/ 
void CCategoryDownload::ContinueTheUncloseds() 
{ 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (pItem->m_vFileDBItems[i]->m_pDownload) 
			pItem->m_vFileDBItems[i]->m_bUnclosed = true; 
 
		_StopDBFileItem(pItem->m_vFileDBItems[i]); 
		StopDBFilesMoveComplete(pItem->m_vFileDBItems[i]); 
	} 
} 
 
void CCategoryDownload::OnDestroy()  
{ 
	// Release downloads. 
	DeleteAllData(GetRootItem()); 
 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		// delete. 
		if (pData->m_vFileDBItems[i]->m_pDownload) 
			_StopDBFileItem(pData->m_vFileDBItems[i]); 
 
		delete pData->m_vFileDBItems[i];		 
	} 
 
	delete pData; 
	// curDel.Delete(); 
} 
 
/********************************************************************** 
 
 download object feedback message handler 
 parameter :  
	long wParam : handle to cursor. 
	long lParam : pointer to download object. 
 
**********************************************************************/ 
 
void CCategoryDownload::OnDownloadTerminated(long wParam, long lParam) 
{ 
	if (m_bNoNotifications) 
	{ 
		assert(false); 
		return; 
	} 
 
	assert(wParam && lParam); 
	 
	for (int i=0; iOnDownloadTerminated(lParam); 
			return; 
		} 
	}	 
	 
	CFileDBItem* pBadFileDBItem = findCursorByDownloadPointer(GetRootItem(), (CDownload*) lParam); 
	if (!pBadFileDBItem) 
	{ 
		assert(false); 
		return; 
	} 
 
	_StopDBFileItem(pBadFileDBItem); 
	bool bCompletedMove = StopDBFilesMoveComplete(pBadFileDBItem); 
	/* 
	string strBadMsg = pBadFileDBItem->m_pDownload->GetBadMsg().data();	 
	pBadFileDBItem->m_pDownload->GetSystemMessage(pBadFileDBItem->m_vMsg); 
	pBadFileDBItem->m_bBad = true; 
	pBadFileDBItem->m_fComplete = 0; 
	//*/ 
 
	// popup from download waiting deque, let engine start next one. refresh filelist if need. 
	m_DownloadEngine.StopDownload(pBadFileDBItem); 
	m_pFilesListCtrl->OnDownloadTerminated((long)pBadFileDBItem, bCompletedMove); 
 
	// release download object 
	// delete pBadFileDBItem->m_pDownload; 
	// pBadFileDBItem->m_pDownload = 0; 
} 
 
 
void CCategoryDownload::OnStorageCheckComplete(long wParam, long lParam) 
{ 
	assert(lParam); 
	m_DownloadEngine.ExcuteDownload(lParam); 
} 
 
CFileDBItem* CCategoryDownload::findCursorByDownloadPointer(CTreeCursor curItem, CDownload* pDownload) 
{ 
	CCategoryDBItem* pItem = (CCategoryDBItem*)curItem.GetData(); 
	assert(pItem && curItem); 
 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (pDownload == pItem->m_vFileDBItems[i]->m_pDownload) 
		{ 
			return pItem->m_vFileDBItems[i]; 
		} 
	} 
 
	if (curItem.HasChildren()) 
	{ 
		CTreeCursor curChild = curItem.GetChild(); 
		while (curChild) 
		{ 
			CFileDBItem* pRet = findCursorByDownloadPointer(curChild, pDownload); 
			if (pRet) 
				return pRet; 
 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
 
	return 0; 
} 
 
/********************************************************************** 
 
	 data manipulate. 
 
**********************************************************************/ 
 
bool CCategoryDownload::Download(CTreeCursor curItem, CFileDBItem* pFileDBItem) 
{	 
	// put the download operation in Download deque. 
	pFileDBItem->m_bBad = false; 
 
	if (m_vRuninings.size() >= m_pSetupRegister->m_lDownloadAllCount) 
	{ 
		pFileDBItem->m_bBad = true; 
 
		CString strBad; 
		strBad.Format("已运行任务数大于全局任务数(%d), 请查看你的任务数设置", m_pSetupRegister->m_lDownloadAllCount); 
 
		time_t tNow; 
		time(&tNow); 
		time(&pFileDBItem->m_tModifiedTime); 
		pFileDBItem->m_vMsg.push_back(CSystemMsg(tNow, strBad.GetBuffer(0), CSystemMsg::eBad));		 
	} 
	else 
	{ 
		m_vRuninings.push_back(pFileDBItem); 
		m_DownloadEngine.StartDownload(pFileDBItem, curItem); 
	} 
 
	// 
	// Move from true category to downloading category. 
	// 
	if (curItem == m_curDownloading) 
		return false; 
	 
	if (!_MoveItemFromto(curItem, m_curDownloading, pFileDBItem)) 
		return false; 
 
	return true; 
} 
 
void CCategoryDownload::PauseDBFiles(CFileDBItem* pFileDBItem) 
{ 
	if (!pFileDBItem->m_pDownload || pFileDBItem->m_pDownload->IsPause()) 
	{ 
		assert(false); 
		return; 
	} 
 
	if (pFileDBItem->m_pDownload->IsDownloading()) 
	{ 
		CStatics statics = pFileDBItem->m_pDownload->GetStatics(); 
 
		if (statics.m_bCheckingDone) 
		{ 
			vector vHaves; 
			pFileDBItem->m_pDownload->GetFractions(vHaves); 
			float fComplete = statics.m_fCompleted; 
 
			pFileDBItem->SetHave(vHaves, fComplete); 
			pFileDBItem->m_lPieceCount = vHaves.size(); 
 
			if (!pFileDBItem->m_vUnneededFileInx.empty()) 
				pFileDBItem->m_fCompletePart = statics.m_fCompletedPart; 
		} 
	} 
 
	pFileDBItem->m_pDownload->Pause(); 
} 
 
void CCategoryDownload::StopDBFiles(vector vToStopFileDBItems) 
{ 
	// 
	// release from m_DownloadEngine. 
	// 
	m_DownloadEngine.StopDownloadArray(vToStopFileDBItems); 
	 
	// 
	// truely release the download object. 
	// 
	for (int i=0; im_pDownload) 
		{ 
			assert(false); 
			continue; 
		} 
 
		_StopDBFileItem(pFileDBItem); 
 
		time_t tNow; 
		time(&tNow); 
		pFileDBItem->m_vMsg.push_back(CSystemMsg(tNow, "用户取消了该任务", CSystemMsg::eCmd)); 
	} 
} 
 
void CCategoryDownload::_StopDBFileItem(CFileDBItem* pFileDBItem) 
{ 
	if (!pFileDBItem->m_pDownload) 
		return; 
	 
	// 
	// remove from runnning vector. 
	// 
	vector::iterator iter = find(m_vRuninings.begin(), m_vRuninings.end(), pFileDBItem); 
	if (iter == m_vRuninings.end()) 
		assert(false); 
	else 
	{ 
		m_vRuninings.erase(iter); 
	} 
	 
 
	// 
	// if bad 
	// 
	if (pFileDBItem->m_pDownload->IsBad()) 
	{ 
		pFileDBItem->m_bBad = true;		 
		vector vHaves; 
		pFileDBItem->SetHave(vHaves, 0); 
	} 
 
	if (pFileDBItem->m_pDownload->IsDownloading()) 
	{ 
		CStatics statics = pFileDBItem->m_pDownload->GetStatics(); 
 
		// Checking and downloading means check completed. 
		// if (!statics.m_bStorageChecking) 
		if (statics.m_bCheckingDone) 
		{ 
			float fComplete = statics.m_fCompleted; 
 
			vector vHaves; 
			pFileDBItem->m_pDownload->GetFractions(vHaves); 
			pFileDBItem->SetHave(vHaves, fComplete); 
			pFileDBItem->m_lPieceCount = vHaves.size(); 
 
			if (!pFileDBItem->m_vUnneededFileInx.empty()) 
				pFileDBItem->m_fCompletePart = statics.m_fCompletedPart; 
		} 
		pFileDBItem->m_pDownload->CloseDownload(); 
		pFileDBItem->m_pDownload->GetSystemMessage(pFileDBItem->m_vMsg); 
		m_vDeleteings.push_back(pFileDBItem->m_pDownload); 
	} 
	else 
	{	 
		pFileDBItem->m_pDownload->GetSystemMessage(pFileDBItem->m_vMsg); 
		delete pFileDBItem->m_pDownload; 
	} 
	 
	pFileDBItem->m_pDownload = 0; 
} 
 
 
bool CCategoryDownload::StopDBFilesMoveComplete(CFileDBItem* pFileDBItem) 
{ 
	assert(pFileDBItem); 
 
	if (!pFileDBItem->m_vUnneededFileInx.empty()) 
	{ 
		if (pFileDBItem->m_fCompletePart < 1) 
			return false; 
	} 
	else 
	{ 
		if (pFileDBItem->m_fComplete < 1) 
			return false; 
	} 
 
	// 
	// move the stoped completed item to the true category assinged. 
	//	 
	CTreeCursor curTrueItem = findCursorByDirid(pFileDBItem->m_lDirectoryID); 
	if (!curTrueItem) 
	{ 
		assert(false); 
		return false; 
	} 
 
	if (curTrueItem == m_curDownloading) 
		return false; 
	 
	if (!_MoveItemFromto(m_curDownloading, curTrueItem, pFileDBItem)) 
	{ 
		assert(false); 
		return false; 
	} 
 
	return true; 
} 
 
bool CCategoryDownload::DeleteDBFile(CTreeCursor curCategory, CFileDBItem* pFileDBItem,  
									 bool bForceDelete, bool bDelUncompleted, bool bDelCompleted) 
{	 
	// 
	// Release from m_DownloadEngine. 
	// 
	if (pFileDBItem->m_pDownload) 
		m_DownloadEngine.StopDownload(pFileDBItem); 
	 
	// 
	// If temperory delete, just move it to recycle category. 
	// 
	if (curCategory != m_curRecycle && !bForceDelete) 
	{ 
		_StopDBFileItem(pFileDBItem); 
		// FileDBItemMoveto(curCategory, m_curRecycle, pFileDBItem, false, true); 
		_MoveItemFromto(curCategory, m_curRecycle, pFileDBItem); 
		return true; 
	} 
 
	// 
	// Remove the item in current category, and release it. 
	// 
	CCategoryDBItem* pTrueCategory = (CCategoryDBItem*)curCategory.GetData(); 
	assert(curCategory && pTrueCategory); 
 
	bool bfind = false; 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (pTrueCategory->m_vFileDBItems[i] == pFileDBItem) 
		{ 
			pTrueCategory->m_vFileDBItems.erase(pTrueCategory->m_vFileDBItems.begin() + i); 
			_StopDBFileItem(pFileDBItem); 
			 
			if (pFileDBItem->m_fComplete >= 1)  
				DeleteFileDBItemFiles(pFileDBItem, bDelCompleted); 
			else 
				DeleteFileDBItemFiles(pFileDBItem, bDelUncompleted); 
 
			delete pFileDBItem; 
			bfind = true; 
			break; 
		} 
	} 
	assert(bfind); 
 
	return true; 
} 
 
bool CCategoryDownload::DeleteFileDBItemFiles(CFileDBItem* pFileDBItem, bool bDelDownloaded) const 
{ 
	CString strTorrentFileName= (GetDBSavePath() + pFileDBItem->m_strTorrentFileName).data();  
	BOOL bRet = DeleteFile(strTorrentFileName); 
	if (!bRet) 
	{ 
		CString strErr = WSAShowError().data(); 
		assert(false); 
		// return false; 
	} 
 
	if (bDelDownloaded) 
	{ 
		if (!DeleteDiretory(pFileDBItem->m_strFileName.data())) 
		{ 
			assert(false); 
			return false; 
		} 
	} 
 
	return true; 
} 
 
bool CCategoryDownload::IsMovingFiles() 
{ 
	return ::IsMovingFiles() > 0; 
} 
 
bool CCategoryDownload::FileDBItemMovetoArray(CTreeCursor curSrc, CTreeCursor curTarget, vector& vFileDBItem) 
{ 
	if (curSrc == curTarget) 
		return false; 
 
	bool bMoveFile = false, bMoveCategory = true; 
 
	// 
	// Get running items. 
	// 
	vector vToStopFileDBItems; 
	for (int i=0; i< vFileDBItem.size(); i++) 
	{ 
		CFileDBItem* pFileDBItem = vFileDBItem[i]; 
		if (pFileDBItem->m_pDownload) 
			vToStopFileDBItems.push_back(pFileDBItem); 
	} 
	 
	// 
	// Query user operations. 
	// 
	if (curTarget == m_curRecycle) 
	{ 
		if (!vToStopFileDBItems.empty()) 
		{ 
			if (AfxMessageBox("有下载正在进行中, 您是否确定删除?", MB_YESNO|MB_DEFBUTTON2) != IDYES)			 
				return false; 
			 
			// if is downloading, popup it from starting engine deque. 
			StopDBFiles(vToStopFileDBItems); 
 
			bMoveFile = false; 
			bMoveCategory = true; 
		} 
	} 
	else 
	{ 
		bMoveFile = false; 
		bMoveCategory = true; 
		// if (curSrc == m_curDownloading) 
		//	bMoveCategory = false; 
 
		switch (m_pSetupRegister->m_eOperMoveToCate) 
		{ 
		case CSetupRegister::ePromptMoveCate: 
			{ 
				if (!vToStopFileDBItems.empty()) 
				{ 
					if (AfxMessageBox("有下载正在进行中,移动已下载文件将停止下载,您是否确定移动已下载文件?", MB_YESNO|MB_DEFBUTTON2) == IDYES) 
						bMoveFile = true; 
					else 
						return false; 
					 
					StopDBFiles(vToStopFileDBItems); 
				} 
				else 
				{ 
					if (AfxMessageBox("是否移动已下载文件?", MB_YESNO|MB_ICONQUESTION) == IDYES) 
						bMoveFile = true; 
				} 
 
			} 
			break; 
		case CSetupRegister::eDontMove: 
			{ 
				bMoveFile = false; 
			} 
			break; 
		case CSetupRegister::eMove: 
			{ 
				bMoveFile = true; 
			} 
			break; 
		} 
	} 
	 
	// 
	// Move. 
	// 
	 
 
	if (bMoveFile) 
	{ 
		// get target path. 
		CCategoryDBItem* pTragetItem= (CCategoryDBItem*)curTarget.GetData(); 
		CString strTargetPath = pTragetItem->m_strDefaultDirectory.data(); 
 
		// get move file path vector. 
		vector vstrPathToMove; 
		for (i=0; i< vFileDBItem.size(); i++) 
		{ 
			CFileDBItem* pFileDBItem = vFileDBItem[i]; 
			DWORD dwAttr = GetFileAttributes(pFileDBItem->m_strFileName.data()); 
			if (dwAttr !=  0xffffffff) 
			{ 
				string strName, strPath; 
				SplitPathName(pFileDBItem->m_strFileName, strPath, strName); 
				 
				if (formatDir(pTragetItem->m_strDefaultDirectory) != formatDir(strPath)) 
				{ 
					vstrPathToMove.push_back(pFileDBItem->m_strFileName.data());					 
				} 
			} 
		} 
 
		// call move function. 
		if (!vstrPathToMove.empty()) 
		{ 
			if (!MoveDiretorySystem(vstrPathToMove, pTragetItem->m_strDefaultDirectory.data(), GetSafeHwnd())) 
			{ 
				assert(false); 
				return false; 
			}			 
		} 
		 
		// change the filedbitem path. 
		for (i=0; i< vFileDBItem.size(); i++) 
		{ 
			CFileDBItem* pFileDBItem = vFileDBItem[i]; 
			 
			string strName, strPath; 
			SplitPathName(pFileDBItem->m_strFileName, strPath, strName); 
			if (formatDir(pTragetItem->m_strDefaultDirectory) != formatDir(strPath)) 
			{ 
				pFileDBItem->m_strFileName = formatDir(pTragetItem->m_strDefaultDirectory) + strName;				 
			} 
		} 
	} 
 
	for (i=0; i< vFileDBItem.size(); i++) 
	{ 
		CFileDBItem* pFileDBItem = vFileDBItem[i]; 
		FileDBItemMoveto(curSrc, curTarget, pFileDBItem, bMoveFile, bMoveCategory); 
	} 
 
	return bMoveCategory; 
} 
 
bool CCategoryDownload::FileDBItemMoveto(CTreeCursor curSrc, CTreeCursor curTarget, CFileDBItem* pFileDBItem, bool bMoveFile, bool bMoveCategory) 
{ 
	CCategoryDBItem* pTragetItem= (CCategoryDBItem*)curTarget.GetData(); 
	assert(pTragetItem); 
 
	if (bMoveFile) 
	{ 
		/* 
		DWORD dwAttr = GetFileAttributes(pFileDBItem->m_strFileName.data()); 
		if (dwAttr !=  0xffffffff) 
		{ 
			string strName, strPath; 
			SplitPathName(pFileDBItem->m_strFileName, strPath, strName); 
			 
			if (formatDir(pTragetItem->m_strDefaultDirectory) != formatDir(strPath)) 
			{ 
				if (!MoveDiretorySystem(pFileDBItem->m_strFileName.data(), pTragetItem->m_strDefaultDirectory.data(), GetSafeHwnd())) 
					return false; 
				 
				pFileDBItem->m_strFileName = formatDir(pTragetItem->m_strDefaultDirectory) + strName; 
			} 
		} 
		//*/ 
	} 
 
	if (bMoveCategory) 
	{ 
		if (!_MoveItemFromto(curSrc, curTarget, pFileDBItem)) 
			return false; 
	} 
 
 
	// change dirid to target dirid.	 
	pFileDBItem->m_lDirectoryID = pTragetItem->m_lDirectoryID; 
 
	return true; 
} 
 
bool CCategoryDownload::FileDBItemRestore(CFileDBItem* pFileDBItem) 
{ 
	CTreeCursor curMove = findCursorByDirid(pFileDBItem->m_lDirectoryID); 
	if (pFileDBItem->m_fComplete < 1) 
		curMove = m_curDownloading; 
	 
	assert(curMove); 
	_MoveItemFromto(m_curRecycle, curMove, pFileDBItem); 
	return true; 
} 
 
bool CCategoryDownload::_MoveItemFromto(CTreeCursor curSrc, CTreeCursor curTarget, CFileDBItem* pFileDBItem) 
{ 
	if (curSrc == curTarget || !curSrc || !curTarget) 
	{ 
		assert(false); 
		return false; 
	} 
 
	// remove form src. 
	bool bfind = false; 
	CCategoryDBItem* pSrcItem= (CCategoryDBItem*)curSrc.GetData(); 
	assert(pSrcItem); 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (pSrcItem->m_vFileDBItems[i] == pFileDBItem) 
		{ 
			pSrcItem->m_vFileDBItems.erase(pSrcItem->m_vFileDBItems.begin() + i); 
			bfind = true; 
			break; 
		} 
	} 
	if (!bfind) 
	{ 
		assert(false); 
		return false; 
	} 
 
	// insert into target. 
	CCategoryDBItem* pTragetItem= (CCategoryDBItem*)curTarget.GetData(); 
	assert(pTragetItem); 
	pTragetItem->m_vFileDBItems.push_back(pFileDBItem); 
 
	return true; 
} 
/******************************************************************** 
 
  Attributes. 
 
********************************************************************/ 
 
bool CCategoryDownload::IsDownloading() 
{ 
	return findDownloading(GetRootItem()); 
} 
 
bool CCategoryDownload::findDownloading(CTreeCursor curItem) 
{ 
	if (!curItem) 
	{ 
		assert(false); 
		return false; 
	} 
 
	CCategoryDBItem* pItem = (CCategoryDBItem*)curItem.GetData(); 
	assert(pItem && curItem); 
 
	for (int i=0; im_vFileDBItems.size(); i++) 
	{ 
		if (pItem->m_vFileDBItems[i]->m_pDownload) 
		{ 
			return true; 
		} 
	} 
 
	if (curItem.HasChildren()) 
	{ 
		CTreeCursor curChild = curItem.GetChild(); 
		while (curChild) 
		{ 
			if (findDownloading(curChild)) 
				return true; 
			curChild = curChild.GetNext(TVGN_NEXT); 
		} 
	} 
 
	return false; 
}