📄 searchresultpage.cpp
字号:
case 2: // network
CellText = Result->Network.c_str(); break;
case 3: // user name
if(Node->ChildCount > 0)
// TRANSLATOR: User column of search results if more than one user.
CellText = WideString(int_to_string(Node->ChildCount+1).c_str()) + _(" Users");
else if(ShowRawUserNames)
CellText = Result->GetUser()->GetId().c_str();
else
CellText = Result->GetUser()->GetSmartName().c_str();
break;
case 4: // file size
CellText = FormatNumber(Result->FileSize,"B",2).c_str(); break;
case 5: // availability
// custom drawn below
// CellText = int_to_string(Result->Availability).c_str(); break;
break;
case 6: // title
CellText = Result->MetaData.Get("title").c_str(); break;
case 7: // artist
CellText = Result->MetaData.Get("artist").c_str(); break;
case 8: // album
CellText = Result->MetaData.Get("album").c_str(); break;
case 9: // category
CellText = Result->MetaData.Get("category").c_str(); break;
case 10: // length
if (Result->MetaData.GetInt("duration") > 0)
CellText = FormatTime(Result->MetaData.GetInt("duration")).c_str();
break;
case 11: // bitrate
if (Result->MetaData.GetInt("bitrate") > 0)
CellText = FormatNumber(Result->MetaData.GetInt("bitrate")/1000,"",-1).c_str();
break;
case 12: // resolution
if(Result->MetaData.Exists("width"))
CellText = WideString(Result->MetaData.Get("width").c_str()) + "x" + Result->MetaData.Get("height").c_str(); break;
case 13: // track
CellText = Result->MetaData.Get("track").c_str(); break;
case 14: // path
CellText = Result->FileDir.c_str(); break;
case 15: // media size
{
int MediaSize = Result->MetaData.GetInt("mediasize");
if(MediaSize > 0)
CellText = FormatNumber(MediaSize,"B",2).c_str(); break;
}
case 16: // creation date
CellText = Result->MetaData.Get("creationdate").c_str(); break;
case 17: // tracker (announce)
CellText = Result->MetaData.Get("announce").c_str(); break;
case 18: // comment
CellText = Result->MetaData.Get("comment").c_str(); break;
case 19: // time found
CellText = ((TResultNodeData*)Sender->GetNodeData(Node))->TimeFound.FormatString("hh:nn:ss"); break;
#if 0
case 20: // UniqueToTotal
{
if(Node->ChildCount > 0) {
TResultNodeData* NodeData = (TResultNodeData*)Sender->GetNodeData(Node);
CellText = AnsiString::Format("%f", ARRAYOFCONST(((float)NodeData->UniqueToTotal)));
}
break;
}
#endif
}
}
void __fastcall TSearchResultForm::ResultTreePaintText(
TBaseVirtualTree *Sender, const TCanvas *TargetCanvas,
PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType)
{
TResultNodeData* NodeData = (TResultNodeData*)Sender->GetNodeData(Node);
if(NodeData->Downloading) {
// color downloading files red
TargetCanvas->Font->Color = TColor(0x0000FF);
} else if(NodeData->LocalFile) {
// color shared files green
TargetCanvas->Font->Color = TColor(0x00CC00);
} else {
// TargetCanvas->Font->Color = TColor(0x000000);
}
// make the user name of results with multiple source bold
if(Column == 3 && Node->ChildCount)
TargetCanvas->Font->Style = TFontStyles() << fsBold;
}
void __fastcall TSearchResultForm::ResultTreeAfterCellPaint(
TBaseVirtualTree *Sender, TCanvas *TargetCanvas, PVirtualNode Node,
TColumnIndex Column, TRect &CellRect)
{
if(Column != 5) // availability column
return;
TResultNodeData* NodeData = (TResultNodeData*)Sender->GetNodeData(Node);
int Avail = NodeData->EffectiveAvail;
if(Avail > AVAILABILITY_BMP_LEN - 1)
Avail = AVAILABILITY_BMP_LEN - 1;
TRect Rect;
Rect.Left = CellRect.Left + (CellRect.Width() - AvailBitmaps[Avail]->Width - 4) / 2;
Rect.Top = CellRect.Top + (CellRect.Height() - AvailBitmaps[Avail]->Height - 2) / 2;
Rect.Right = Rect.Left + AvailBitmaps[Avail]->Width + 4;
Rect.Bottom = Rect.Top + AvailBitmaps[Avail]->Height + 2;
TargetCanvas->Brush->Color = TColor(0x00707070);
TargetCanvas->FrameRect(Rect);
TargetCanvas->Draw(Rect.Left+2,Rect.Top+1,AvailBitmaps[Avail]);
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeGetImageIndex(
TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind,
TColumnIndex Column, bool &Ghosted, int &ImageIndex)
{
TResultNodeData* NodeData = (TResultNodeData*)Sender->GetNodeData(Node);
ImageIndex = -1;
if(Kind != ikNormal && Kind != ikSelected)
return;
if(ResultTree->Header->MainColumn == Column) {
ImageIndex = NodeData->ImageIndex;
} else if(Column == 2) { // network column
if(ResultTree->Header->Columns->Items[2]->Options.Contains(coVisible))
ImageIndex = NodeData->NetworkImageIndex;
} else if(Column == 3) { // user column
if(!ResultTree->Header->Columns->Items[2]->Options.Contains(coVisible))
ImageIndex = NodeData->NetworkImageIndex;
}
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeGetHint(
TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column,
TVTTooltipLineBreakStyle &LineBreakStyle, WideString &HintText)
{
TSearchResult* Result = ((TResultNodeData*)Sender->GetNodeData(Node))->Result;
if(Result->FileDir.empty())
// TRANSLATOR: Search result tool tip.
HintText = _("File: ") + Result->FileName.c_str();
else
// TRANSLATOR: Search result tool tip.
HintText = _("File: ") + Result->FileDir.c_str() + "/" + Result->FileName.c_str();
for(THashSet::Iterator itr = Result->GetHashes()->Begin(); itr != Result->GetHashes()->End(); ++itr)
// TRANSLATOR: Search result tool tip.
HintText += _("\nHash: ") + (*itr)->GetGiftHash().c_str();
// TRANSLATOR: Search result tool tip.
HintText += _("\nSize: ") + FormatNumber(Result->FileSize,"Byte").c_str();
if(!Result->MimeType.empty())
// TRANSLATOR: Search result tool tip.
HintText += _("\nMime-Type: ") + Result->MimeType.c_str();
// TRANSLATOR: Search result tool tip.
HintText += _("\nUser: ") + Result->GetUser()->GetId().c_str() + " " + Result->GetUser()->GetSmartName().c_str();
// TRANSLATOR: Search result tool tip.
HintText += _("\nNetwork: ") + Result->Network.c_str();
// TRANSLATOR: Search result tool tip.
HintText += _("\nAvailability: ") + int_to_string(Result->Availability).c_str();
if(!Result->MetaData.Empty()) {
HintText += WideString("\n--");
for(TMetaData::Iterator itr=Result->MetaData.Begin();itr!=Result->MetaData.End();++itr)
HintText += WideString("\n") + (*itr).Name.c_str() + ": " + (*itr).Value.c_str();
}
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeScroll(
TBaseVirtualTree *Sender, int DeltaX, int DeltaY)
{
// workaround for paint problem with focused nodes on scrolling
if(ResultTree->FocusedNode && DeltaX != 0)
ResultTree->InvalidateNode(ResultTree->FocusedNode);
}
//---------------------------------------------------------------------------
int __fastcall TSearchResultForm::SortStrCmp(const char* sa, const char* sb)
{
if(!SortByAlphaNum)
return stricmp(sa,sb);
register unsigned char* a = (unsigned char*)sa;
register unsigned char* b = (unsigned char*)sb;
#if 0
while(*a != 0 && !isalnum(*a)) a++;
while(*b != 0 && !isalnum(*b)) b++;
return stricmp(a,b);
#else
while(*a && *b) {
if(!isalnum(*a)) { a++; continue; }
if(!isalnum(*b)) { b++; continue; }
register unsigned char A = tolower(*a);
register unsigned char B = tolower(*b);
if(A < B) return -1;
if(A > B) return 1;
a++; b++;
}
if(*a < *b) return -1;
if(*a > *b) return 1;
return 0;
#endif
}
int __fastcall TSearchResultForm::SortIntCmp(int a, int b)
{
if(a < b)
return -1;
if(a == b)
return 0;
return 1;
}
void __fastcall TSearchResultForm::ResultTreeCompareNodes(
TBaseVirtualTree *Sender, PVirtualNode Node1, PVirtualNode Node2,
TColumnIndex Column, int &Result)
{
TResultNodeData* NodeData1 = (TResultNodeData*)Sender->GetNodeData(Node1);
TResultNodeData* NodeData2 = (TResultNodeData*)Sender->GetNodeData(Node2);
TSearchResult* Result1 = NodeData1->Result;
TSearchResult* Result2 = NodeData2->Result;
if(!Result1 || !Result2)
return;
switch(Column) {
case 0: Result = SortStrCmp(Result1->FileName.c_str(),Result2->FileName.c_str()); break;
case 1: Result = SortIntCmp(Result1->FileType,Result2->FileType); break;
case 2: Result = SortStrCmp(Result1->Network.c_str(),Result2->Network.c_str()); break;
case 3:
if(Node1->ChildCount != Node2->ChildCount)
Result = SortIntCmp(Node1->ChildCount,Node2->ChildCount);
else
Result = SortStrCmp(Result1->GetUser()->GetSmartName().c_str(),Result2->GetUser()->GetSmartName().c_str());
break;
case 4: Result = (Result1->FileSize == Result2->FileSize) ? 0 : (Result1->FileSize < Result2->FileSize) ? -1 : 1; break;
case 5: Result = (NodeData1->EffectiveAvail < NodeData2->EffectiveAvail) ? -1 : (NodeData1->EffectiveAvail > NodeData2->EffectiveAvail); break;
case 6: Result = SortStrCmp(Result1->MetaData.Get("title").c_str(),Result2->MetaData.Get("title").c_str()); break;
case 7: Result = SortStrCmp(Result1->MetaData.Get("artist").c_str(),Result2->MetaData.Get("artist").c_str()); break;
case 8: Result = SortStrCmp(Result1->MetaData.Get("album").c_str(),Result2->MetaData.Get("album").c_str()); break;
case 9: Result = SortStrCmp(Result1->MetaData.Get("category").c_str(),Result2->MetaData.Get("category").c_str()); break;
case 10: Result = SortIntCmp(Result1->MetaData.GetInt("duration"),Result2->MetaData.GetInt("duration")); break;
case 11: Result = SortIntCmp(Result1->MetaData.GetInt("bitrate"),Result2->MetaData.GetInt("bitrate")); break;
case 12: Result = SortIntCmp(Result1->MetaData.GetInt("width") * Result1->MetaData.GetInt("height"),
Result2->MetaData.GetInt("width") * Result2->MetaData.GetInt("height")); break;
case 13: Result = SortIntCmp(Result1->MetaData.GetInt("track"),Result2->MetaData.GetInt("track")); break;
case 14: Result = SortStrCmp(Result1->FileDir.c_str(),Result2->FileDir.c_str()); break;
case 15: Result = SortIntCmp(Result1->MetaData.GetInt("mediasize"),Result2->MetaData.GetInt("mediasize")); break;
case 16: Result = SortStrCmp(Result1->MetaData.Get("creationdate").c_str(),Result2->MetaData.Get("creationdate").c_str()); break;
case 17: Result = SortStrCmp(Result1->MetaData.Get("announce").c_str(),Result2->MetaData.Get("announce").c_str()); break;
case 18: Result = SortStrCmp(Result1->MetaData.Get("comment").c_str(),Result2->MetaData.Get("comment").c_str()); break;
case 19: Result = (NodeData1->TimeFound == NodeData2->TimeFound) ? 0 : (NodeData1->TimeFound < NodeData2->TimeFound) ? -1 : 1; break;
default: Result = 0;
}
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeHeaderClick(
TVTHeader *Sender, TColumnIndex Column, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if(Button != mbLeft)
return;
if(Sender->SortColumn != Column) {
Sender->SortColumn = Column;
Sender->SortDirection = sdAscending;
} else {
Sender->SortDirection = (Sender->SortDirection == sdAscending) ? sdDescending : sdAscending;
}
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeHeaderDragged(
TVTHeader *Sender, TColumnIndex Column, int OldPosition)
{
// make sure the tree is always in the first column
Sender->MainColumn = Sender->Columns->GetFirstVisibleColumn();
}
void __fastcall TSearchResultForm::ResultTreeHeaderPopupPopup(
TObject *Sender)
{
TMenuItem* Items = ((TVTHeaderPopupMenu*)Sender)->Items;
// disable hiding of column which contains the tree
for(int i=0;i<Items->Count;i++) {
if(Items->Items[i]->Tag == ResultTree->Header->MainColumn) {
Items->Items[i]->Enabled = false;
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeDblClick(TObject *Sender)
{
DownloadMnuClick(NULL);
}
void __fastcall TSearchResultForm::ResultTreeChange(
TBaseVirtualTree *Sender, PVirtualNode Node)
{
DownloadBtn->Enabled = (ResultTree->TreeOptions->SelectionOptions.Contains(toMultiSelect) &&
ResultTree->SelectedCount > 1) ||
ResultTree->FocusedNode != NULL;
}
//---------------------------------------------------------------------------
void __fastcall TSearchResultForm::ResultTreeGetPopupMenu(
TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column,
const TPoint &P, bool &AskParent, TPopupMenu *&PopupMenu)
{
DownloadMnu->Enabled = false;
FindFileInLibraryMnu->Visible = false;
FindMoreFromUserMnu->Enabled = false;
CopyMagnetMnu->Enabled = false;
CopyTrackerMnu->Visible = false;
HideSingleSourcesMnu->Checked = !ShowSingleSources;
if(Node) {
TResultNodeData* ResultNodeData = (TResultNodeData*)ResultTree->GetNodeData(Node);
TSearchResult* Result = ((TResultNodeData*)ResultTree->GetNodeData(Node))->Result;
DownloadMnu->Enabled = true;
FindFileInLibraryMnu->Visible = ResultNodeData->LocalFile;
FindMoreFromUserMnu->Enabled = true;
CopyMagnetMnu->Enabled = true;
CopyTrackerMnu->Visible = Result->MetaData.Exists("announce");
}
PopupMenu = ResultPopup;
}
void TSearchResultForm::DownloadNode(TVirtualNode* Node)
{
if(!Node)
return;
// get save file name from clicked node
string SaveFileName = ((TResultNodeData*)ResultTree->GetNodeData(Node))->Result->FileName;
// get top level node
if(ResultTree->GetNodeLevel(Node) > 0)
Node = Node->Parent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -