⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transferpage.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
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 + -