📄 librarypage.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.
*/
//---------------------------------------------------------------------------
// 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 + -