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

📄 ftplistctrl.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		m_FilesToDelete.clear();
		m_FilesToDeletePaths.clear();
		UpdateStatusBar();
		return;
	}

	m_IndexMapping.push_back(m_pDirectory->num);
	m_IndexMapping.resize(list->num+1);
	for (int i=0;i<list->num;i++)
		m_IndexMapping[i+1]=i;

	SetItemCount(m_IndexMapping.size());
	
	SortList(m_sortcolumn,m_sortdir);

	//Restore item selection
	for (std::list<CString>::iterator iter=SelectedList.begin(); iter!=SelectedList.end(); iter++)
	{
		for( int nListItem = 1; nListItem < GetItemCount(); nListItem++ )
		{
			if (*iter==m_pDirectory->direntry[m_IndexMapping[nListItem]].lName)
			{
				SetItemState( nListItem, LVIS_SELECTED, LVIS_SELECTED);
				break;
			}
		}
	}
	if (bDotsSelected)
		SetItemState( 0, LVIS_SELECTED, LVIS_SELECTED);

	m_bUpdating = FALSE;
	UpdateStatusBar();

	//Check if complex operation in progress
	if (m_nBatchAction && m_pDirectory->path!=OldPath)
	{
		//Check if current path is valid
		if (!m_pDirectory->path.IsSubdirOf(m_PathsVisited.front()))
		{ //Path is not a subdir of the startdir
			DoNextStep();
			return;
		}
		for (std::list<CServerPath>::iterator iter=m_PathsVisited.begin(); iter!=m_PathsVisited.end(); iter++)
			if (m_pDirectory->path==*iter)
			{ //Path already processed
				DoNextStep();
				return;
			}
		m_PathsVisited.push_back(m_pDirectory->path);

		CString subdir;
		CServerPath path=m_pDirectory->path;
		while(path.IsSubdirOf(m_PathsVisited.front()))
		{
			subdir=_T("\\")+path.GetLastSegment()+subdir;
			path=path.GetParent();
		}
		subdir.TrimLeft( _T("\\") );
		
		if (!m_pDirectory->num &&
			m_nBatchAction == 1)
		{
			//Create empty local directories
			CString pathToCreate = pMainFrame->GetLocalPane2()->GetLocalFolder()+_T("\\")+subdir;
			while(pathToCreate.Replace( _T("\\\\"), _T("\\") ));
			
			pathToCreate.TrimRight(_T("\\"));
			pathToCreate += _T("\\");
			CString path2;
			while (pathToCreate!="")
			{
				path2+=pathToCreate.Left(pathToCreate.Find( _T("\\") )+1);
				pathToCreate = pathToCreate.Mid(pathToCreate.Find( _T("\\") )+1);
				int res = CreateDirectory(path2, 0);
			}
		}

		for (int i=0; i<m_pDirectory->num; i++)
		{ //Process all dir entries
			if (m_pDirectory->direntry[i].dir)
			{ //Change directory

				//Don't change to parent and own dir
				if ((m_pDirectory->direntry[i].name==".")||(m_pDirectory->direntry[i].name==".."))
					continue;

				if (m_nBatchAction == 2 && m_pDirectory->direntry[i].bLink)
				{
					m_FilesToDelete.push_back(m_pDirectory->direntry[i].name);
					m_FilesToDeletePaths.push_back(m_pDirectory->path);
				}
				else
				{
					t_folder folder;
					folder.path = m_pDirectory->path;
					folder.subdir = m_pDirectory->direntry[i].name;
					m_PathsToVisit.push_front(folder);
				}
			}
			else
			{
				//Download/Delete file
				if (m_nBatchAction == 1)
					pMainFrame->AddQueueItem(TRUE, m_pDirectory->direntry[i].name, subdir, _T(""), m_pDirectory->path, m_nFolderDownloadStart, m_transferuser, m_transferpass);
				else if (m_nBatchAction == 2)
				{
					m_FilesToDelete.push_back(m_pDirectory->direntry[i].name);
					m_FilesToDeletePaths.push_back(m_pDirectory->path);
				}
				else
					ASSERT(FALSE);
			}
		}
		DoNextStep();
	}
}

void CFtpListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
	if (pResult)
		*pResult = 0;
	
	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
	if (pMainFrame->m_pCommandQueue->IsLocked())
		return;
	POSITION selpos = GetFirstSelectedItemPosition();
	if (selpos)
	{
		int nItem = GetNextSelectedItem(selpos);
		int index=m_IndexMapping[nItem];
		if (index==m_pDirectory->num)
			ChangeDir(m_pDirectory->path, "..", FALSE, FZ_LIST_USECACHE|FZ_LIST_EXACT);		
		else if (m_pDirectory->direntry[index].dir)
		{
			CString name=m_pDirectory->direntry[index].name;
			ChangeDir(m_pDirectory->path, name, FALSE, FZ_LIST_USECACHE|FZ_LIST_EXACT);		
		}
		else
		{
			int nAction = COptions::GetOptionVal(OPTION_REMOTE_DOUBLECLICK_ACTION);
			if (nAction == 1)
			{
				pMainFrame->AddQueueItem(TRUE, m_pDirectory->direntry[index].name, _T(""), _T(""), m_pDirectory->path, TRUE, _T(""), _T(""), 2);	
				pMainFrame->TransferQueue(2);
			}
			else
			{
				pMainFrame->AddQueueItem(TRUE, m_pDirectory->direntry[index].name, "", "", m_pDirectory->path, !nAction);
				if (!nAction)
					pMainFrame->TransferQueue(2);
			}
		}
	}
}

void CFtpListCtrl::SortList(int item, int direction /*=0*/)
{	
	if (!m_pDirectory)
		return;
	if (item>3)
		return;
	UINT nID[7] = {IDS_HEADER_FILENAME, IDS_HEADER_FILESIZE, IDS_HEADER_FILETYPE, IDS_HEADER_DATE, IDS_HEADER_TIME, IDS_HEADER_PERMISSIONS, IDS_HEADER_OWNERGROUP};

	if (!direction)
	{
		if (item!=m_sortcolumn)
			m_sortdir=1;
		else
		{
			m_sortdir=(++m_sortdir%3);
			if (!m_sortdir)
				m_sortdir++;
		}
			
	}
	else if (direction != -1)
		m_sortdir = direction;

	if (item == -1)
		item = m_sortcolumn;

	CString headertext;
	headertext.LoadString(nID[m_Columns[m_sortcolumn]]);
	CHeaderCtrl *header=GetHeaderCtrl();
	HDITEM *hdi=new HDITEM;
	hdi->pszText=headertext.GetBuffer(0);
	hdi->cchTextMax=0;
	hdi->mask= HDI_TEXT | HDI_FORMAT;
	switch (m_Columns[m_sortcolumn])
	{
	case 1:
		hdi->fmt = HDF_RIGHT | HDF_STRING;
		break;
	default:
		hdi->fmt = HDF_LEFT | HDF_STRING;
	}
	hdi->mask= HDI_TEXT | HDI_IMAGE | HDI_FORMAT;
	hdi->iImage=0; // My ascending image list index
	header->SetItem( m_sortcolumn, hdi );

	headertext.ReleaseBuffer();
	headertext.LoadString(nID[m_Columns[item]]);
	
	hdi->pszText=headertext.GetBuffer(0);
	hdi->mask= HDI_TEXT | HDI_IMAGE | HDI_FORMAT;
	hdi->iImage= m_sortdir; // My ascending image list index
	hdi->fmt=((m_Columns[item]!=1)?HDF_LEFT:HDF_RIGHT) | HDF_IMAGE | HDF_STRING | HDF_BITMAP_ON_RIGHT;
	header->SetItem( item, hdi );
	delete hdi;
	headertext.ReleaseBuffer();
	m_sortcolumn=item;
	if (GetItemCount()<2)
		return;

	std::list<int> SelectedItemsList;
	
	int i;
	for (i=1; i<GetItemCount(); i++)
	{
		if (GetItemState( i, LVIS_SELECTED))
		{
			SelectedItemsList.push_back(m_IndexMapping[i]);
			SetItemState( i, 0, LVIS_SELECTED);
		}
	}


	if (!m_Columns[m_sortcolumn])
		QSortByName(1, GetItemCount()-1);
	else if (m_Columns[m_sortcolumn]==1)
		QSortBySize(1, GetItemCount()-1);
	else if (m_Columns[m_sortcolumn]==2)
	{	//Sort by filetype
		//Since this is a column that is filled while displaying,
		//we have to load the filetypes for every file

		std::vector<CString> typeArray;
		typeArray.resize(GetItemCount());
		typeArray[0] = _T("");
		for (int i = 1; i<GetItemCount(); i++)
		{
			typeArray[m_IndexMapping[i]] = GetType(m_pDirectory->direntry[m_IndexMapping[i]].lName, m_pDirectory->direntry[m_IndexMapping[i]].dir);
			typeArray[m_IndexMapping[i]].MakeLower();
		}
		QSortByType(typeArray, 1, GetItemCount()-1);
	}
	else if (m_Columns[m_sortcolumn]==3 || m_Columns[m_sortcolumn]==4)
		QSortByTime(1, GetItemCount()-1);

	for (i=1; i<GetItemCount(); i++)
	{
		int nIndex = m_IndexMapping[i];
		if (SelectedItemsList.empty())
			break;
		for (std::list<int>::iterator iter=SelectedItemsList.begin(); iter!=SelectedItemsList.end(); iter++)
			if (*iter==nIndex)
			{
				SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
				SelectedItemsList.erase(iter);
				break;
			}
	}

	RedrawItems(1, GetItemCount()-1);

	return;
}

void CFtpListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	SortList(pNMListView->iSubItem);
	
	*pResult = 0;
}

BOOL CFtpListCtrl::GetTransferfile(t_transferfile &transferfile)
{
	if (!m_pDirectory)
		return FALSE;
	transferfile.size=0;
	transferfile.server=m_pDirectory->server;
	for (int i=0;i<m_pDirectory->num;i++)
	{
		if (m_pDirectory->direntry[i].name==transferfile.remotefile)
		{
			transferfile.size=m_pDirectory->direntry[i].size;
			return TRUE;
		}
		
	}
	return TRUE;
}

void CFtpListCtrl::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	m_transferuser=m_transferpass="";
	if (!GetItemCount() || !m_pDirectory)
		return;
	CMenu menu;
	menu.LoadMenu(IDR_FTPCONTEXTMENU);

	CMenu* pPopup = menu.GetSubMenu(0);
	ASSERT(pPopup != NULL);
	CWnd* pWndPopupOwner = this;
	//while (pWndPopupOwner->GetStyle() & WS_CHILD)
	//	pWndPopupOwner = pWndPopupOwner->GetParent();

	POSITION selpos=GetFirstSelectedItemPosition();

	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
	if (!selpos || pMainFrame->m_pCommandQueue->IsLocked())
	{
		pPopup->EnableMenuItem(ID_FTPCONTEXT_DOWNLOADAS, MF_GRAYED);	
		pPopup->EnableMenuItem(ID_FTPCONTEXT_DOWNLOAD, MF_GRAYED);	
		pPopup->EnableMenuItem(ID_FTPCONTEXT_ADDTOQUEUE, MF_GRAYED);
		pPopup->EnableMenuItem(ID_FTPCONTEXT_DELETE, MF_GRAYED);	
		pPopup->EnableMenuItem(ID_FTPCONTEXT_RENAME, MF_GRAYED);	
		pPopup->EnableMenuItem(ID_FTPCONTEXT_OPEN, MF_GRAYED);
		pPopup->EnableMenuItem(ID_FTPCONTEXT_ATTRIBUTES, MF_GRAYED);
		pPopup->EnableMenuItem(ID_FTPCONTEXT_VIEWEDIT, MF_GRAYED);
		if (point.x==-1 || point.y==-1)
		{
			point.x=5;
			point.y=5;
			ClientToScreen(&point);
		}
	}
	else
	{
		int nItem = GetNextSelectedItem(selpos);

		if (point.x==-1 || point.y==-1)
		{
			CRect rect;
			GetItemRect(nItem,&rect,LVIR_LABEL);
			point.x=rect.left+5;
			point.y=rect.top+5;
			ClientToScreen(&point);
		}

		int index=m_IndexMapping[nItem];
		if (index==m_pDirectory->num) //.. item
		{
			pPopup->EnableMenuItem(ID_FTPCONTEXT_DOWNLOADAS, MF_GRAYED);	
			pPopup->EnableMenuItem(ID_FTPCONTEXT_DOWNLOAD, MF_GRAYED);	
			pPopup->EnableMenuItem(ID_FTPCONTEXT_ADDTOQUEUE, MF_GRAYED);
			pPopup->EnableMenuItem(ID_FTPCONTEXT_DELETE, MF_GRAYED);	
			pPopup->EnableMenuItem(ID_FTPCONTEXT_RENAME, MF_GRAYED);	
			pPopup->EnableMenuItem(ID_FTPCONTEXT_ATTRIBUTES, MF_GRAYED);
			pPopup->EnableMenuItem(ID_FTPCONTEXT_VIEWEDIT, MF_GRAYED);
		}
		else
		{
			if (m_pDirectory->direntry[index].dir)
			{
				pPopup->SetDefaultItem(ID_FTPCONTEXT_OPEN);
				pPopup->EnableMenuItem(ID_FTPCONTEXT_VIEWEDIT, MF_GRAYED);
			}
			else
			{
				int nAction = COptions::GetOptionVal(OPTION_REMOTE_DOUBLECLICK_ACTION);
				if (nAction == 1)
					pPopup->SetDefaultItem(ID_FTPCONTEXT_VIEWEDIT);
				else if (nAction == 2)
					pPopup->SetDefaultItem(ID_FTPCONTEXT_ADDTOQUEUE);
				else
					pPopup->SetDefaultItem(ID_FTPCONTEXT_DOWNLOAD);
				pPopup->EnableMenuItem(ID_FTPCONTEXT_OPEN, MF_GRAYED);
			}
		}

		nItem = GetNextSelectedItem(selpos);
		while (nItem!=-1)
		{
			int nAction = COptions::GetOptionVal(OPTION_REMOTE_DOUBLECLICK_ACTION);
			if (nAction == 2)
				pPopup->SetDefaultItem(ID_FTPCONTEXT_ADDTOQUEUE);
			else
				pPopup->SetDefaultItem(ID_FTPCONTEXT_DOWNLOAD);

			int index=m_IndexMapping[nItem];
			if (index==m_pDirectory->num ||
				m_pDirectory->direntry[index].dir) //.. item
				pPopup->EnableMenuItem(ID_FTPCONTEXT_VIEWEDIT, MF_GRAYED);
		
			pPopup->EnableMenuItem(ID_FTPCONTEXT_OPEN, MF_GRAYED);
			pPopup->EnableMenuItem(ID_FTPCONTEXT_RENAME, MF_GRAYED);
			nItem = GetNextSelectedItem(selpos);
		}
	}
		
	pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
		pWndPopupOwner);
}

void CFtpListCtrl::OnFtpcontextOpen() 
{
	if (!GetItemCount() || !m_pDirectory)
		return;

	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
	if (pMainFrame->m_pCommandQueue->IsLocked())
		return;
	if (m_nBatchAction || !m_PathsToVisit.empty() || !m_PathsVisited.empty())
		return;

	POSITION selpos = GetFirstSelectedItemPosition();
	if (!selpos)
		return;
	
	int nItem = GetNextSelectedItem(selpos);
	int index = m_IndexMapping[nItem];

	if (index == m_pDirectory->num)
		ChangeDir(m_pDirectory->path,"..",FALSE,FZ_LIST_USECACHE|FZ_LIST_EXACT);		
	else if (m_pDirectory->direntry[index].dir)
		ChangeDir(m_pDirectory->path,m_pDirectory->direntry[index].name,FALSE,FZ_LIST_USECACHE|FZ_LIST_EXACT);		
	else
	{
	/*	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
		pMainFrame->AddQueueItem(TRUE, m_pDirectory->direntry[index].name, _T(""), _T(""), m_pDirectory->path, TRUE, _T(""), _T(""), 1);
		pMainFrame->TransferQueue(2);*/
	}
}

void CFtpListCtrl::OnFtpcontextDownload() 
{
	if (!GetItemCount() || !m_pDirectory)
		return;

	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
	if (pMainFrame->m_pCommandQueue->IsLocked())
		return;
	if (m_nBatchAction || !m_PathsToVisit.empty() || !m_PathsVisited.empty())
		return;

	POSITION selpos=GetFirstSelectedItemPosition();
	if (pMainFrame->m_pCommandQueue->IsBusy())
	{
		while (selpos)
		{
			int nItem = GetNextSelectedItem(selpos);
			int index=m_IndexMapping[nItem];
			ASSERT(index!=m_pDirectory->num);
			if (m_pDirectory->direntry[index].dir)
			{
				MessageBeep(MB_ICONEXCLAMATION);
				return;
			}
		}
		selpos=GetFirstSelectedItemPosition();
	}
	while (selpos)
	{
		int nItem = GetNextSelectedItem(selpos);
		int index=m_IndexMapping[nItem];
		ASSERT(index!=m_pDirectory->num);
		if (m_pDirectory->direntry[index].dir)
		{
			t_folder folder;
			folder.path = m_pDirectory->path;
			folder.subdir = m_pDirectory->direntry[index].name;
			m_PathsToVisit.push_back(folder);
			pMainFrame->m_pCommandQueue->SetLock(TRUE);
		}
		else
			pMainFrame->AddQueueItem(TRUE,m_pDirectory->direntry[index].name,"","",m_pDirectory->path,TRUE,m_transferuser,m_transferpass);
	}
	if (!m_PathsToVisit.empty())
	{
		m_nFolderDownloadStart = TRUE;
		m_PathsVisited.push_front(m_pDirectory->path);
		m_nBatchAction = 1;
		DoNextStep();
	}
	else
		pMainFrame->TransferQueue(2);
}

void CFtpListCtrl::OnFtpcontextAddtoqueue() 
{
	CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
	if (pMainFrame->m_pCommandQueue->IsLocked())
		return;
	if (m_nBatchAction || !m_PathsToVisit.empty() || !m_PathsVisited.empty())
		return;

	POSITION selpos=GetFirstSelectedItemPosition();
	if (pMainFrame->m_pCommandQueue->IsBusy())
	{

⌨️ 快捷键说明

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