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

📄 librarypage.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.
*/
//---------------------------------------------------------------------------
// don't change this order, VCL's shlobj.hpp collides with window's shlobj.h
#define NO_WIN32_LEAN_AND_MEAN
#include <shlobj.hpp>
#undef NO_WIN32_LEAN_AND_MEAN
#include <vcl.h>
#include <KCeasy.h>
#pragma hdrstop

#include <Clipbrd.hpp>
#include "LibraryPage.h"
#include "PlayerPage.h"
#include "BrowserPage.h"
#include "ShareSelectDialog.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VirtualTrees"
#pragma link "VTHeaderPopup"
#pragma resource "*.dfm"
TLibraryForm *LibraryForm;
//---------------------------------------------------------------------------
// icons in FolderImageList
const int StarImageIndex = 0;
const int ClosedFolderImageIndex = 1;
const int OpenFolderImageIndex = 2;

//---------------------------------------------------------------------------

__fastcall TLibraryForm::TLibraryForm(TComponent* Owner)
:   TForm(Owner)
{
    // don't translate filter until doing so doesn't brake it
    TP_Ignore(this,"FilterKeyCombo.Items");
    TranslateComponent(this);
    FolderTree->NodeDataSize = sizeof(TFolderNodeData);
    FileTree->NodeDataSize = sizeof(TFileNodeData);
    StatusStatic->Caption = "";
    StatusStatic->DoubleBuffered = true; // prevent flickering on sync
    FilterKeyCombo->ItemIndex = 0;
    HashingAnimate->ResName = "CHECK_FILES_AVI";

    // get some stuff from config
    UseSystemIcons = Config->GetValueInt("gui/use_system_file_icons");
    ShowFoldersBtn->Down = Config->GetValueInt("library/show_folders");
    LeftPanel->Visible = ShowFoldersBtn->Down;
    HSplitter->Visible = ShowFoldersBtn->Down;
    ShowDetailsBtn->Down = Config->GetValueInt("library/show_details");
    VSplitter->Visible = ShowDetailsBtn->Down;
    DetailsPanel->Visible = ShowDetailsBtn->Down;

    FilePlayBtn->Enabled = false;
    FileDeleteBtn->Enabled = false;
}

void __fastcall TLibraryForm::Release()
{
    FolderTree->Clear();
    FileTree->Clear();

    TForm::Release();
}
//---------------------------------------------------------------------------

bool __fastcall TLibraryForm::EngineCallback(TCallbackInfo* CbInfo)
{
    switch(CbInfo->Code) {
    case CbcStateChange:
        if(Engine->IsOnline()) {
            // setup folder tree
            FolderTree->BeginUpdate();
            FolderTree->Clear();
            // My Media
            // TRANSLATOR: Library folder
            TVirtualNode* Node = AddFolder(NULL,TFolderNodeData::Shares,_("Shares"),StarImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::All,_("All Files"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Audio,_("Audio"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Video,_("Video"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Images,_("Images"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Documents,_("Documents"),ClosedFolderImageIndex);
#if 0
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Software,_("Software"),ClosedFolderImageIndex);
#endif
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Torrents,_("Torrents"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::Unknown,_("Others"),ClosedFolderImageIndex);
            // TRANSLATOR: Library folder
            AddFolder(Node,TFolderNodeData::RecentDownloads,_("Recent Downloads"),ClosedFolderImageIndex);
            FolderTree->Expanded[Node] = true;
            // File Collections
#if 0
            Node = AddFolder(NULL,TFolderNodeData::Collections,"File Collections",StarImageIndex);
            FolderTree->Expanded[Node] = true;
#endif
            // update
            FolderTree->EndUpdate();

            // setup file tree
            FileTree->Clear();

            // enable share select button
            SelectSharesBtn->Enabled = Engine->IsUsingLocalGift();
            DownloadFolderBtn->Enabled = Engine->IsUsingLocalGift();
            // sync and retrieve shared files from giFT
            Engine->GetShares()->UpdateHide();
            if(Config->GetValueInt("library/update_on_connect"))
                Engine->GetShares()->Sync();

            // TRANSLATOR: Library status
            StatusStatic->Caption = _("No files in library");
            HashingPanel->Visible = false;
            HashingAnimate->Active = false;
        }

        if(Engine->IsOffline()) {
            FolderTree->Clear();
            FileTree->Clear();
        }
        return true;

    case CbcSharesSyncUpdate: {
        TShares* Shares = (TShares*)CbInfo->Data1;
        if(Shares->IsSyncing()) {
            // TRANSLATOR: Library status
            StatusStatic->Caption = AnsiString::Format(_("%d files hashed"), ARRAYOFCONST(((int)CbInfo->Data2)));
            HashingPanel->Visible = true;
            HashingAnimate->Active = true;
        } else {
            // TRANSLATOR: Library status
            StatusStatic->Caption = _("Hashing complete");
            HashingPanel->Visible = false;
            HashingAnimate->Active = false;
            // update shares
            Shares->UpdateDirs();
            Shares->UpdateFiles();
        }
        return true;
    }
    case CbcSharesHiddenUpdate: {
/*
        if(((TShares*)CbInfo->Data1)->IsHidden())
            HideSharesBtn->Caption = "Show Shares";
        else
            HideSharesBtn->Caption = "Hide Shares";
*/
        return true;
    }
    case CbcSharesDelFile: {
        TShares* Shares = (TShares*)CbInfo->Data1;
        TSharedFile* SharedFile = (TSharedFile*)CbInfo->Data2;

        if(CbInfo->Data2 == NULL) {
            // remove all files
            FileTree->FocusedNode = NULL;
            FileTree->Clear();
            // TRANSLATOR: Library status
            StatusStatic->Caption = AnsiString::Format(_("Sharing %d files"), ARRAYOFCONST((0)));

            // find shares folder
            FolderTree->BeginUpdate();
            TVirtualNode* Node = FolderTree->GetFirst();
            while(Node && ((TFolderNodeData*)FolderTree->GetNodeData(Node))->Type != TFolderNodeData::Shares)
                Node = FolderTree->GetNextSibling(Node);
            if(!Node)
                return true;
            FolderTree->InvalidateChildren(Node,true);
            // zero CaptionNumber
            for(Node=FolderTree->GetFirstChild(Node);Node;Node = FolderTree->GetNextSibling(Node))
                ((TFolderNodeData*)FolderTree->GetNodeData(Node))->CaptionNumber = 0;
            FolderTree->EndUpdate();

            return true;
        }

        // remove single file

        // find shares folder
        FolderTree->BeginUpdate();
        TVirtualNode* Node = FolderTree->GetFirst();
        while(Node && ((TFolderNodeData*)FolderTree->GetNodeData(Node))->Type != TFolderNodeData::Shares)
            Node = FolderTree->GetNextSibling(Node);
        if(!Node)
            return true;
        FolderTree->InvalidateChildren(Node,true);
        // update matching CaptionNumber
        for(Node=FolderTree->GetFirstChild(Node);Node;Node = FolderTree->GetNextSibling(Node)) {
            TFolderNodeData* FolderNodeData = (TFolderNodeData*)FolderTree->GetNodeData(Node);
            if(FolderNodeData->Type == TFolderNodeData::All ||
               FolderNodeData->Type == SharedFile->FileType ||
               (FolderNodeData->Type == TFolderNodeData::RecentDownloads && SharedFile->AddedManually))
            {
                FolderNodeData->CaptionNumber--;
            }
        }
        FolderTree->EndUpdate();
        // update FileTree
        for(TVirtualNode* Node=FileTree->GetFirst();Node;Node = FolderTree->GetNext(Node)) {
            TFileNodeData* FolderNodeData = (TFileNodeData*)FileTree->GetNodeData(Node);
            if(FolderNodeData->File == SharedFile) {
                if(Node == FileTree->FocusedNode)
                    FileTree->FocusedNode = NULL;
                FileTree->DeleteNode(Node);
                break;
            }
        }
        // TRANSLATOR: Library status
        StatusStatic->Caption = AnsiString::Format(_("Sharing %d files"), ARRAYOFCONST((Shares->NoOfFiles())));
        return true;
    }
    case CbcSharesChangeFile: {
        TSharedFile* SharedFile = (TSharedFile*)CbInfo->Data2;

        // update FileTree
        for(TVirtualNode* Node=FileTree->GetFirst();Node;Node = FolderTree->GetNext(Node)) {
            TFileNodeData* FolderNodeData = (TFileNodeData*)FileTree->GetNodeData(Node);
            if(FolderNodeData->File == SharedFile) {
                FileTree->IsVisible[Node] = FileNodeVisible(Node);
                FileTree->InvalidateNode(Node);
                // update details if set to this node
                if(FileTree->FocusedNode == Node)
                    FileTreeFocusChanged(FileTree,Node,0);
                break;
            }
        }
        return true;
    }
    case CbcSharesAddFile: {
        TShares* Shares = (TShares*)CbInfo->Data1;
        TSharedFile* SharedFile = (TSharedFile*)CbInfo->Data2;

        // find shares folder
        FolderTree->BeginUpdate();
        TVirtualNode* Node = FolderTree->GetFirst();
        while(Node && ((TFolderNodeData*)FolderTree->GetNodeData(Node))->Type != TFolderNodeData::Shares)
            Node = FolderTree->GetNextSibling(Node);
        if(!Node)
            return true;
        FolderTree->InvalidateChildren(Node,true);
        // update matching CaptionNumber
        for(Node=FolderTree->GetFirstChild(Node);Node;Node = FolderTree->GetNextSibling(Node)) {
            TFolderNodeData* FolderNodeData = (TFolderNodeData*)FolderTree->GetNodeData(Node);
            if(FolderNodeData->Type == TFolderNodeData::All ||
               FolderNodeData->Type == SharedFile->FileType ||
               (FolderNodeData->Type == TFolderNodeData::RecentDownloads && SharedFile->AddedManually))
            {
                FolderNodeData->CaptionNumber++;
            }
        }
        FolderTree->EndUpdate();
        // update FileTree
        Node = FileTree->AddChild(NULL);
        TFileNodeData* FileNodeData = (TFileNodeData*)FileTree->GetNodeData(Node);
        FileNodeData->File = SharedFile;
        if(UseSystemIcons)
            FileNodeData->ImageIndex = MainForm->IconManager->GetIconIndex(FileNodeData->File->FileName);
        else
            FileNodeData->ImageIndex = MainForm->IconManager->GetIconIndex(FileNodeData->File->FileType);
        FileTree->IsVisible[Node] = FileNodeVisible(Node);
        // TRANSLATOR: Library status
        StatusStatic->Caption = AnsiString::Format(_("Sharing %d files"), ARRAYOFCONST((Shares->NoOfFiles())));
        return true;
    }
    }
    return false;
}

bool TLibraryForm::FindFileByHash(const THashSet* Hashes)
{
    TSharedFile* SharedFile;

    if (!(SharedFile = Engine->GetShares()->GetFileByHashes(Hashes)))
        return false;

    // switch to 'all files' folder
    FolderTree->FocusedNode = GetFolderNodeByType(TFolderNodeData::All);
    FolderTree->Selected[FolderTree->FocusedNode] = true;

    // find node in tree
    for(TVirtualNode* Node=FileTree->GetFirst();Node;Node = FolderTree->GetNext(Node)) {
        TFileNodeData* FolderNodeData = (TFileNodeData*)FileTree->GetNodeData(Node);
        if(FolderNodeData->File == SharedFile) {
            // focus this node
            FileTree->ClearSelection();
            FileTree->FocusedNode = Node;
            FileTree->Selected[Node] = true;

            MainForm->SetVisiblePage(LibraryForm);
            FileTree->SetFocus();
            return true;
        }
    }

    return true;
}

//---------------------------------------------------------------------------
// FolderTree

TVirtualNode* __fastcall TLibraryForm::AddFolder(TVirtualNode* ParentNode, TFolderNodeData::TFolderType Type, AnsiString Caption, int ImageIndex)
{
    TVirtualNode* Node = FolderTree->AddChild(ParentNode);
    // call constructor using placement new
    new((TFolderNodeData*)FolderTree->GetNodeData(Node)) TFolderNodeData(Type,Caption.c_str(),ImageIndex);
    return Node;
}

TVirtualNode* __fastcall TLibraryForm::GetFolderNodeByType(TFolderNodeData::TFolderType Type)
{
    // find shares folder
    TVirtualNode* Node = FolderTree->GetFirst();
    while(Node && ((TFolderNodeData*)FolderTree->GetNodeData(Node))->Type != TFolderNodeData::Shares)
        Node = FolderTree->GetNextSibling(Node);
    if(!Node)
        return NULL;

    // find sub folder
    for(Node=FolderTree->GetFirstChild(Node);Node;Node = FolderTree->GetNextSibling(Node)) {
        TFolderNodeData* FolderNodeData = (TFolderNodeData*)FolderTree->GetNodeData(Node);
        if(FolderNodeData->Type == Type)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -