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;
}