📄 searchlistctrl.cpp
字号:
}
}
// set name in list to the most used filename
if (change)
SetItemText(index,0,strFileName);
Update(index);
}
}
void CSearchListCtrl::RemoveResult(const CSearchFile* toremove)
{
LVFINDINFO find;
find.flags = LVFI_PARAM;
find.lParam = (LPARAM)toremove;
sint32 result = FindItem(&find);
if(result != (-1) )
DeleteItem(result);
}
void CSearchListCtrl::ShowResults(uint32 nResultsID)
{
DeleteAllItems();
m_nResultsID = nResultsID;
searchlist->ShowResults(m_nResultsID);
}
void CSearchListCtrl::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// Barry - Store sort order in preferences
// Determine ascending based on whether already sorted on this column
int sortItem = thePrefs.GetColumnSortItem(CPreferences::tableSearch);
bool m_oldSortAscending = thePrefs.GetColumnSortAscending(CPreferences::tableSearch);
bool sortAscending = (sortItem != pNMListView->iSubItem) ? true : !m_oldSortAscending;
// Item is column clicked
sortItem = pNMListView->iSubItem;
// Save new preferences
thePrefs.SetColumnSortItem(CPreferences::tableSearch, sortItem);
thePrefs.SetColumnSortAscending(CPreferences::tableSearch, sortAscending);
// Sort table
SetSortArrow(sortItem, sortAscending);
SortItems(SortProc, sortItem + (sortAscending ? 0:100));
*pResult = 0;
}
int CSearchListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
const CSearchFile* item1 = (CSearchFile*)lParam1;
const CSearchFile* item2 = (CSearchFile*)lParam2;
int sortMod = 1;
if(lParamSort >= 100) {
sortMod = -1;
lParamSort -= 100;
}
int comp;
if (item1->GetListParent()==NULL && item2->GetListParent()!=NULL){
if (item1 == item2->GetListParent())
return -1;
comp = Compare(item1, item2->m_list_parent, lParamSort) * sortMod;
}
else if (item2->GetListParent()==NULL && item1->GetListParent()!=NULL){
if (item1->m_list_parent == item2)
return 1;
comp = Compare(item1->GetListParent(), item2, lParamSort) * sortMod;
}
else if (item1->GetListParent()==NULL){
comp = Compare(item1, item2, lParamSort) * sortMod;
}
else{
comp = Compare(item1->GetListParent(), item2->GetListParent(), lParamSort);
if (comp != 0)
return sortMod * comp;
if ((item1->GetListParent()==NULL && item2->GetListParent()!=NULL) || (item2->GetListParent()==NULL && item1->GetListParent()!=NULL)){
if (item1->GetListParent()==NULL)
return -1;
else
return 1;
}
comp = CompareChild(item1, item2, lParamSort);
}
return comp;
}
int CSearchListCtrl::CompareChild(const CSearchFile* item1, const CSearchFile* item2, LPARAM lParamSort)
{
switch(lParamSort){
case 0: //filename asc
return CompareLocaleStringNoCase(item1->GetFileName(),item2->GetFileName());
case 100: //filename desc
return CompareLocaleStringNoCase(item2->GetFileName(),item1->GetFileName());
default:
// always sort by descending availability
return CompareUnsigned(item2->GetIntTagValue(FT_SOURCES), item1->GetIntTagValue(FT_SOURCES));
}
}
int CSearchListCtrl::Compare(const CSearchFile* item1, const CSearchFile* item2, LPARAM lParamSort)
{
switch(lParamSort){
case 0: //filename asc
return CompareLocaleStringNoCase(item1->GetFileName(),item2->GetFileName());
case 100: //filename desc
return CompareLocaleStringNoCase(item2->GetFileName(),item1->GetFileName());
case 1: //size asc
return CompareUnsigned(item1->GetFileSize(), item2->GetFileSize());
case 101: //size desc
return CompareUnsigned(item2->GetFileSize(), item1->GetFileSize());
case 2: //sources asc
return CompareUnsigned(item1->GetIntTagValue(FT_SOURCES), item2->GetIntTagValue(FT_SOURCES));
case 102: //sources desc
return CompareUnsigned(item2->GetIntTagValue(FT_SOURCES), item1->GetIntTagValue(FT_SOURCES));
case 3: // complete sources asc
if (item1->GetIntTagValue(FT_SOURCES) == 0 || item2->GetIntTagValue(FT_SOURCES) == 0 || item1->IsKademlia() || item2->IsKademlia() )
return 0; // should never happen, just a sanity check
return CompareUnsigned((item1->GetIntTagValue(FT_COMPLETE_SOURCES)*100)/item1->GetIntTagValue(FT_SOURCES), (item2->GetIntTagValue(FT_COMPLETE_SOURCES)*100)/item2->GetIntTagValue(FT_SOURCES));
case 103: //complete sources desc
if (item1->GetIntTagValue(FT_SOURCES) == 0 || item2->GetIntTagValue(FT_SOURCES) == 0 || item1->IsKademlia() || item2->IsKademlia())
return 0; // should never happen, just a sanity check
return CompareUnsigned((item2->GetIntTagValue(FT_COMPLETE_SOURCES)*100)/item2->GetIntTagValue(FT_SOURCES), (item1->GetIntTagValue(FT_COMPLETE_SOURCES)*100)/item1->GetIntTagValue(FT_SOURCES));
case 4: //type asc
return item1->GetFileTypeDisplayStr().Compare(item2->GetFileTypeDisplayStr());
case 104: //type desc
return item2->GetFileTypeDisplayStr().Compare(item1->GetFileTypeDisplayStr());
case 5: //filehash asc
return memcmp(item1->GetFileHash(),item2->GetFileHash(),16);
case 105: //filehash desc
return memcmp(item2->GetFileHash(),item1->GetFileHash(),16);
case 6:
return CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_ARTIST), item2->GetStrTagValue(FT_MEDIA_ARTIST));
case 106:
return -CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_ARTIST), item2->GetStrTagValue(FT_MEDIA_ARTIST));
case 7:
return CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_ALBUM), item2->GetStrTagValue(FT_MEDIA_ALBUM));
case 107:
return -CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_ALBUM), item2->GetStrTagValue(FT_MEDIA_ALBUM));
case 8:
return CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_TITLE), item2->GetStrTagValue(FT_MEDIA_TITLE));
case 108:
return -CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_TITLE), item2->GetStrTagValue(FT_MEDIA_TITLE));
case 9:
return CompareUnsigned(item1->GetIntTagValue(FT_MEDIA_LENGTH), item2->GetIntTagValue(FT_MEDIA_LENGTH));
case 109:
return -CompareUnsigned(item1->GetIntTagValue(FT_MEDIA_LENGTH), item2->GetIntTagValue(FT_MEDIA_LENGTH));
case 10:
return CompareUnsigned(item1->GetIntTagValue(FT_MEDIA_BITRATE), item2->GetIntTagValue(FT_MEDIA_BITRATE));
case 110:
return -CompareUnsigned(item1->GetIntTagValue(FT_MEDIA_BITRATE), item2->GetIntTagValue(FT_MEDIA_BITRATE));
case 11:
return CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_CODEC), item2->GetStrTagValue(FT_MEDIA_CODEC));
case 111:
return -CompareOptLocaleStringNoCase(item1->GetStrTagValue(FT_MEDIA_CODEC), item2->GetStrTagValue(FT_MEDIA_CODEC));
case 12: //path asc
return CompareOptLocaleStringNoCase(item1->GetDirectory(), item2->GetDirectory());
case 112: //path desc
return -CompareOptLocaleStringNoCase(item1->GetDirectory(), item2->GetDirectory());
case 13:
return item1->GetKnownType() - item2->GetKnownType();
case 113:
return -(item1->GetKnownType() - item2->GetKnownType());
default:
return 0;
}
}
void CSearchListCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
int iSelected = 0;
int iToDownload = 0;
int iToPreview = 0;
POSITION pos = GetFirstSelectedItemPosition();
while (pos != NULL)
{
const CSearchFile* pFile = (CSearchFile*)GetItemData(GetNextSelectedItem(pos));
if (pFile)
{
iSelected++;
if (pFile->IsPreviewPossible())
iToPreview++;
if (!theApp.downloadqueue->IsFileExisting(pFile->GetFileHash(), false))
iToDownload++;
}
}
if (thePrefs.IsExtControlsEnabled())
m_SearchFileMenu.EnableMenuItem(MP_RESUMEPAUSED, iToDownload > 0 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_RESUME, iToDownload > 0 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_DETAIL, iSelected == 1 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_GETED2KLINK, iSelected > 0 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_GETHTMLED2KLINK, iSelected > 0 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_REMOVESELECTED, iSelected > 0 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_PREVIEW, iToPreview == 1 ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_REMOVEALL, theApp.emuledlg->searchwnd->CanDeleteAllSearches() ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_REMOVE, theApp.emuledlg->searchwnd->CanDeleteSearch(m_nResultsID) ? MF_ENABLED : MF_GRAYED);
m_SearchFileMenu.EnableMenuItem(MP_FIND, GetItemCount() > 0 ? MF_ENABLED : MF_GRAYED);
CMenu WebMenu;
WebMenu.CreateMenu();
int iWebMenuEntries = theWebServices.GetFileMenuEntries(WebMenu);
UINT flag2 = (iWebMenuEntries == 0 || iSelected != 1) ? MF_GRAYED : MF_STRING;
m_SearchFileMenu.AppendMenu(MF_POPUP | flag2, (UINT_PTR)WebMenu.m_hMenu, GetResString(IDS_WEBSERVICES));
if (iToDownload > 0)
m_SearchFileMenu.SetDefaultItem( ( !thePrefs.AddNewFilesPaused() || !thePrefs.IsExtControlsEnabled() )?MP_RESUME:MP_RESUMEPAUSED);
else
m_SearchFileMenu.SetDefaultItem((UINT)-1);
GetPopupMenuPos(*this, point);
m_SearchFileMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON,point.x,point.y,this);
m_SearchFileMenu.RemoveMenu(m_SearchFileMenu.GetMenuItemCount()-1,MF_BYPOSITION);
VERIFY( WebMenu.DestroyMenu() );
}
BOOL CSearchListCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
{
if (wParam == MP_FIND)
{
OnFindStart();
return TRUE;
}
int iSel = GetNextItem(-1, LVIS_SELECTED | LVIS_FOCUSED);
if (iSel != -1)
{
const CSearchFile* file = (CSearchFile*)GetItemData(iSel);
switch (wParam)
{
case MP_GETED2KLINK:{
CWaitCursor curWait;
CString clpbrd;
POSITION pos = GetFirstSelectedItemPosition();
while (pos!=NULL)
{
if (!clpbrd.IsEmpty())
clpbrd += _T("\r\n");
clpbrd += CreateED2kLink((CSearchFile*)GetItemData(GetNextSelectedItem(pos)));
}
theApp.CopyTextToClipboard(clpbrd);
return TRUE;
}
case MP_GETHTMLED2KLINK:{
CWaitCursor curWait;
CString clpbrd;
POSITION pos = GetFirstSelectedItemPosition();
while (pos!=NULL)
{
if (!clpbrd.IsEmpty())
clpbrd += _T("<br />\r\n");
clpbrd += CreateHTMLED2kLink((CSearchFile*)GetItemData(GetNextSelectedItem(pos)));
}
theApp.CopyTextToClipboard(clpbrd);
return TRUE;
}
case MP_RESUMEPAUSED:
case MP_RESUME:
theApp.emuledlg->searchwnd->DownloadSelected(wParam==MP_RESUMEPAUSED);
return TRUE;
case MPG_DELETE:
case MP_REMOVESELECTED:{
CWaitCursor curWait;
SetRedraw(FALSE);
while (GetFirstSelectedItemPosition()!=NULL)
{
POSITION pos = GetFirstSelectedItemPosition();
CSearchFile* pItem = (CSearchFile*)GetItemData(GetNextSelectedItem(pos));
HideSources(pItem);
theApp.searchlist->RemoveResult(pItem);
}
SetRedraw(TRUE);
return TRUE;
}
case MPG_ALTENTER:
case MP_DETAIL:
if (file){
CSearchResultFileDetailSheet sheet(file);
sheet.DoModal();
}
return TRUE;
case MP_PREVIEW:
if (file){
if (file->GetPreviews().GetSize() > 0){
// already have previews
(new PreviewDlg())->SetFile(file);
}
else{
CUpDownClient* newclient = new CUpDownClient(NULL, file->GetClientPort(),file->GetClientID(),file->GetClientServerIP(),file->GetClientServerPort(), true);
if (!theApp.clientlist->AttachToAlreadyKnown(&newclient,NULL)){
theApp.clientlist->AddClient(newclient);
}
newclient->SendPreviewRequest(file);
// add to res - later
AddLogLine(true, _T("Preview Requested - Please wait"));
}
}
return TRUE;
default:
if (wParam>=MP_WEBURL && wParam<=MP_WEBURL+256){
theWebServices.RunURL(file, wParam);
return TRUE;
}
break;
}
}
switch (wParam){
case MP_REMOVEALL:{
CWaitCursor curWait;
theApp.emuledlg->searchwnd->DeleteAllSearchs();
break;
}
case MP_REMOVE:{
CWaitCursor curWait;
theApp.emuledlg->searchwnd->DeleteSearch(m_nResultsID);
break;
}
}
return FALSE;
}
void CSearchListCtrl::OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult)
{
// To suppress subsequent LVN_DELETEITEM notification messages, return TRUE.
*pResult = TRUE;
}
void CSearchListCtrl::CreateMenues()
{
if (m_SearchFileMenu)
VERIFY( m_SearchFileMenu.DestroyMenu() );
m_SearchFileMenu.CreatePopupMenu();
m_SearchFileMenu.AddMenuTitle(GetResString(IDS_FILE));
m_SearchFileMenu.AppendMenu(MF_STRING,MP_RESUME, GetResString(IDS_DOWNLOAD));
if (thePrefs.IsExtControlsEnabled())
m_SearchFileMenu.AppendMenu(MF_STRING, MP_RESUMEPAUSED, GetResString(IDS_DOWNLOAD) + _T(" (") + GetResString(IDS_PAUSED) + _T(")"));
m_SearchFileMenu.AppendMenu(MF_STRING,MP_PREVIEW, GetResString(IDS_DL_PREVIEW));
if (thePrefs.IsExtControlsEnabled())
m_SearchFileMenu.AppendMenu(MF_STRING,MP_DETAIL, GetResString(IDS_SHOWDETAILS));
m_SearchFileMenu.AppendMenu(MF_SEPARATOR);
m_SearchFileMenu.AppendMenu(MF_STRING,MP_GETED2KLINK, GetResString(IDS_DL_LINK1));
m_SearchFileMenu.AppendMenu(MF_STRING,MP_GETHTMLED2KLINK, GetResString(IDS_DL_LINK2));
m_SearchFileMenu.AppendMenu(MF_SEPARATOR);
m_SearchFileMenu.AppendMenu(MF_STRING,MP_REMOVESELECTED, GetResString(IDS_REMOVESELECTED));
m_SearchFileMenu.AppendMenu(MF_STRING,MP_REMOVE, GetResString(IDS_REMOVESEARCHSTRING));
m_SearchFileMenu.AppendMenu(MF_STRING,MP_REMOVEALL, GetResString(IDS_REMOVEALLSEARCH));
m_SearchFileMenu.AppendMenu(MF_SEPARATOR);
m_SearchFileMenu.AppendMenu(MF_STRING, MP_FIND, GetResString(IDS_FIND));
}
void CSearchListCtrl::OnLvnGetInfoTip(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLVGETINFOTIP pGetInfoTip = reinterpret_cast<LPNMLVGETINFOTIP>(pNMHDR);
if (pGetInfoTip->iSubItem == 0)
{
LVHITTESTINFO hti = {0};
::GetCursorPos(&hti.pt);
ScreenToClient(&hti.pt);
bool bOverMainItem = (SubItemHitTest(&hti) != -1 && hti.iItem == pGetInfoTip->iItem && hti.iSubItem == 0);
// those tooltips are very nice for debugging/testing but pretty annoying for general usage
// enable tooltips only if Shift+Ctrl is currently pressed
bool bShowInfoTip = GetSelectedCount() > 1 || ((GetKeyState(VK_SHIFT) & 0x8000) && (GetKeyState(VK_CONTROL) & 0x8000));
if (!bShowInfoTip){
if (!bOverMainItem){
// don' show the default label tip for the main item, if the mouse is not over the main item
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -