📄 transferpage.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
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.
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#include <KCeasy.h>
#pragma hdrstop
#include "TransferPage.h"
#include "SearchPage.h"
#include "PlayerPage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VirtualTrees"
#pragma link "VTHeaderPopup"
#pragma resource "*.dfm"
TTransferForm *TransferForm;
//---------------------------------------------------------------------------
__fastcall TTransferForm::TTransferForm(TComponent* Owner)
: TForm(Owner)
{
TranslateComponent(this);
DownloadTree->NodeDataSize = sizeof(TDownloadNodeData);
UploadTree->NodeDataSize = sizeof(TUploadNodeData);
// load column settings
VTSetColumnSettings(DownloadTree,Config->GetValue("tree_columns/downloads"));
VTSetColumnSettings(UploadTree,Config->GetValue("tree_columns/uploads"));
}
void __fastcall TTransferForm::Release()
{
// save column settings
Config->SetValue("tree_columns/downloads",VTGetColumnSettings(DownloadTree));
Config->SetValue("tree_columns/uploads",VTGetColumnSettings(UploadTree));
DownloadTree->Clear();
UploadTree->Clear();
TForm::Release();
}
void __fastcall TTransferForm::FormCanResize(TObject *Sender,
int &NewWidth, int &NewHeight, bool &Resize)
{
// preserve download/upload tree height when resizing
double ratio = (double)NewHeight / (double)TransferForm->Height;
DownloadPanel->Height = (double)DownloadPanel->Height * ratio;
}
//---------------------------------------------------------------------------
bool __fastcall TTransferForm::EngineCallback(TCallbackInfo* CbInfo)
{
switch(CbInfo->Code) {
case CbcStateChange:
if(Engine->IsOnline() || Engine->IsOffline()) {
TransferForm->DownloadTree->Clear();
TransferForm->UploadTree->Clear();
}
return true;
// downloading
case CbcNewDownload: {
DownloadTree->BeginUpdate();
TDownloadNodeData* DownloadNodeData = (TDownloadNodeData*)DownloadTree->GetNodeData(DownloadTree->AddChild(NULL));
DownloadNodeData->Download = (TDownload*)CbInfo->Data1;
DownloadNodeData->Source = NULL;
DownloadNodeData->ImageIndex = MainForm->IconManager->GetIconIndex(((TDownload*)CbInfo->Data1)->GetSaveFileName());
DownloadNodeData->NetworkImageIndex = MainForm->IconManager->GetNetworkIconIndex(((TDownload*)CbInfo->Data1)->GetNetwork());
DownloadTree->EndUpdate();
return true;
}
case CbcDownloadRemoved: {
TVirtualNode* Node = DownloadTree->GetFirst();
for(;Node;Node=DownloadTree->GetNextSibling(Node))
if(((TDownloadNodeData*)DownloadTree->GetNodeData(Node))->Download == (TDownload*)CbInfo->Data1)
break;
if(Node)
DownloadTree->DeleteNode(Node); // deletes children too
return true;
}
case CbcDownloadUpdate: {
TDownload* Download = (TDownload*)CbInfo->Data1;
TVirtualNode* Node = DownloadTree->GetFirst();
for(;Node;Node=DownloadTree->GetNextSibling(Node))
if(((TDownloadNodeData*)DownloadTree->GetNodeData(Node))->Download == Download)
break;
if(Download->GetState() == TDownload::Completed ||
Download->GetState() == TDownload::Cancelled ||
Download->GetState() == TDownload::Failed)
{
// only autoclear downloads if they have not failed
if(Config->GetValueInt("download/autoclear_complete") &&
Download->GetState() != TDownload::Failed)
{
Engine->RemoveDownload(Download);
break;
}
// delete sources
DownloadTree->BeginUpdate();
DownloadTree->DeleteChildren(Node, true);
DownloadTree->EndUpdate();
} else if(Node) {
DownloadTree->InvalidateChildren(Node,false);
}
// update total throughput in status bar
#if 0
Engine->LockDownloads();
int TotalBps = 0;
TEngine::TDownloadIterator itr = Engine->GetDownloadsBegin();
for(;itr != Engine->GetDownloadsEnd();++itr)
TotalBps += (*itr)->GetThroughput();
Engine->ReleaseDownloads();
MainForm->MainStatusBar->Panels->Items[1]->Text = FormatNumber(TotalBps,"Bps",2).c_str();
#endif
return true;
}
case CbcDownloadAddSource: {
TVirtualNode* Node = DownloadTree->GetFirst();
for(;Node;Node=DownloadTree->GetNextSibling(Node))
if(((TDownloadNodeData*)DownloadTree->GetNodeData(Node))->Download == (TDownload*)CbInfo->Data1)
break;
if(Node) {
TDownloadNodeData* DownloadNodeData;
DownloadTree->BeginUpdate();
// network of download may have changed if it didn't have a source before
DownloadNodeData = (TDownloadNodeData*)DownloadTree->GetNodeData(Node);
DownloadNodeData->NetworkImageIndex = MainForm->IconManager->GetNetworkIconIndex(((TDownload*)CbInfo->Data1)->GetNetwork());
// add source
DownloadNodeData = (TDownloadNodeData*)DownloadTree->GetNodeData(DownloadTree->AddChild(Node));
DownloadNodeData->Download = (TDownload*)CbInfo->Data1;
DownloadNodeData->Source = (TDlSource*)CbInfo->Data2;
DownloadNodeData->ImageIndex = MainForm->IconManager->GetIconIndex(((TDownload*)CbInfo->Data1)->GetSaveFileName());
DownloadNodeData->NetworkImageIndex = MainForm->IconManager->GetNetworkIconIndex(((TDlSource*)CbInfo->Data2)->Network);
DownloadTree->EndUpdate();
}
return true;
}
case CbcDownloadDelSource: {
TVirtualNode* Node = DownloadTree->GetFirst();
for(;Node;Node=DownloadTree->GetNext(Node))
if(((TDownloadNodeData*)DownloadTree->GetNodeData(Node))->Source == (TDlSource*)CbInfo->Data2)
break;
if(Node)
DownloadTree->DeleteNode(Node);
return true;
}
// uploading
case CbcNewUpload: {
if(((TUpload*)CbInfo->Data1)->IsSpecial() && Config->GetValueInt("upload/filter_nodepage_uploads"))
return true;
TUploadNodeData* UploadNodeData = NULL;
UploadTree->BeginUpdate();
// try to find a completed/canceled upload of the same file we can reuse
TVirtualNode* Node = UploadTree->GetFirst();
for(;Node;Node=UploadTree->GetNextSibling(Node)) {
UploadNodeData = (TUploadNodeData*)UploadTree->GetNodeData(Node);
if(UploadNodeData->Upload->GetState() == TUpload::Completed ||
UploadNodeData->Upload->GetState() == TUpload::Cancelled)
{
if((UploadNodeData->Upload->GetSource()->GetUser()->GetId() == ((TUpload*)CbInfo->Data1)->GetSource()->GetUser()->GetId()) &&
(UploadNodeData->Upload->GetHashes()->Equals(((TUpload*)CbInfo->Data1)->GetHashes()) ||
(UploadNodeData->Upload->GetHashes()->Size() == 0 && ((TUpload*)CbInfo->Data1)->GetHashes()->Size() == 0)))
{
break;
}
}
}
if(Node) {
// remove upload which previously used this node
// set Upload to NULL first to prevent CbcUploadRemoved from deleting the node
TUpload* OldUpload = UploadNodeData->Upload;
UploadNodeData->Upload = NULL;
Engine->RemoveUpload(OldUpload);
UploadTree->InvalidateChildren(Node,false);
} else {
// create new node
UploadNodeData = (TUploadNodeData*)UploadTree->GetNodeData(UploadTree->AddChild(NULL));
}
UploadNodeData->Upload = (TUpload*)CbInfo->Data1;
UploadNodeData->ImageIndex = MainForm->IconManager->GetIconIndex(((TUpload*)CbInfo->Data1)->GetFileName());
UploadNodeData->NetworkImageIndex = MainForm->IconManager->GetNetworkIconIndex(((TUpload*)CbInfo->Data1)->GetNetwork());
UploadTree->EndUpdate();
return true;
}
case CbcUploadRemoved: {
TVirtualNode* Node = UploadTree->GetFirst();
for(;Node;Node=UploadTree->GetNextSibling(Node))
if(((TUploadNodeData*)UploadTree->GetNodeData(Node))->Upload == (TUpload*)CbInfo->Data1)
break;
if(Node)
UploadTree->DeleteNode(Node);
return true;
}
case CbcUploadUpdate: {
if((((TUpload*)CbInfo->Data1)->GetState() == TUpload::Completed ||
((TUpload*)CbInfo->Data1)->GetState() == TUpload::Cancelled) &&
(Config->GetValueInt("upload/autoclear_complete") ||
(((TUpload*)CbInfo->Data1)->IsSpecial() && Config->GetValueInt("upload/filter_nodepage_uploads"))) )
{
Engine->RemoveUpload((TUpload*)CbInfo->Data1);
break;
}
TVirtualNode* Node = UploadTree->GetFirst();
for(;Node;Node=UploadTree->GetNextSibling(Node))
if(((TUploadNodeData*)UploadTree->GetNodeData(Node))->Upload == ((TUpload*)CbInfo->Data1))
break;
if(Node)
UploadTree->InvalidateChildren(Node,false);
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
// downloads
//---------------------------------------------------------------------------
void __fastcall TTransferForm::DownloadTreeGetText(
TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column,
TVSTTextType TextType, WideString &CellText)
{
if(TextType != ttNormal)
return;
TDownload* Download = ((TDownloadNodeData*)Sender->GetNodeData(Node))->Download;
TDlSource* Source = ((TDownloadNodeData*)Sender->GetNodeData(Node))->Source;
switch(Column) {
case 0: // file name
CellText = Download->GetSaveFileName().c_str(); break;
case 1: // user
if(Source) {
CellText = Source->GetUser()->GetSmartName().c_str();
} else {
// TRANSLATOR: Number of users in download tree view.
CellText = Node->ChildCount ? WideString(int_to_string(Node->ChildCount).c_str()) + _(" Users") : WideString("");
}
break;
case 2: // network
if(Source)
CellText = Source->Network.c_str();
else
CellText = Download->GetNetwork().c_str();
break;
case 3: // progress, owner drawn
break;
case 4: // status
if(Source) {
CellText = Source->ProtoState.c_str();
} else {
// New, Queued, Paused, Downloading, Completed, Cancelled
switch(Download->GetState()) {
// TRANSLATOR: Download status.
case TDownload::New: CellText = _("New"); break;
// TRANSLATOR: Download status.
case TDownload::Registering: CellText = _("Registering"); break;
// TRANSLATOR: Download status.
case TDownload::Queued: CellText = _("Queued"); break;
case TDownload::Paused: {
// TRANSLATOR: Download status.
CellText = _("Paused");
// if disk space is low add a hint as to why download was paused
if(Engine->IsUsingLocalGift()) {
DWORD SecPerCluster, BytesPerSec, FreeClusters, TotalClusters;
// GetDiskFreeSpace only reports < 2GB but is available on all
// windows versions. Since we only check for little disk space
// this is fine
if(GetDiskFreeSpace(Engine->GetShares()->GetIncomingDir().c_str(),
&SecPerCluster, &BytesPerSec,
&FreeClusters, &TotalClusters))
{
if(((__int64)FreeClusters) * ((__int64)SecPerCluster) * ((__int64)BytesPerSec) < 10*1024*1024) {
// TRANSLATOR: Download status.
CellText = _("Paused (Disk Full?)");
}
}
}
break;
}
// TRANSLATOR: Download status.
case TDownload::Downloading: CellText = _("Downloading"); break;
// TRANSLATOR: Download status.
case TDownload::Completed: CellText = _("Completed"); break;
// TRANSLATOR: Download status.
case TDownload::Cancelled: CellText = _("Cancelled"); break;
// TRANSLATOR: Download status.
case TDownload::Failed: CellText = _("Failed"); break;
// TRANSLATOR: Download status.
case TDownload::Verifying: CellText = _("Verifying"); break;
}
if(Download->IsFindingMoreSources()) {
// TRANSLATOR: Download status
CellText = _("Finding more Sources...");
}
}
break;
case 5: // size
if(Source && Source->State == TDlSource::Active) {
CellText = FormatNumber(Source->Transmitted,"B",2).c_str();
CellText += " / ";
CellText += FormatNumber(Source->Size,"B",2).c_str();
} else if(!Source) {
CellText = FormatNumber(Download->GetTransmitted(),"B",2).c_str();
CellText += " / ";
CellText += FormatNumber(Download->GetFileSize(),"B",2).c_str();
}
break;
case 6: // speed
if(Source && Source->State == TDlSource::Active)
CellText = FormatNumber(Source->Throughput.GetBps(),"Bps",2).c_str();
else if(!Source && Download->GetState() == TDownload::Downloading)
CellText = FormatNumber(Download->GetThroughput(),"Bps",2).c_str();
break;
case 7: // ETA
if(Source && Source->State == TDlSource::Active)
CellText = FormatTime(Source->GetTimeLeft()).c_str();
else if(!Source && Download->GetState() == TDownload::Downloading)
CellText = FormatTime(Download->GetTimeLeft()).c_str();
break;
case 8: // title
CellText = Download->GetMetaData().Get("title").c_str();
break;
case 9: // artist
CellText = Download->GetMetaData().Get("artist").c_str();
break;
}
}
void __fastcall TTransferForm::DownloadTreeGetImageIndex(
TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind,
TColumnIndex Column, bool &Ghosted, int &ImageIndex)
{
TDownloadNodeData* NodeData = (TDownloadNodeData*)Sender->GetNodeData(Node);
if(DownloadTree->Header->MainColumn == Column) {
if(Kind == ikNormal || Kind == ikSelected)
ImageIndex = NodeData->ImageIndex;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -