localfilelistctrl.cpp

来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 2,497 行 · 第 1/5 页

CPP
2,497
字号
// FileZilla - a Windows ftp client

// Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>

// 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.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// LocalFileListCtrl.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "FileZilla.h"
#include "LocalFileListCtrl.h"
#include "LocalView2.h"
#include "process.h"
#include "mainfrm.h"
#include "direct.h"
#include "EnterSomething.h"
#include "TransferAsDlg.h"
#include "PathFunctions.h"
#include "CommandQueue.h"
#include "FtpListCtrl.h"
#include "DirTreeCtrl.h"
#include "LocalView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLocalFileListCtrl

CLocalFileListCtrl::CLocalFileListCtrl(CLocalView2 *pOwner)
{
	ASSERT(pOwner);

	m_pOwner = pOwner;

	m_Fullpath = ".."; //Just anything invalid
	m_nStyle = -1;
	for (int i = 0; i < 4; i++)
		m_Columns[i] = i;
	m_nHideColumns = 0;
	m_bUpdating = FALSE;

	m_nDragHilited = -1;
}

CLocalFileListCtrl::~CLocalFileListCtrl()
{
}


BEGIN_MESSAGE_MAP(CLocalFileListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(CLocalFileListCtrl)
	ON_WM_CREATE()
	ON_MESSAGE(WM_APP+1, OnUpdateContinue)
	ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
	ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginlabeledit)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_WM_CONTEXTMENU()
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	ON_WM_DESTROY()
	ON_WM_DROPFILES()
	ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_LOCALCONTEXT_ADDTOQUEUE, OnLocalcontextAddtoqueue)
	ON_COMMAND(ID_LOCALCONTEXT_CREATEDIRECTORY, OnLocalcontextCreatedirectory)
	ON_COMMAND(ID_LOCALCONTEXT_DELETE, OnLocalcontextDelete)
	ON_COMMAND(ID_LOCALCONTEXT_OPEN, OnLocalcontextOpen)
	ON_COMMAND(ID_LOCALCONTEXT_PROPERTIES, OnLocalcontextProperties)
	ON_COMMAND(ID_LOCALCONTEXT_RENAME, OnLocalcontextRename)
	ON_COMMAND(ID_LOCALCONTEXT_UPLOAD, OnLocalcontextUpload)
	ON_COMMAND(ID_LOCALCONTEXT_UPLOADAS, OnLocalcontextUploadas)
	ON_COMMAND(ID_LOCALCONTEXT_VIEWEDIT, OnLocalcontextViewEdit)
	ON_WM_VSCROLL()
	ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen f黵 Nachrichten CLocalFileListCtrl 

void CLocalFileListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
	POSITION selpos = GetFirstSelectedItemPosition();
	if (selpos)
	{
		int nItem = GetNextSelectedItem(selpos);
		int nIndex = m_IndexMapping[nItem];
		if (m_FileData[nIndex].bIsDir)
		{
			CString newpath;
			if (!nItem && m_Fullpath!="")
			{
				newpath=m_Fullpath;
				newpath.TrimRight('\\');
				int pos=newpath.ReverseFind('\\');
				newpath=newpath.Left(pos+1);
			}
			else
				newpath=m_Fullpath+m_FileData[nIndex].Name + "\\";
			m_pOwner->SetLocalFolder(newpath);
			m_pOwner->SetLocalFolderOut(newpath);

		}
		else
		{
			int nAction = COptions::GetOptionVal(OPTION_LOCAL_DOUBLECLICK_ACTION);
			if (nAction == 1)
			{
				CString file = m_Fullpath+m_FileData[nIndex].Name;
				SHELLEXECUTEINFO sei = {0};
				sei.cbSize = sizeof(SHELLEXECUTEINFO);
				sei.lpFile = file;
				sei.nShow = SW_SHOWNORMAL;
				BOOL b = ShellExecuteEx(&sei);
			}
			else
			{
				CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
				pMainFrame->AddQueueItem(FALSE, GetItemText(nItem,0), "", m_Fullpath, CServerPath(), !nAction);
				if (!nAction)
					pMainFrame->TransferQueue(2);
			}
		}
	}
	*pResult = 0;
}

void CLocalFileListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
	
}


CString CLocalFileListCtrl::GetFolder() const
{
	return m_Fullpath;
}

int CLocalFileListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CListCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	int widths[5]={150, 66, 100, 99};
	if (COptions::GetOptionVal(OPTION_REMEMBERLOCALCOLUMNWIDTHS))
	{
		CString tmp = COptions::GetOption(OPTION_LOCALCOLUMNWIDTHS);
		int pos = -1;
		int i;
		for (i = 0; i<3; i++)
		{
			int oldpos = pos + 1;
			pos = tmp.Find(_T(" "), oldpos);
			if (pos == -1)
				break;
			tmp.SetAt(pos, 0);
			int size=_ttoi(tmp.Mid(oldpos));
			if (size>0)
				widths[i]=size;
		}
		if (i==3)
		{
			int size=_ttoi(tmp.Mid(pos+1));
			if (size>0)
				widths[i]=size;
		}
	}
	
	CString str;
	str.LoadString(IDS_HEADER_FILENAME);
	InsertColumn(0,str,LVCFMT_LEFT, widths[0]);
	str.LoadString(IDS_HEADER_FILESIZE);
	InsertColumn(1,str,LVCFMT_RIGHT, widths[1]);
	str.LoadString(IDS_HEADER_FILETYPE);
	InsertColumn(2,str,LVCFMT_LEFT, widths[2]);
	str.LoadString(IDS_HEADER_LASTMODIFIED);
	InsertColumn(3,str,LVCFMT_LEFT, widths[3]);
	
	m_SortImg.Create( 8, 8, ILC_MASK, 3, 3 );
	HICON Icon;
	Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_EMPTY));
	m_SortImg.Add(Icon);
	Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_UP));
	m_SortImg.Add(Icon);
	Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_DOWN));
	m_SortImg.Add(Icon);
	m_SortImg.SetBkColor(CLR_NONE);
	
	SetListStyle(0);
	
	int nSort = COptions::GetOptionVal(OPTION_LOCALCOLUMNSORT);
	m_sortdir = (nSort >> 4) % 3;
	if (!m_sortdir)
		m_sortdir = 1;
	m_sortcolumn = (nSort >> 1) & 0x07;
	if (m_sortcolumn > 3)
		m_sortcolumn = 0;

	DragAcceptFiles(TRUE);

	SetExtendedStyle(LVS_EX_INFOTIP);

	return 0;
}

/////////////////////////////////////////////////
BOOL CLocalFileListCtrl::GetSysImgList()
/////////////////////////////////////////////////
{
	CImageList sysImgList;
	SHFILEINFO shFinfo;
	
	HIMAGELIST hImageList = 0;
	CString errorMessage;
	TCHAR filename[MAX_PATH + 10];

	if (GetModuleFileName(0, filename, MAX_PATH + 10))
	{
		hImageList = (HIMAGELIST)SHGetFileInfo(filename,
							 0,
							 &shFinfo,
							 sizeof( shFinfo ),
							 SHGFI_SYSICONINDEX |
							 ((m_nStyle == LVS_ICON)?SHGFI_ICON:SHGFI_SMALLICON) );

		if (!hImageList)
		{
			int errorCode = GetLastError();
			TCHAR buffer[1000];
			memset(buffer, 0, 1000);
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);

			CString str;
			str.Format(_T("SHGetFileInfo failed with error %d: %s"), errorCode, buffer);
			errorMessage += str;
		}
	}
	else
	{
		int errorCode = GetLastError();
		TCHAR buffer[1000];
		memset(buffer, 0, 1000);
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);
		
		CString str;
		str.Format(_T("GetModuleFileName failed with error %d: %s"), errorCode, buffer);
		errorMessage += str;
	}
	if (!hImageList)
	{
		/*
		 * Fall back to C:\\
		 * Not bullerproof, but better than nothing
		 */		
		hImageList = (HIMAGELIST)SHGetFileInfo(_T("C:\\"),
							 0,
							 &shFinfo,
							 sizeof( shFinfo ),
							 SHGFI_SYSICONINDEX |
							 ((m_nStyle == LVS_ICON)?SHGFI_ICON:SHGFI_SMALLICON) );

		if (!hImageList)
		{
			int errorCode = GetLastError();
			TCHAR buffer[1000];
			memset(buffer, 0, 1000);
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);

			CString str;
			str.Format(_T("SHGetFileInfo failed with error %d: %s"), errorCode, buffer);
			if (errorMessage != _T(""))
				errorMessage += _T("\n");
			errorMessage += str;
		}
	}

	if (!hImageList)
	{
		AfxMessageBox(errorMessage);
		return FALSE;
	}

	sysImgList.Attach(hImageList);
	
	SetImageList( &sysImgList, (m_nStyle == LVS_ICON)?LVSIL_NORMAL:LVSIL_SMALL);
	sysImgList.Detach();

	return TRUE;
}

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

BOOL greater(const CString &str1, const CString &str2, BOOL isdir1, BOOL isdir2)
{
	if (isdir1 && !isdir2)
		return FALSE;
	if (!isdir1 && isdir2)
		return TRUE;

	if (str1.CollateNoCase(str2) > 0)
		return TRUE;
	return FALSE;
}

BOOL lesser(const CString &str1, const CString &str2, BOOL isdir1, BOOL isdir2)
{
	if (isdir1 && !isdir2)
		return TRUE;
	if (!isdir1 && isdir2)
		return FALSE;
	
	if (str2.CollateNoCase(str1) > 0)
		return TRUE;
	return FALSE;
}

