void CState::UploadDroppedFiles(const wxFileDataObject* pFileDataObject, const CServerPath& path, bool queueOnly)
{
	if (!m_pServer)
		return;

	const wxArrayString& files = pFileDataObject->GetFilenames();

	for (unsigned int i = 0; i < files.Count(); i++)
	{
		int64_t size;
		bool is_link;
		CLocalFileSystem::local_fileType type = CLocalFileSystem::GetFileInfo(files[i], is_link, &size, 0, 0);
		if (type == CLocalFileSystem::file)
		{
			wxString localFile;
			const CLocalPath localPath(files[i], &localFile);
			m_pMainFrame->GetQueue()->QueueFile(queueOnly, false, localFile, wxEmptyString, localPath, path, *m_pServer, size);
			m_pMainFrame->GetQueue()->QueueFile_Finish(!queueOnly);
		}
		else if (type == CLocalFileSystem::dir)
		{
			CLocalPath localPath(files[i]);
			if (localPath.HasParent())
			{
				CServerPath target = path;
				target.AddSegment(localPath.GetLastSegment());
				m_pMainFrame->GetQueue()->QueueFolder(queueOnly, false, localPath, target, *m_pServer);
			}
		}
	}
}
예제 #2
0
CServerPath CRemoteTreeView::GetPathFromItem(const wxTreeItemId& item) const
{
	std::list<wxString> segments;

	wxTreeItemId i = item;
	while (i != GetRootItem())
	{
		const CItemData* const pData = (const CItemData*)GetItemData(i);
		if (pData)
		{
			CServerPath path = pData->m_path;
			for (std::list<wxString>::const_iterator iter = segments.begin(); iter != segments.end(); ++iter)
			{
				if (!path.AddSegment(*iter))
					return CServerPath();
			}
			return path;
		}

		segments.push_front(GetItemText(i));
		i = GetItemParent(i);
	}

	return CServerPath();
}
예제 #3
0
void CPathCache::InvalidatePath(tServerCache & serverCache, CServerPath const& path, wxString const& subdir)
{
	CSourcePath sourcePath;

	sourcePath.source = path;
	sourcePath.subdir = subdir;

	CServerPath target;
	tServerCacheIterator serverIter = serverCache.find(sourcePath);
	if (serverIter != serverCache.end()) {
		target = serverIter->second;
		serverCache.erase(serverIter);
	}

	if (target.empty() && !subdir.empty()) {
		target = path;
		if (!target.AddSegment(subdir))
			return;
	}

	if (!target.empty()) {
		// Unfortunately O(n), don't know of a faster way.
		for (auto serverIter = serverCache.begin(); serverIter != serverCache.end(); ) {
			if (serverIter->second == target || target.IsParentOf(serverIter->second, false))
				serverCache.erase(serverIter++);
			else if (serverIter->first.source == target || target.IsParentOf(serverIter->first.source, false))
				serverCache.erase(serverIter++);
			else
				++serverIter;
		}
	}
}
예제 #4
0
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);
}
예제 #5
0
파일: state.cpp 프로젝트: idgaf/FileZilla3
void CState::UploadDroppedFiles(const wxFileDataObject* pFileDataObject, const CServerPath& path, bool queueOnly)
{
	if (!m_pServer)
		return;

	const wxArrayString& files = pFileDataObject->GetFilenames();
	
	for (unsigned int i = 0; i < files.Count(); i++)
	{
		if (wxFile::Exists(files[i]))
		{
			const wxFileName name(files[i]);
			const wxLongLong size = name.GetSize().GetValue();
			m_pMainFrame->GetQueue()->QueueFile(queueOnly, false, files[i], name.GetFullName(), path, *m_pServer, size);
		}
		else if (wxDir::Exists(files[i]))
		{
			wxString name = files[i];
			int pos = name.Find(wxFileName::GetPathSeparator(), true);
			if (pos != -1)
			{
				name = name.Mid(pos + 1);
				CServerPath target = path;
				target.AddSegment(name);
				m_pMainFrame->GetQueue()->QueueFolder(queueOnly, false, files[i], target, *m_pServer);
			}
		}
	}
}
예제 #6
0
void CRemoteTreeView::OnMkdir(wxCommandEvent& event)
{
	if (!m_pState->IsRemoteIdle())
		return;

	if (!m_contextMenuItem)
		return;

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

	CInputDialog dlg;
	if (!dlg.Create(this, _("Create directory"), _("Please enter the name of the directory which should be created:")))
		return;

	CServerPath newPath = path;

	// Append a long segment which does (most likely) not exist in the path and
	// replace it with "New directory" later. This way we get the exact position of
	// "New directory" and can preselect it in the dialog.
	wxString tmpName = _T("25CF809E56B343b5A12D1F0466E3B37A49A9087FDCF8412AA9AF8D1E849D01CF");
	if (newPath.AddSegment(tmpName))
	{
		wxString pathName = newPath.GetPath();
		int pos = pathName.Find(tmpName);
		wxASSERT(pos != -1);
		wxString newName = _("New directory");
		pathName.Replace(tmpName, newName);
		dlg.SetValue(pathName);
		dlg.SelectText(pos, pos + newName.Length());
	}

	if (dlg.ShowModal() != wxID_OK)
		return;

	newPath = path;
	if (!newPath.ChangePath(dlg.GetValue()))
	{
		wxBell();
		return;
	}

	m_pState->m_pCommandQueue->ProcessCommand(new CMkdirCommand(newPath));
	CServerPath listed;
	if (newPath.HasParent())
	{
		listed = newPath.GetParent();
		m_pState->ChangeRemoteDir(listed);
	}

	CServerPath currentPath;
	const wxTreeItemId selected = GetSelection();
	if (selected)
		currentPath = GetPathFromItem(selected);
	if (!currentPath.IsEmpty() && currentPath != listed)
		m_pState->ChangeRemoteDir(currentPath);
}
void CState::UploadDroppedFiles(const wxFileDataObject* pFileDataObject, const wxString& subdir, bool queueOnly)
{
	if (!m_pServer || !m_pDirectoryListing)
		return;

	CServerPath path = m_pDirectoryListing->path;
	if (subdir == _T("..") && path.HasParent())
		path = path.GetParent();
	else if (!subdir.empty())
		path.AddSegment(subdir);

	UploadDroppedFiles(pFileDataObject, path, queueOnly);
}
예제 #8
0
void CPathCache::InvalidatePath(const CServer& server, const CServerPath& path, const wxString& subdir /*=_T("")*/)
{
	tCacheIterator iter = m_cache.find(server);
	if (iter == m_cache.end())
		return;

	CSourcePath sourcePath;

	sourcePath.source = path;
	sourcePath.subdir = subdir;

	CServerPath target;
	tServerCacheIterator serverIter = iter->second->find(sourcePath);
	if (serverIter != iter->second->end())
	{
		target = serverIter->second;
		iter->second->erase(serverIter);
	}

	if (target.IsEmpty() && subdir != _T(""))
	{
		target = path;
		if (!target.AddSegment(subdir))
			return;
	}

	if (!target.IsEmpty())
	{
		// Unfortunately O(n), don't know of a faster way.
		for (std::map<CSourcePath, CServerPath>::iterator serverIter = iter->second->begin(); serverIter != iter->second->end();)
		{
			if (serverIter->second == target || target.IsParentOf(serverIter->second, false))
				iter->second->erase(serverIter++);
			else if (serverIter->first.source == target || target.IsParentOf(serverIter->first.source, false))
				iter->second->erase(serverIter++);
			else
				++serverIter;
		}
	}
}
예제 #9
0
	virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
	{
		if (def == wxDragError ||
			def == wxDragNone ||
			def == wxDragCancel)
			return def;

		wxTreeItemId hit = GetHit(wxPoint(x, y));
		if (!hit)
			return wxDragNone;

		CServerPath path = m_pRemoteTreeView->GetPathFromItem(hit);
		if (path.empty())
			return wxDragNone;

		if (!GetData())
			return wxDragError;

		CDragDropManager* pDragDropManager = CDragDropManager::Get();
		if (pDragDropManager)
			pDragDropManager->pDropTarget = m_pRemoteTreeView;

		if (m_pDataObject->GetReceivedFormat() == m_pFileDataObject->GetFormat())
			m_pRemoteTreeView->m_pState->UploadDroppedFiles(m_pFileDataObject, path, false);
		else
		{
			if (m_pRemoteDataObject->GetProcessId() != (int)wxGetProcessId())
			{
				wxMessageBoxEx(_("Drag&drop between different instances of FileZilla has not been implemented yet."));
				return wxDragNone;
			}

			if (!m_pRemoteTreeView->m_pState->GetServer() || !m_pRemoteDataObject->GetServer().EqualsNoPass(*m_pRemoteTreeView->m_pState->GetServer()))
			{
				wxMessageBoxEx(_("Drag&drop between different servers has not been implemented yet."));
				return wxDragNone;
			}

			// Make sure path path is valid
			if (path == m_pRemoteDataObject->GetServerPath())
			{
				wxMessageBoxEx(_("Source and path of the drop operation are identical"));
				return wxDragNone;
			}

			const std::list<CRemoteDataObject::t_fileInfo>& files = m_pRemoteDataObject->GetFiles();
			for (std::list<CRemoteDataObject::t_fileInfo>::const_iterator iter = files.begin(); iter != files.end(); ++iter)
			{
				const CRemoteDataObject::t_fileInfo& info = *iter;
				if (info.dir)
				{
					CServerPath dir = m_pRemoteDataObject->GetServerPath();
					dir.AddSegment(info.name);
					if (dir == path)
						return wxDragNone;
					else if (dir.IsParentOf(path, false))
					{
						wxMessageBoxEx(_("A directory cannot be dragged into one of its subdirectories."));
						return wxDragNone;
					}
				}
			}

			for (std::list<CRemoteDataObject::t_fileInfo>::const_iterator iter = files.begin(); iter != files.end(); ++iter)
			{
				const CRemoteDataObject::t_fileInfo& info = *iter;
				m_pRemoteTreeView->m_pState->m_pCommandQueue->ProcessCommand(
					new CRenameCommand(m_pRemoteDataObject->GetServerPath(), info.name, path, info.name)
					);
			}

			return wxDragNone;
		}

		return def;
	}
예제 #10
0
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);
}
예제 #11
0
wxTreeItemId CRemoteTreeView::MakeParent(CServerPath path, bool select)
{
	std::vector<wxString> pieces;
	pieces.reserve(path.SegmentCount() + 1);
	while (path.HasParent()) {
		pieces.push_back(path.GetLastSegment());
		path = path.GetParent();
	}
	wxASSERT(!path.GetPath().empty());
	pieces.push_back(path.GetPath());

	const wxTreeItemId root = GetRootItem();
	wxTreeItemId parent = root;

	for (std::vector<wxString>::const_reverse_iterator iter = pieces.rbegin(); iter != pieces.rend(); ++iter) {
		if (iter != pieces.rbegin())
			path.AddSegment(*iter);

		wxTreeItemIdValue cookie;
		wxTreeItemId child = GetFirstChild(parent, cookie);
		if (child && GetItemText(child).empty()) {
			Delete(child);
			child = wxTreeItemId();
			if (parent != root)
				ListExpand(parent);
		}
		for (child = GetFirstChild(parent, cookie); child; child = GetNextSibling(child)) {
			const wxString& text = GetItemText(child);
			if (text == *iter)
				break;
		}
		if (!child) {
			CDirectoryListing listing;

			if (m_pState->m_pEngine->CacheLookup(path, listing) == FZ_REPLY_OK) {
				child = AppendItem(parent, *iter, 0, 2, path.HasParent() ? 0 : new CItemData(path));
				SetItemImages(child, false);
			}
			else {
				child = AppendItem(parent, *iter, 1, 3, path.HasParent() ? 0 : new CItemData(path));
				SetItemImages(child, true);
			}
			SortChildren(parent);

			auto nextIter = iter;
			++nextIter;
			if (nextIter != pieces.rend())
				DisplayItem(child, listing);
		}
		if (select && iter != pieces.rbegin()) {
#ifndef __WXMSW__
			// Prevent CalculatePositions from being called
			wxGenericTreeItem *anchor = m_anchor;
			m_anchor = 0;
#endif
			Expand(parent);
#ifndef __WXMSW__
			m_anchor = anchor;
#endif
		}

		parent = child;
	}

	return parent;
}
예제 #12
0
void CRemoteTreeView::OnEndLabelEdit(wxTreeEvent& event)
{
	if (event.IsEditCancelled())
	{
		event.Veto();
		return;
	}

	if (!m_pState->IsRemoteIdle())
	{
		event.Veto();
		return;
	}

	CItemData* const pData = (CItemData*)GetItemData(event.GetItem());
	if (pData)
	{
		event.Veto();
		return;
	}

	CServerPath old_path = GetPathFromItem(event.GetItem());
	CServerPath parent = old_path.GetParent();

	const wxString& oldName = GetItemText(event.GetItem());
	const wxString& newName = event.GetLabel();
	if (oldName == newName)
	{
		event.Veto();
		return;
	}

	m_pState->m_pCommandQueue->ProcessCommand(new CRenameCommand(parent, oldName, parent, newName));
	m_pState->ChangeRemoteDir(parent);

	CServerPath currentPath;
	const wxTreeItemId selected = GetSelection();
	if (selected)
		currentPath = GetPathFromItem(selected);
	if (currentPath.empty())
		return;

	if (currentPath == old_path || currentPath.IsSubdirOf(old_path, false))
	{
		// Previously selected path was below renamed one, list the new one

		std::list<wxString> subdirs;
		while (currentPath != old_path)
		{
			if (!currentPath.HasParent())
			{
				// Abort just in case
				return;
			}
			subdirs.push_front(currentPath.GetLastSegment());
			currentPath = currentPath.GetParent();
		}
		currentPath = parent;
		currentPath.AddSegment(newName);
		for (std::list<wxString>::const_iterator iter = subdirs.begin(); iter != subdirs.end(); ++iter)
			currentPath.AddSegment(*iter);
		m_pState->ChangeRemoteDir(currentPath);
	}
	else if (currentPath != parent)
		m_pState->ChangeRemoteDir(currentPath);
}
예제 #13
0
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);
}