📄 downloadlistctrl.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// DownloadListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "emule.h"
#include "DownloadListCtrl.h"
#include "otherfunctions.h"
#include "updownclient.h"
#include "opcodes.h"
#include "ClientDetailDialog.h"
#include "FileDetailDialog.h"
#include "commentdialoglst.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// CDownloadListCtrl
#define DLC_DT_TEXT (DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_END_ELLIPSIS)
#define DLC_BARUPDATE 512
IMPLEMENT_DYNAMIC(CDownloadListCtrl, CListBox)
CDownloadListCtrl::CDownloadListCtrl() {
}
CDownloadListCtrl::~CDownloadListCtrl(){
while(m_ListItems.empty() == false){
delete m_ListItems.begin()->second; // second = CtrlItem_Struct*
m_ListItems.erase(m_ListItems.begin());
}
}
void CDownloadListCtrl::Init(){
CImageList ilDummyImageList; //dummy list
ilDummyImageList.Create(1, 17,ILC_COLOR, 1, 1);
SetImageList(&ilDummyImageList, LVSIL_SMALL);
SetStyle();
SetColors();
ModifyStyle(LVS_SINGLESEL,0);
InsertColumn(0,GetResString(IDS_DL_FILENAME),LVCFMT_LEFT, 260);
InsertColumn(1,GetResString(IDS_DL_SIZE),LVCFMT_LEFT, 60);
InsertColumn(2,GetResString(IDS_DL_TRANSF),LVCFMT_LEFT, 65);
InsertColumn(3,GetResString(IDS_DL_TRANSFCOMPL),LVCFMT_LEFT, 65);
InsertColumn(4,GetResString(IDS_DL_SPEED),LVCFMT_LEFT, 65);
InsertColumn(5,GetResString(IDS_DL_PROGRESS),LVCFMT_LEFT, 170);
InsertColumn(6,GetResString(IDS_DL_SOURCES),LVCFMT_LEFT, 50);
InsertColumn(7,GetResString(IDS_PRIORITY),LVCFMT_LEFT, 55);
InsertColumn(8,GetResString(IDS_STATUS),LVCFMT_LEFT, 70);
InsertColumn(9,GetResString(IDS_DL_REMAINS),LVCFMT_LEFT, 110);
CString lsctitle=GetResString(IDS_LASTSEENCOMPL);
lsctitle.Remove(':');
InsertColumn(10, lsctitle,LVCFMT_LEFT, 220);
lsctitle=GetResString(IDS_FD_LASTCHANGE);
lsctitle.Remove(':');
InsertColumn(11, lsctitle,LVCFMT_LEFT, 220);
m_ImageList.Create(16,16,ILC_COLOR32|ILC_MASK,0,10);
m_ImageList.SetBkColor(CLR_NONE);
m_ImageList.Add(theApp.LoadIcon(IDI_DCS1));
m_ImageList.Add(theApp.LoadIcon(IDI_DCS2));
m_ImageList.Add(theApp.LoadIcon(IDI_DCS3));
m_ImageList.Add(theApp.LoadIcon(IDI_DCS4));
m_ImageList.Add(theApp.LoadIcon(IDI_DCS5));
m_ImageList.Add(theApp.LoadIcon(IDI_COMPPROT));
m_ImageList.Add(theApp.LoadIcon(IDI_FRIEND));
m_ImageList.Add(theApp.LoadIcon(IDI_USER0));
m_ImageList.Add(theApp.LoadIcon(IDI_MLDONK));
m_ImageList.Add(theApp.LoadIcon(IDI_RATING));
m_ImageList.Add(theApp.LoadIcon(IDI_RATINGBAD));
m_ImageList.Add(theApp.LoadIcon(IDI_EDONKEYHYBRID));
CreateMenues();
LoadSettings(CPreferences::tableDownload);
curTab=0;
// Barry - Use preferred sort order from preferences
int sortItem = theApp.glob_prefs->GetColumnSortItem(CPreferences::tableDownload);
bool sortAscending = theApp.glob_prefs->GetColumnSortAscending(CPreferences::tableDownload);
SetSortArrow(sortItem, sortAscending);
SortItems(SortProc, sortItem + (sortAscending ? 0:10));
}
void CDownloadListCtrl::Localize() {
CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
HDITEM hdi;
hdi.mask = HDI_TEXT;
CString strRes;
strRes = GetResString(IDS_DL_FILENAME);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(0, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_SIZE);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(1, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_TRANSF);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(2, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_TRANSFCOMPL);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(3, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_SPEED);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(4, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_PROGRESS);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(5, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_SOURCES);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(6, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_PRIORITY);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(7, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_STATUS);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(8, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_DL_REMAINS);
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(9, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_LASTSEENCOMPL);
strRes.Remove(':');
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(10, &hdi);
strRes.ReleaseBuffer();
strRes = GetResString(IDS_FD_LASTCHANGE);
strRes.Remove(':');
hdi.pszText = strRes.GetBuffer();
pHeaderCtrl->SetItem(11, &hdi);
strRes.ReleaseBuffer();
ShowFilesCount();
}
void CDownloadListCtrl::AddFile(CPartFile* toadd){
// Create new Item
CtrlItem_Struct* newitem = new CtrlItem_Struct;
uint16 itemnr = GetItemCount();
newitem->owner = NULL;
newitem->type = FILE_TYPE;
newitem->value = toadd;
newitem->parent = NULL;
newitem->dwUpdated = 0;
// The same file shall be added only once
ASSERT(m_ListItems.find(toadd) == m_ListItems.end());
m_ListItems.insert(ListItemsPair(toadd, newitem));
if (CheckShowItemInGivenCat(toadd, curTab ))
InsertItem(LVIF_PARAM,itemnr,0,0,0,0,(LPARAM)newitem);
ShowFilesCount();
}
void CDownloadListCtrl::AddSource(CPartFile* owner,CUpDownClient* source,bool notavailable){
// Create new Item
CtrlItem_Struct* newitem = new CtrlItem_Struct;
newitem->owner = owner;
newitem->type = (notavailable) ? UNAVAILABLE_SOURCE : AVAILABLE_SOURCE;
newitem->value = source;
newitem->dwUpdated = 0;
// Update cross link to the owner
ListItems::const_iterator ownerIt = m_ListItems.find(owner);
ASSERT(ownerIt != m_ListItems.end());
CtrlItem_Struct* ownerItem = ownerIt->second;
ASSERT(ownerItem->value == owner);
newitem->parent = ownerItem;
// The same source could be added a few time but only one time per file
{
// Update the other instances of this source
bool bFound = false;
std::pair<ListItems::const_iterator, ListItems::const_iterator> rangeIt = m_ListItems.equal_range(source);
for(ListItems::const_iterator it = rangeIt.first; it != rangeIt.second; it++){
CtrlItem_Struct* cur_item = it->second;
// Check if this source has been already added to this file => to be sure
if(cur_item->owner == owner){
// Update this instance with its new setting
cur_item->type = newitem->type;
cur_item->dwUpdated = 0;
bFound = true;
}
else if(notavailable == false){
// The state 'Available' is exclusive
cur_item->type = UNAVAILABLE_SOURCE;
cur_item->dwUpdated = 0;
}
}
if(bFound == true){
delete newitem;
return;
}
}
m_ListItems.insert(ListItemsPair(source, newitem));
}
void CDownloadListCtrl::RemoveSource(CUpDownClient* source,CPartFile* owner){
// Retrieve all entries matching the source
std::pair<ListItems::iterator, ListItems::iterator> rangeIt = m_ListItems.equal_range(source);
for(ListItems::iterator it = rangeIt.first; it != rangeIt.second; ){
CtrlItem_Struct* delItem = it->second;
if(owner == NULL || owner == delItem->owner){
// Remove it from the m_ListItems
it = m_ListItems.erase(it);
// Remove it from the CListCtrl
LVFINDINFO find;
find.flags = LVFI_PARAM;
find.lParam = (LPARAM)delItem;
sint16 result = FindItem(&find);
if(result != (-1)){
DeleteItem(result);
}
// finally it could be delete
delete delItem;
}
else{
it++;
}
}
}
void CDownloadListCtrl::RemoveFile(CPartFile* toremove){
// Retrieve all entries matching the File or linked to the file
// Remark: The 'asked another files' clients must be removed from here
ASSERT(toremove != NULL);
for(ListItems::iterator it = m_ListItems.begin(); it != m_ListItems.end(); ){
CtrlItem_Struct* delItem = it->second;
if(delItem->owner == toremove || delItem->value == toremove){
// Remove it from the m_ListItems
it = m_ListItems.erase(it);
// Remove it from the CListCtrl
LVFINDINFO find;
find.flags = LVFI_PARAM;
find.lParam = (LPARAM)delItem;
sint16 result = FindItem(&find);
if(result != (-1)){
DeleteItem(result);
}
// finally it could be delete
delete delItem;
}
else {
it++;
}
}
ShowFilesCount();
}
void CDownloadListCtrl::UpdateItem(void* toupdate){
// Retrieve all entries matching the source
std::pair<ListItems::const_iterator, ListItems::const_iterator> rangeIt = m_ListItems.equal_range(toupdate);
for(ListItems::const_iterator it = rangeIt.first; it != rangeIt.second; it++){
CtrlItem_Struct* updateItem = it->second;
// Find entry in CListCtrl and update object
LVFINDINFO find;
find.flags = LVFI_PARAM;
find.lParam = (LPARAM)updateItem;
sint16 result = FindItem(&find);
if(result != (-1)){
updateItem->dwUpdated = 0;
Update(result);
}
}
}
void CDownloadListCtrl::DrawFileItem(CDC *dc, int nColumn, LPRECT lpRect, CtrlItem_Struct *lpCtrlItem) {
if(lpRect->left < lpRect->right) {
CString buffer;
CPartFile *lpPartFile = (CPartFile*)lpCtrlItem->value;
switch(nColumn) {
case 0:{ // file name
LPRECT temprec=lpRect;
dc->SetTextColor( (theApp.glob_prefs->GetCatColor(lpPartFile->GetCategory())>0)?theApp.glob_prefs->GetCatColor(lpPartFile->GetCategory()):(::GetSysColor(COLOR_WINDOWTEXT)) );
if ( theApp.glob_prefs->ShowRatingIndicator() && ( lpPartFile->HasComment() || lpPartFile->HasRating() )){
int image=9;
if (lpPartFile->HasRating()) if (lpPartFile->HasBadRating()) image=10;
POINT point= {lpRect->left-4,lpRect->top+2};
m_ImageList.Draw(dc, image, point, ILD_NORMAL);
lpRect->left+=9;
dc->DrawText(lpPartFile->GetFileName(), (int)strlen(lpPartFile->GetFileName()),lpRect, DLC_DT_TEXT);
lpRect->left-=9;
} else
dc->DrawText(lpPartFile->GetFileName(), (int)strlen(lpPartFile->GetFileName()),lpRect, DLC_DT_TEXT);
}
break;
case 1: // size
buffer.Format("%s",CastItoXBytes(lpPartFile->GetFileSize()));
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
break;
case 2: // transfered
buffer.Format( "%s", CastItoXBytes(lpPartFile->GetTransfered()));
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
break;
case 3: // transfered complete
buffer.Format( "%s", CastItoXBytes(lpPartFile->GetCompletedSize()));
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
break;
case 4: // speed
if (lpPartFile->GetTransferingSrcCount()==0)
buffer = "";
else
buffer.Format("%.1f %s", lpPartFile->GetDatarate() / 1024.0f,GetResString(IDS_KBYTESEC));
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
break;
case 5: // progress
{
lpRect->bottom --;
lpRect->top ++;
// added
int iWidth = lpRect->right - lpRect->left;
int iHeight = lpRect->bottom - lpRect->top;
if (lpCtrlItem->status == (HBITMAP)NULL)
VERIFY(lpCtrlItem->status.CreateBitmap(1, 1, 1, 8, NULL));
CDC cdcStatus;
HGDIOBJ hOldBitmap;
cdcStatus.CreateCompatibleDC(dc);
int cx = lpCtrlItem->status.GetBitmapDimension().cx;
DWORD dwTicks = GetTickCount();
if(lpCtrlItem->dwUpdated + DLC_BARUPDATE < dwTicks || cx != iWidth || !lpCtrlItem->dwUpdated) {
lpCtrlItem->status.DeleteObject();
lpCtrlItem->status.CreateCompatibleBitmap(dc, iWidth, iHeight);
lpCtrlItem->status.SetBitmapDimension(iWidth, iHeight);
hOldBitmap = cdcStatus.SelectObject(lpCtrlItem->status);
RECT rec_status;
rec_status.left = 0;
rec_status.top = 0;
rec_status.bottom = iHeight;
rec_status.right = iWidth;
lpPartFile->DrawStatusBar(&cdcStatus, &rec_status, theApp.glob_prefs->UseFlatBar());
lpCtrlItem->dwUpdated = dwTicks + (rand() % 128);
} else
hOldBitmap = cdcStatus.SelectObject(lpCtrlItem->status);
dc->BitBlt(lpRect->left, lpRect->top, iWidth, iHeight, &cdcStatus, 0, 0, SRCCOPY);
cdcStatus.SelectObject(hOldBitmap);
//added end
lpRect->bottom ++;
lpRect->top --;
}
break;
case 6: // sources
{
uint16 sc = lpPartFile->GetSourceCount();
uint16 ncsc = lpPartFile->GetNotCurrentSourcesCount();
if(ncsc>0){
buffer.Format("%i/%i (%i)",
sc-ncsc, sc, lpPartFile->GetTransferingSrcCount());
}
else {
buffer.Format("%i (%i)",
sc, lpPartFile->GetTransferingSrcCount());
}
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
}
break;
case 7: // prio
switch(lpPartFile->GetDownPriority()) {
case 0:
if( lpPartFile->IsAutoDownPriority() )
dc->DrawText(GetResString(IDS_PRIOAUTOLOW),GetResString(IDS_PRIOAUTOLOW).GetLength(),lpRect, DLC_DT_TEXT);
else
dc->DrawText(GetResString(IDS_PRIOLOW),GetResString(IDS_PRIOLOW).GetLength(),lpRect, DLC_DT_TEXT);
break;
case 1:
if( lpPartFile->IsAutoDownPriority() )
dc->DrawText(GetResString(IDS_PRIOAUTONORMAL),GetResString(IDS_PRIOAUTONORMAL).GetLength(),lpRect, DLC_DT_TEXT);
else
dc->DrawText(GetResString(IDS_PRIONORMAL),GetResString(IDS_PRIONORMAL).GetLength(),lpRect, DLC_DT_TEXT);
break;
case 2:
if( lpPartFile->IsAutoDownPriority() )
dc->DrawText(GetResString(IDS_PRIOAUTOHIGH),GetResString(IDS_PRIOAUTOHIGH).GetLength(),lpRect, DLC_DT_TEXT);
else
dc->DrawText(GetResString(IDS_PRIOHIGH),GetResString(IDS_PRIOHIGH).GetLength(),lpRect, DLC_DT_TEXT);
break;
}
break;
case 8: // <<--9/21/02
buffer.Format("%s", lpPartFile->getPartfileStatus());
dc->DrawText(buffer,buffer.GetLength(),lpRect, DLC_DT_TEXT);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -