Exemple #1
0
int CFileZillaEnginePrivate::List(const CListCommand &command)
{
	if (!IsConnected())
		return FZ_REPLY_NOTCONNECTED;

	if (command.GetPath().empty() && !command.GetSubDir().empty())
		return FZ_REPLY_SYNTAXERROR;

	if (command.GetFlags() & LIST_FLAG_LINK && command.GetSubDir().empty())
		return FZ_REPLY_SYNTAXERROR;

	int flags = command.GetFlags();
	bool const refresh = (command.GetFlags() & LIST_FLAG_REFRESH) != 0;
	bool const avoid = (command.GetFlags() & LIST_FLAG_AVOID) != 0;
	if (refresh && avoid)
		return FZ_REPLY_SYNTAXERROR;

	if (!refresh && !command.GetPath().empty())
	{
		const CServer* pServer = m_pControlSocket->GetCurrentServer();
		if (pServer)
		{
			CServerPath path(CPathCache::Lookup(*pServer, command.GetPath(), command.GetSubDir()));
			if (path.empty() && command.GetSubDir().empty())
				path = command.GetPath();
			if (!path.empty())
			{
				CDirectoryListing *pListing = new CDirectoryListing;
				CDirectoryCache cache;
				bool is_outdated = false;
				bool found = cache.Lookup(*pListing, *pServer, path, true, is_outdated);
				if (found && !is_outdated)
				{
					if (pListing->get_unsure_flags())
						flags |= LIST_FLAG_REFRESH;
					else {
						if (!avoid) {
							m_lastListDir = pListing->path;
							m_lastListTime = CDateTime::Now();
							CDirectoryListingNotification *pNotification = new CDirectoryListingNotification(pListing->path);
							AddNotification(pNotification);
						}
						delete pListing;
						return FZ_REPLY_OK;
					}
				}
				if (is_outdated)
					flags |= LIST_FLAG_REFRESH;
				delete pListing;
			}
		}
	}
	if (IsBusy())
		return FZ_REPLY_BUSY;

	m_pCurrentCommand = command.Clone();
	return m_pControlSocket->List(command.GetPath(), command.GetSubDir(), flags);
}
void CRemoteTreeView::DisplayItem(wxTreeItemId parent, const CDirectoryListing& listing)
{
	DeleteChildren(parent);

	const wxString path = listing.path.GetPath();

	CFilterDialog filter;
	for (unsigned int i = 0; i < listing.GetCount(); ++i) {
		if (!listing[i].is_dir())
			continue;

		if (filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].time))
			continue;

		const wxString& name = listing[i].name;
		CServerPath subdir = listing.path;
		subdir.AddSegment(name);

		CDirectoryListing subListing;

		if (m_pState->m_pEngine->CacheLookup(subdir, subListing) == FZ_REPLY_OK) {
			wxTreeItemId child = AppendItem(parent, name, 0, 2, 0);
			SetItemImages(child, false);

			if (HasSubdirs(subListing, filter))
				AppendItem(child, _T(""), -1, -1);
		}
		else {
			wxTreeItemId child = AppendItem(parent, name, 1, 3, 0);
			SetItemImages(child, true);
		}
	}
	SortChildren(parent);
}
bool CRemoteTreeView::HasSubdirs(const CDirectoryListing& listing, const CFilterManager& filter)
{
	if (!listing.has_dirs())
		return false;

	if (!filter.HasActiveFilters())
		return true;

	const wxString path = listing.path.GetPath();
	for (unsigned int i = 0; i < listing.GetCount(); i++)
	{
		if (!listing[i].is_dir())
			continue;

		if (filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].time))
			continue;

		return true;
	}

	return false;
}
void CRemoteTreeView::OnMenuChmod(wxCommandEvent&)
{
	if (!m_pState->IsRemoteIdle())
		return;

	if (!m_contextMenuItem)
		return;

	const CServerPath& path = GetPathFromItem(m_contextMenuItem);
	if (path.empty())
		return;

	const bool hasParent = path.HasParent();

	CChmodDialog* pChmodDlg = new CChmodDialog;

	// Get current permissions of directory
	const wxString& name = GetItemText(m_contextMenuItem);
	char permissions[9] = {0};
	bool cached = false;

	// Obviously item needs to have a parent directory...
	if (hasParent)
	{
		const CServerPath& parentPath = path.GetParent();
		CDirectoryListing listing;

		// ... and it needs to be cached
		cached = m_pState->m_pEngine->CacheLookup(parentPath, listing) == FZ_REPLY_OK;
		if (cached)
		{
			for (unsigned int i = 0; i < listing.GetCount(); i++)
			{
				if (listing[i].name != name)
					continue;

				pChmodDlg->ConvertPermissions(*listing[i].permissions, permissions);
			}
		}
	}

	if (!pChmodDlg->Create(this, 0, 1, name, permissions))
	{
		pChmodDlg->Destroy();
		pChmodDlg = 0;
		return;
	}

	if (pChmodDlg->ShowModal() != wxID_OK)
	{
		pChmodDlg->Destroy();
		pChmodDlg = 0;
		return;
	}

	// State may have changed while chmod dialog was shown
	if (!m_contextMenuItem || !m_pState->IsRemoteConnected() || !m_pState->IsRemoteIdle())
	{
		pChmodDlg->Destroy();
		pChmodDlg = 0;
		return;
	}

	const int applyType = pChmodDlg->GetApplyType();

	CRecursiveOperation* pRecursiveOperation = m_pState->GetRecursiveOperationHandler();

	if (cached) // Implies hasParent
	{
		// Change directory permissions
		if (!applyType || applyType == 2)
		{
			wxString newPerms = pChmodDlg->GetPermissions(permissions, true);

			m_pState->m_pCommandQueue->ProcessCommand(new CChmodCommand(path.GetParent(), name, newPerms));
		}

		if (pChmodDlg->Recursive())
			// Start recursion
			pRecursiveOperation->AddDirectoryToVisit(path, _T(""), CLocalPath());
	}
	else
	{
		if (hasParent)
			pRecursiveOperation->AddDirectoryToVisitRestricted(path.GetParent(), name, pChmodDlg->Recursive());
		else
			pRecursiveOperation->AddDirectoryToVisitRestricted(path, _T(""), pChmodDlg->Recursive());
	}

	if (!cached || pChmodDlg->Recursive())
	{
		pRecursiveOperation->SetChmodDialog(pChmodDlg);

		CServerPath currentPath;
		const wxTreeItemId selected = GetSelection();
		if (selected)
			currentPath = GetPathFromItem(selected);
		CFilterManager filter;
		pRecursiveOperation->StartRecursiveOperation(CRecursiveOperation::recursive_chmod, hasParent ? path.GetParent() : path, filter.GetActiveFilters(false), !cached, currentPath);
	}
	else
	{
		pChmodDlg->Destroy();
		const wxTreeItemId selected = GetSelection();
		if (selected)
		{
			CServerPath currentPath = GetPathFromItem(selected);
			m_pState->ChangeRemoteDir(currentPath);
		}
	}
}
void CRemoteTreeView::RefreshItem(wxTreeItemId parent, const CDirectoryListing& listing, bool will_select_parent)
{
	SetItemImages(parent, false);

	wxTreeItemIdValue cookie;
	wxTreeItemId child = GetFirstChild(parent, cookie);
	if (!child || GetItemText(child).empty()) {
		DisplayItem(parent, listing);
		return;
	}

	CFilterManager filter;

	wxString const path = listing.path.GetPath();

	wxArrayString dirs;
	for (unsigned int i = 0; i < listing.GetCount(); ++i) {
		if (!listing[i].is_dir())
			continue;

		if (!filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].time))
			dirs.push_back(listing[i].name);
	}

	auto const& sortFunc = CFileListCtrlSortBase::GetCmpFunction(m_nameSortMode);
	dirs.Sort(sortFunc);

	bool inserted = false;
	child = GetLastChild(parent);
	wxArrayString::reverse_iterator iter = dirs.rbegin();
	while (child && iter != dirs.rend()) {
		int cmp = sortFunc(GetItemText(child), *iter);

		if (!cmp) {
			CServerPath childPath = listing.path;
			childPath.AddSegment(*iter);

			CDirectoryListing subListing;
			if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) {
				if (!GetLastChild(child) && HasSubdirs(subListing, filter))
					AppendItem(child, _T(""), -1, -1);
				SetItemImages(child, false);
			}
			else
				SetItemImages(child, true);

			child = GetPrevSibling(child);
			++iter;
		}
		else if (cmp > 0) {
			// Child no longer exists
			wxTreeItemId sel = GetSelection();
			while (sel && sel != child)
				sel = GetItemParent(sel);
			wxTreeItemId prev = GetPrevSibling(child);
			if (!sel || will_select_parent)
				Delete(child);
			child = prev;
		}
		else if (cmp < 0) {
			// New directory
			CServerPath childPath = listing.path;
			childPath.AddSegment(*iter);

			CDirectoryListing subListing;
			if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) {
				wxTreeItemId childItem = AppendItem(parent, *iter, 0, 2, 0);
				if (childItem) {
					SetItemImages(childItem, false);

					if (HasSubdirs(subListing, filter)) {
						AppendItem(childItem, _T(""), -1, -1);
					}
				}
			}
			else {
				wxTreeItemId childItem = AppendItem(parent, *iter, 1, 3, 0);
				if (childItem) {
					SetItemImages(childItem, true);
				}
			}

			++iter;
			inserted = true;
		}
	}
	while (child) {
		// Child no longer exists
		wxTreeItemId sel = GetSelection();
		while (sel && sel != child)
			sel = GetItemParent(sel);
		wxTreeItemId prev = GetPrevSibling(child);
		if (!sel || will_select_parent)
			Delete(child);
		child = prev;
	}
	while (iter != dirs.rend()) {
		CServerPath childPath = listing.path;
		childPath.AddSegment(*iter);

		CDirectoryListing subListing;
		if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) {
			wxTreeItemId childItem = AppendItem(parent, *iter, 0, 2, 0);
			if (childItem) {
				SetItemImages(childItem, false);

				if (HasSubdirs(subListing, filter)) {
					AppendItem(childItem, _T(""), -1, -1);
				}
			}
		}
		else {
			wxTreeItemId childItem = AppendItem(parent, *iter, 1, 3, 0);
			if (childItem) {
				SetItemImages(childItem, true);
			}
		}

		++iter;
		inserted = true;
	}

	if (inserted)
		SortChildren(parent);
}
void CRemoteTreeView::RefreshItem(wxTreeItemId parent, const CDirectoryListing& listing, bool will_select_parent)
{
	SetItemImages(parent, false);

	wxTreeItemIdValue cookie;
	wxTreeItemId child = GetFirstChild(parent, cookie);
	if (!child || GetItemText(child) == _T(""))
	{
		DisplayItem(parent, listing);
		return;
	}

	CFilterManager filter;

	const wxString path = listing.path.GetPath();

	std::list<wxString> dirs;
	for (unsigned int i = 0; i < listing.GetCount(); i++)
	{
		if (!listing[i].is_dir())
			continue;

		if (!filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].has_date() ? &listing[i].time : 0))
			dirs.push_back(listing[i].name);
	}

	dirs.sort(sortfunc);

	bool inserted = false;
	child = GetLastChild(parent);
	std::list<wxString>::reverse_iterator iter = dirs.rbegin();
	while (child && iter != dirs.rend())
	{
		int cmp = GetItemText(child).CmpNoCase(*iter);
		if (!cmp)
			cmp = GetItemText(child).Cmp(*iter);

		if (!cmp)
		{
			CServerPath path = listing.path;
			path.AddSegment(*iter);

			CDirectoryListing subListing;
			if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK)
			{
				if (!GetLastChild(child) && HasSubdirs(subListing, filter))
					AppendItem(child, _T(""), -1, -1);
				SetItemImages(child, false);
			}
			else
				SetItemImages(child, true);

			child = GetPrevSibling(child);
			iter++;
		}
		else if (cmp > 0)
		{
			// Child no longer exists
			wxTreeItemId sel = GetSelection();
			while (sel && sel != child)
				sel = GetItemParent(sel);
			wxTreeItemId prev = GetPrevSibling(child);
			if (!sel || will_select_parent)
				Delete(child);
			child = prev;
		}
		else if (cmp < 0)
		{
			// New directory
			CServerPath path = listing.path;
			path.AddSegment(*iter);

			CDirectoryListing subListing;
			if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK)
			{
				wxTreeItemId child = AppendItem(parent, *iter, 0, 2, 0);
				SetItemImages(child, false);

				if (HasSubdirs(subListing, filter))
					AppendItem(child, _T(""), -1, -1);
			}
			else
			{
				wxTreeItemId child = AppendItem(parent, *iter, 1, 3, 0);
				if (child)
					SetItemImages(child, true);
			}

			iter++;
			inserted = true;
		}
	}
	while (child)
	{
		// Child no longer exists
		wxTreeItemId sel = GetSelection();
		while (sel && sel != child)
			sel = GetItemParent(sel);
		wxTreeItemId prev = GetPrevSibling(child);
		if (!sel || will_select_parent)
			Delete(child);
		child = prev;
	}
	while (iter != dirs.rend())
	{
		CServerPath path = listing.path;
		path.AddSegment(*iter);

		CDirectoryListing subListing;
		if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK)
		{
			wxTreeItemId child = AppendItem(parent, *iter, 0, 2, 0);
			SetItemImages(child, false);

			if (HasSubdirs(subListing, filter))
				AppendItem(child, _T(""), -1, -1);
		}
		else
		{
			wxTreeItemId child = AppendItem(parent, *iter, 1, 3, 0);
			SetItemImages(child, true);
		}

		iter++;
		inserted = true;
	}

	if (inserted)
		SortChildren(parent);
}