BOOL greaterbytype(const CString &str1, const CString &str2, const BOOL isdir1, const BOOL isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return FALSE;
	if (!isdir1 && isdir2)
		return TRUE;
	if (str1>str2)
		return TRUE;
	if (str1==str2)
	{
		if (fn1.CollateNoCase(fn2) > 0)
			return TRUE;
	}
	return FALSE;
}

BOOL lesserbytype(const CString &str1, const CString &str2, const BOOL isdir1, const BOOL isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return TRUE;
	if (!isdir1 && isdir2)
		return FALSE;
	if (str1<str2)
		return TRUE;
	if (str1==str2)
	{
		if (fn1.CollateNoCase(fn2) < 0)
			return TRUE;
	}
	return FALSE;
}

BOOL greaterbytime(const CTime &time1, const CTime &time2, const BOOL &isdir1, const BOOL &isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return FALSE;
	if (!isdir1 && isdir2)
		return TRUE;
	if (time1>time2)
		return TRUE;
	if (time1==time2)
	{
		if (fn1.CollateNoCase(fn2) > 0)
			return TRUE;
	}
	return FALSE;
}

BOOL lesserbytime(const CTime &time1, const CTime &time2, const BOOL &isdir1, const BOOL &isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return TRUE;
	if (!isdir1 && isdir2)
		return FALSE;
	if (time1<time2)
		return TRUE;
	if (time1==time2)
	{
		if (fn1.CollateNoCase(fn2) < 0)
			return TRUE;
	}
	return FALSE;
}

BOOL greaterbysize(const __int64 &size1, const __int64 &size2, BOOL isdir1, BOOL isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return FALSE;
	if (!isdir1 && isdir2)
		return TRUE;
	if (size1>size2)
		return TRUE;
	if (size1==size2)
	{
		if (fn1.CollateNoCase(fn2) > 0)
			return TRUE;
	}
	return FALSE;
}

BOOL lesserbysize(const __int64 &size1, const __int64 &size2, BOOL isdir1, BOOL isdir2, const CString &fn1, const CString &fn2)
{
	if (isdir1 && !isdir2)
		return TRUE;
	if (!isdir1 && isdir2)
		return FALSE;
	if (size1<size2)
		return TRUE;
	if (size1==size2)
	{
		if (fn1.CollateNoCase(fn2) < 0)
			return TRUE;
	}
	return FALSE;
}

void CLocalFileListCtrl::quicksortbyname(const BOOL &direction, int anf, int ende)
{
	int l=anf;
	int r=ende;
	CString tmp;
	CString ref=m_FileData[m_IndexMapping[(l+r)/2]].lName;
	BOOL bRefIsDir=m_FileData[m_IndexMapping[(l+r)/2]].bIsDir;
	do
	{
		if (direction)
		{
			while (lesser (m_FileData[m_IndexMapping[l]].lName, ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir) && (l<ende)) l++;
			while (greater(m_FileData[m_IndexMapping[r]].lName, ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir) && (r>anf)) r--;
		}
		else
		{
			while (greater(m_FileData[m_IndexMapping[l]].lName, ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir) && (l<ende)) l++;
			while (lesser (m_FileData[m_IndexMapping[r]].lName, ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir) && (r>anf)) r--;
		}
		if (l<=r)
		{
			int tmp=m_IndexMapping[l];
			m_IndexMapping[l]=m_IndexMapping[r];
			m_IndexMapping[r]=tmp;
			l++;
			r--;
		}
	} 
	while (l<=r);

	if (anf<r) quicksortbyname(direction, anf, r);
	if (l<ende) quicksortbyname(direction, l, ende);
}

void CLocalFileListCtrl::quicksortbytype(const std::vector<CString> &array, const BOOL &direction, int anf, int ende)
{
	int l=anf;
	int r=ende;
	CString tmp;
	CString ref=array[m_IndexMapping[(l+r)/2]];
	CString refname=m_FileData[m_IndexMapping[(l+r)/2]].lName;
	BOOL bRefIsDir=m_FileData[m_IndexMapping[(l+r)/2]].bIsDir;
	do
    {
		if (direction)
		{
			while (lesserbytype (array[m_IndexMapping[l]], ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[l]].lName, refname) && (l<ende)) l++;
			while (greaterbytype(array[m_IndexMapping[r]], ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[r]].lName, refname) && (r>anf)) r--;
		}
		else
		{
			while (greaterbytype(array[m_IndexMapping[l]], ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[l]].lName, refname) && (l<ende)) l++;
			while (lesserbytype (array[m_IndexMapping[r]], ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[r]].lName, refname) && (r>anf)) r--;
		}
		if (l<=r)
		{
			int tmp=m_IndexMapping[l];
			m_IndexMapping[l]=m_IndexMapping[r];
			m_IndexMapping[r]=tmp;
			l++;
			r--;
		}
    } 
	while (l<=r);

⌨️ 快捷键说明

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