Beispiel #1
0
void CRemoteTreeView::OnMenuDelete(wxCommandEvent&)
{
	if (!m_pState->IsRemoteIdle())
		return;

	if (!m_contextMenuItem)
		return;

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

	if (wxMessageBoxEx(_("Really delete all selected files and/or directories from the server?"), _("Confirmation needed"), wxICON_QUESTION | wxYES_NO, this) != wxYES)
		return;

	const bool hasParent = path.HasParent();

	CRecursiveOperation* pRecursiveOperation = m_pState->GetRecursiveOperationHandler();

	CServerPath startDir;
	if (hasParent)
	{
		const wxString& name = GetItemText(m_contextMenuItem);
		startDir = path.GetParent();
		pRecursiveOperation->AddDirectoryToVisit(startDir, name);
	}
	else
	{
		startDir = path;
		pRecursiveOperation->AddDirectoryToVisit(startDir, _T(""));
	}

	CServerPath currentPath;
	const wxTreeItemId selected = GetSelection();
	if (selected)
		currentPath = GetPathFromItem(selected);
	if (!currentPath.empty() && (path == currentPath || path.IsParentOf(currentPath, false)))
		currentPath = startDir;

	CFilterManager filter;
	pRecursiveOperation->StartRecursiveOperation(CRecursiveOperation::recursive_delete, startDir, filter.GetActiveFilters(false), !hasParent, currentPath);
}
Beispiel #2
0
bool CServerPath::operator==(const CServerPath &op) const
{
	if (empty() != op.empty())
		return false;
	else if (m_type != op.m_type)
		return false;
	else if (m_data != op.m_data)
		return false;

	return true;
}
Beispiel #3
0
bool CRemoteTreeView::ListExpand(wxTreeItemId item)
{
	const CServerPath path = GetPathFromItem(item);
	wxASSERT(!path.empty());
	if (path.empty())
		return false;

	CDirectoryListing listing;
	if (m_pState->m_pEngine->CacheLookup(path, listing) == FZ_REPLY_OK)
		RefreshItem(item, listing, false);
	else
	{
		SetItemImages(item, true);

		wxTreeItemId child = GetLastChild(item);
		if (!child || GetItemText(child).empty())
			return false;
	}

	return true;
}
int CHttpControlSocket::FileTransfer(const wxString localFile, const CServerPath &remotePath,
							  const wxString &remoteFile, bool download,
							  const CFileTransferCommand::t_transferSettings& transferSettings)
{
	LogMessage(Debug_Verbose, _T("CHttpControlSocket::FileTransfer()"));

	LogMessage(Status, _("Downloading %s"), remotePath.FormatFilename(remoteFile).c_str());

	if (!download)
	{
		ResetOperation(FZ_REPLY_CRITICALERROR | FZ_REPLY_NOTSUPPORTED);
		return FZ_REPLY_ERROR;
	}

	if (m_pCurOpData)
	{
		LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("deleting nonzero pData"));
		delete m_pCurOpData;
	}

	CHttpFileTransferOpData *pData = new CHttpFileTransferOpData(download, localFile, remoteFile, remotePath);
	m_pCurOpData = pData;
	m_pHttpOpData = pData;

	if (localFile != _T(""))
	{
		pData->opState = filetransfer_waitfileexists;
		int res = CheckOverwriteFile();
		if (res != FZ_REPLY_OK)
			return res;

		pData->opState = filetransfer_transfer;

		pData->pFile = new wxFile();

		CreateLocalDir(pData->localFile);

		if (!pData->pFile->Open(pData->localFile, wxFile::write))
		{
			LogMessage(::Error, _("Failed to open \"%s\" for writing"), pData->localFile.c_str());
			ResetOperation(FZ_REPLY_ERROR);
			return FZ_REPLY_ERROR;
		}
	}
	else
		pData->opState = filetransfer_transfer;

	int res = InternalConnect(m_pCurrentServer->GetHost(), m_pCurrentServer->GetPort(), m_pCurrentServer->GetProtocol() == HTTPS);
	if (res != FZ_REPLY_OK)
		return res;

	return FileTransferSend();
}
Beispiel #5
0
void CRemoteViewHeader::OnSelectionChanged(wxCommandEvent& event)
{
	const wxString& dir = event.GetString();
	if (dir == _T(""))
		return;

	CServerPath path = m_path;
	if (!path.SetPath(dir))
	{
		wxBell();
		return;
	}

	if (!m_pState->m_pCommandQueue->Idle())
	{
		wxBell();
		return;
	}

	m_pState->ChangeRemoteDir(path);
}
Beispiel #6
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;
		}
	}
}
Beispiel #7
0
void CPathCache::Store(CServer const& server, CServerPath const& target, CServerPath const& source, wxString const& subdir)
{
	scoped_lock lock(mutex_);

	wxASSERT(!target.empty() && !source.empty());

	tCacheIterator iter = m_cache.find(server);
	if (iter == m_cache.cend())
#if HAVE_MAP_EMPLACE
		iter = m_cache.emplace(std::make_pair(server, tServerCache())).first;
#else
		iter = m_cache.insert(std::make_pair(server, tServerCache())).first;
#endif
	tServerCache &serverCache = iter->second;

	CSourcePath sourcePath;

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

	serverCache[sourcePath] = target;
}
Beispiel #8
0
void CQueueStorage::Impl::ReadRemotePaths()
{
	if (!selectRemotePathQuery_)
		return;

	int res;
	do
	{
		res = sqlite3_step(selectRemotePathQuery_);
		if (res == SQLITE_ROW)
		{
			int64_t id = GetColumnInt64(selectRemotePathQuery_, path_table_column_names::id);
			wxString remotePathRaw = GetColumnText(selectRemotePathQuery_, path_table_column_names::path);
			CServerPath remotePath;
			if (id > 0 && !remotePathRaw.empty() && remotePath.SetSafePath(remotePathRaw))
				reverseRemotePaths_[id] = remotePath;
		}
	}
	while (res == SQLITE_BUSY || res == SQLITE_ROW);

	sqlite3_reset(selectRemotePathQuery_);
}
Beispiel #9
0
void CPathCache::Store(const CServer& server, const CServerPath& target, const CServerPath& source, const wxString subdir/*=_T("")*/)
{
	wxASSERT(!target.IsEmpty() && !source.IsEmpty());

	tServerCache *pServerCache;
	tCacheIterator iter = m_cache.find(server);
	if (iter != m_cache.end())
		pServerCache = iter->second;
	else
	{
		pServerCache = new tServerCache;
		m_cache[server] = pServerCache;
	}
	tServerCache &serverCache = *pServerCache;

	CSourcePath sourcePath;

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

	serverCache[sourcePath] = target;
}
Beispiel #10
0
bool CServerPath::IsSubdirOf(const CServerPath &path, bool cmpNoCase) const
{
	if (empty() || path.empty())
		return false;

	if (m_type != path.m_type)
		return false;

	if (!HasParent())
		return false;

	if (traits[m_type].prefixmode != 1) {
		if (cmpNoCase ) {
			if( m_data->m_prefix && !path.m_data->m_prefix ) {
				return false;
			}
			else if( !m_data->m_prefix && path.m_data->m_prefix ) {
				return false;
			}
			else if( m_data->m_prefix && path.m_data->m_prefix && m_data->m_prefix->CmpNoCase(*path.m_data->m_prefix) ) {
				return false;
			}
		}
		if (!cmpNoCase && m_data->m_prefix != path.m_data->m_prefix)
			return false;
	}

	// On MVS, dirs like 'FOO.BAR' without trailing dot cannot have
	// subdirectories
	if (traits[m_type].prefixmode == 1 && !path.m_data->m_prefix)
		return false;

	tConstSegmentIter iter1 = m_data->m_segments.begin();
	tConstSegmentIter iter2 = path.m_data->m_segments.begin();
	while (iter1 != m_data->m_segments.end()) {
		if (iter2 == path.m_data->m_segments.end())
			return true;
		if (cmpNoCase) {
			if (iter1->CmpNoCase(*iter2))
				return false;
		}
		else if (*iter1 != *iter2)
			return false;

		++iter1;
		++iter2;
	}

	return false;
}
Beispiel #11
0
int CFileZillaApi::MakeDir(const CServerPath &path)
{
	//Check if call allowed
	if (!m_bInitialized)
		return FZ_REPLY_NOTINITIALIZED;
	if (IsConnected()==FZ_REPLY_NOTCONNECTED)
		return FZ_REPLY_NOTCONNECTED;
	if (IsBusy()==FZ_REPLY_BUSY)
		return FZ_REPLY_BUSY;
	if (path.IsEmpty() || !path.HasParent())
		return FZ_REPLY_INVALIDPARAM;

	t_command command;
	command.id=FZ_COMMAND_MAKEDIR;
	command.path=path;
	m_pMainThread->Command(command);
	if (m_hOwnerWnd)
		return FZ_REPLY_WOULDBLOCK;
	else
		return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
	
	return FZ_REPLY_ERROR;
}
Beispiel #12
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].has_date() ? &listing[i].time : 0))
			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);
}
Beispiel #13
0
bool CServerPath::operator<(const CServerPath &op) const
{
	if (empty()) {
		if (!op.empty())
			return false;
	}
	else if (op.empty())
		return true;

	if( m_data->m_prefix || op.m_data->m_prefix ) {
		if( m_data->m_prefix < op.m_data->m_prefix ) {
			return true;
		}
		else if( op.m_data->m_prefix < m_data->m_prefix ) {
			return false;
		}
	}

	if (m_type > op.m_type)
		return false;
	else if (m_type < op.m_type)
		return true;

	tConstSegmentIter iter1, iter2;
	for (iter1 = m_data->m_segments.begin(), iter2 = op.m_data->m_segments.begin(); iter1 != m_data->m_segments.end(); ++iter1, ++iter2) {
		if (iter2 == op.m_data->m_segments.end())
			return false;

		const int cmp = iter1->Cmp(*iter2);
		if (cmp < 0)
			return true;
		if (cmp > 0)
			return false;
	}

	return iter2 != op.m_data->m_segments.end();
}
Beispiel #14
0
bool CSearchDialog::Load()
{
	if (!wxDialogEx::Load(m_parent, _T("ID_SEARCH")))
		return false;

	/* XRCed complains if adding a status bar to a dialog, so do it here instead */
	CFilelistStatusBar* pStatusBar = new CFilelistStatusBar(this);
	pStatusBar->SetEmptyString(_("No search results"));

	GetSizer()->Add(pStatusBar, 0, wxGROW);

	if (!CreateListControl(filter_name | filter_size | filter_path | filter_date))
		return false;

	m_results = new CSearchDialogFileList(this, m_pState, 0);
	ReplaceControl(XRCCTRL(*this, "ID_RESULTS", wxWindow), m_results);

	m_results->SetFilelistStatusBar(pStatusBar);

	const CServerPath path = m_pState->GetRemotePath();
	if (!path.IsEmpty())
		XRCCTRL(*this, "ID_PATH", wxTextCtrl)->ChangeValue(path.GetPath());

	SetCtrlState();

	m_pWindowStateManager = new CWindowStateManager(this);
	m_pWindowStateManager->Restore(OPTION_SEARCH_SIZE, wxSize(750, 500));

	Layout();

	LoadConditions();
	EditFilter(m_search_filter);
	XRCCTRL(*this, "ID_CASE", wxCheckBox)->SetValue(m_search_filter.matchCase);

	return true;
}
Beispiel #15
0
void CRemoteTreeView::OnSelectionChanged(wxTreeEvent& event)
{
	if (event.GetItem() != m_ExpandAfterList)
		m_ExpandAfterList = wxTreeItemId();
	if (m_busy)
		return;

	if (!m_pState->IsRemoteIdle())
	{
		wxBell();
		return;
	}

	wxTreeItemId item = event.GetItem();
	if (!item)
		return;

	const CServerPath path = GetPathFromItem(item);
	wxASSERT(!path.empty());
	if (path.empty())
		return;

	m_pState->ChangeRemoteDir(path);
}
Beispiel #16
0
CFolderScanItem::CFolderScanItem(CServerItem* parent, bool queued, bool download, const wxString& localPath, const CServerPath& remotePath)
{
	m_parent = parent;

	m_download = download;
	m_localPath = localPath;
	m_remotePath = remotePath;
	m_queued = queued;
	m_remove = false;
	m_active = false;
	m_count = 0;
	t_dirPair pair;
	pair.localPath = localPath.c_str();
	pair.remotePath.SetSafePath(remotePath.GetSafePath().c_str());
	m_dirsToCheck.push_back(pair);

	m_defaultFileExistsAction = CFileExistsNotification::unknown;
}
Beispiel #17
0
bool CBookmarksDialog::GetBookmark(const wxString &name, wxString &local_dir, CServerPath &remote_dir, bool &sync)
{
	CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);

	CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
	TiXmlElement* pDocument = file.Load();
	if (!pDocument) {
		wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR);

		return false;
	}

	for (TiXmlElement *pBookmark = pDocument->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark"))
	{
		wxString remote_dir_raw;

		if (name != GetTextElement(pBookmark, "Name"))
			continue;

		local_dir = GetTextElement(pBookmark, "LocalDir");
		remote_dir_raw = GetTextElement(pBookmark, "RemoteDir");
		if (!remote_dir_raw.empty())
		{
			if (!remote_dir.SetSafePath(remote_dir_raw))
				return false;
		}
		if (local_dir.empty() && remote_dir_raw.empty())
			return false;

		if (local_dir.empty() || remote_dir_raw.empty())
			sync = false;
		else
			sync = GetTextElementBool(pBookmark, "SyncBrowsing", false);

		return true;
	}

	return false;
}
Beispiel #18
0
bool CState::Connect(const CServer& server, bool askBreak, const CServerPath& path /*=CServerPath()*/)
{
	if (!m_pEngine)
		return false;
	if (m_pEngine->IsConnected() || m_pEngine->IsBusy() || !m_pCommandQueue->Idle())
	{
		if (askBreak)
			if (wxMessageBox(_("Break current connection?"), _T("FileZilla"), wxYES_NO | wxICON_QUESTION) != wxYES)
				return false;
		m_pCommandQueue->Cancel();
	}

	m_pCommandQueue->ProcessCommand(new CConnectCommand(server));
	m_pCommandQueue->ProcessCommand(new CListCommand(path));
	
	COptions::Get()->SetLastServer(server);
	COptions::Get()->SetOption(OPTION_LASTSERVERPATH, path.GetSafePath());

	m_pMainFrame->SetTitle(server.FormatServer() + _T(" - FileZilla"));

	return true;
}
Beispiel #19
0
int CServerPath::CmpNoCase(const CServerPath &op) const
{
	if (empty() != op.empty())
		return 1;
	else if (m_data->m_prefix != op.m_data->m_prefix)
		return 1;
	else if (m_type != op.m_type)
		return 1;

	if (m_data->m_segments.size() > op.m_data->m_segments.size())
		return 1;
	else if (m_data->m_segments.size() < op.m_data->m_segments.size())
		return -1;

	tConstSegmentIter iter = m_data->m_segments.begin();
	tConstSegmentIter iter2 = op.m_data->m_segments.begin();
	while (iter != m_data->m_segments.end()) {
		int res = iter++->CmpNoCase(*iter2++);
		if (res)
			return res;
	}

	return 0;
}
void CRemoteRecursiveOperation::StartRecursiveOperation(OperationMode mode, ActiveFilters const& filters, CServerPath const& finalDir, bool immediate)
{
	wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none"));
	wxCHECK_RET(m_state.IsRemoteConnected(), _T("StartRecursiveOperation while disconnected"));
	wxCHECK_RET(!finalDir.empty(), _T("Empty final dir in recursive operation"));

	if (mode == recursive_chmod && !m_pChmodDlg) {
		return;
	}

	if ((mode == recursive_transfer || mode == recursive_transfer_flatten) && !m_pQueue) {
		return;
	}

	if (recursion_roots_.empty()) {
		// Nothing to do in this case
		return;
	}

	m_processedFiles = 0;
	m_processedDirectories = 0;

	m_immediate = immediate;
	m_operationMode = mode;

	if ((mode == CRecursiveOperation::recursive_transfer || mode == CRecursiveOperation::recursive_transfer_flatten) && immediate) {
		m_actionAfterBlocker = m_pQueue->GetActionAfterBlocker();
	}

	m_state.NotifyHandlers(STATECHANGE_REMOTE_IDLE);
	m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS);

	m_filters = filters;

	NextOperation();
}
Beispiel #21
0
int64_t CQueueStorage::Impl::SaveRemotePath(const CServerPath& path)
{
	wxString const& safePath = path.GetSafePath();
	std::unordered_map<wxString, int64_t, wxStringHash>::const_iterator it = remotePaths_.find(safePath);
	if (it != remotePaths_.end())
		return it->second;

	Bind(insertRemotePathQuery_, path_table_column_names::path, safePath);

	int res;
	do {
		res = sqlite3_step(insertRemotePathQuery_);
	} while (res == SQLITE_BUSY);

	sqlite3_reset(insertRemotePathQuery_);

	if (res == SQLITE_DONE) {
		int64_t id = sqlite3_last_insert_rowid(db_);
		remotePaths_[safePath] = id;
		return id;
	}

	return -1;
}
Beispiel #22
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;
		}
	}
}
Beispiel #23
0
CSiteManagerItemData_Site* CSiteManager::GetSiteByPath(wxString sitePath)
{
	wxChar c = sitePath[0];
	if (c != '0' && c != '1')
	{
		wxMessageBox(_("Site path has to begin with 0 or 1."), _("Invalid site path"));
		return 0;
	}

	sitePath = sitePath.Mid(1);

	// We have to synchronize access to sitemanager.xml so that multiple processed don't write
	// to the same file or one is reading while the other one writes.
	CInterProcessMutex mutex(MUTEX_SITEMANAGER);

	CXmlFile file;
	TiXmlElement* pDocument = 0;

	if (c == '0')
		pDocument = file.Load(_T("sitemanager"));
	else
	{
		const wxString& defaultsDir = wxGetApp().GetDefaultsDir();
		if (defaultsDir == _T(""))
		{
			wxMessageBox(_("Site does not exist."), _("Invalid site path"));
			return 0;
		}
		wxFileName name(defaultsDir, _T("fzdefaults.xml"));
		pDocument = file.Load(name);
	}

	if (!pDocument)
	{
		wxMessageBox(file.GetError(), _("Error loading xml file"), wxICON_ERROR);

		return 0;
	}

	TiXmlElement* pElement = pDocument->FirstChildElement("Servers");
	if (!pElement)
	{
		wxMessageBox(_("Site does not exist."), _("Invalid site path"));
		return 0;
	}

	std::list<wxString> segments;
	if (!UnescapeSitePath(sitePath, segments) || segments.empty())
	{
		wxMessageBox(_("Site path is malformed."), _("Invalid site path"));
		return 0;
	}

	TiXmlElement* pChild = GetElementByPath(pElement, segments);
	if (!pChild)
	{
		wxMessageBox(_("Site does not exist."), _("Invalid site path"));
		return 0;
	}

	TiXmlElement* pBookmark;
	if (!strcmp(pChild->Value(), "Bookmark"))
	{
		pBookmark = pChild;
		pChild = pChild->Parent()->ToElement();
		segments.pop_back();
	}
	else
		pBookmark = 0;

	CSiteManagerItemData_Site* data = ReadServerElement(pChild);

	if (!data)
	{
		wxMessageBox(_("Could not read server item."), _("Invalid site path"));
		return 0;
	}

	if (pBookmark)
	{
		TiXmlHandle handle(pBookmark);

		wxString localPath;
		CServerPath remotePath;
		TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text();
		if (localDir)
			localPath = ConvLocal(localDir->Value());
		TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text();
		if (remoteDir)
			remotePath.SetSafePath(ConvLocal(remoteDir->Value()));
		if (!localPath.empty() && !remotePath.IsEmpty())
		{
			data->m_sync = GetTextElementBool(pBookmark, "SyncBrowsing", false);
		}
		else
			data->m_sync = false;

		data->m_localDir = localPath;
		data->m_remoteDir = remotePath;
	}

	data->m_path = BuildPath( c, segments );

	return data;
}
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const
{
	if (*this == path) {
		return *this;
	}

	if (empty() || path.empty()) {
		return CServerPath();
	}

	if (m_type != path.m_type ||
		(!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix))
	{
		return CServerPath();
	}

	if (!HasParent()) {
		if (path.IsSubdirOf(*this, false)) {
			return *this;
		}
		else {
			return CServerPath();
		}
	}
	else if (!path.HasParent()) {
		if (IsSubdirOf(path, false)) {
			return path;
		}
		else {
			return CServerPath();
		}
	}

	CServerPath parent;
	parent.m_type = m_type;

	CServerPathData& parentData = parent.m_data.get();

	tConstSegmentIter last = m_data->m_segments.end();
	tConstSegmentIter last2 = path.m_data->m_segments.end();
	if (traits[m_type].prefixmode == 1) {
		if (!m_data->m_prefix) {
			--last;
		}
		if (!path.m_data->m_prefix) {
			--last2;
		}
		parentData.m_prefix = GetParent().m_data->m_prefix;
	}
	else
		parentData.m_prefix = m_data->m_prefix;

	tConstSegmentIter iter = m_data->m_segments.begin();
	tConstSegmentIter iter2 = path.m_data->m_segments.begin();
	while (iter != last && iter2 != last2) {
		if (*iter != *iter2) {
			if (!traits[m_type].has_root && parentData.m_segments.empty()) {
				return CServerPath();
			}
			else {
				return parent;
			}
		}

		parentData.m_segments.push_back(*iter);

		++iter;
		++iter2;
	}

	return parent;
}
bool CServerPath::IsParentOf(const CServerPath &path, bool cmpNoCase) const
{
	return path.IsSubdirOf(*this, cmpNoCase);
}
recursion_root::recursion_root(CServerPath const& start_dir, bool allow_parent)
	: m_remoteStartDir(start_dir)
	, m_allowParent(allow_parent)
{
	wxASSERT_MSG(!start_dir.empty(), _T("Empty startDir in recursion_root constructor"));
}
Beispiel #27
0
void CRemoteTreeView::OnBeginDrag(wxTreeEvent& event)
{
	// Drag could result in recursive operation, don't allow at this point
	if (!m_pState->IsRemoteIdle()) {
		wxBell();
		return;
	}

	const wxTreeItemId& item = event.GetItem();
	if (!item)
		return;

	CServerPath path = GetPathFromItem(item);
	if (path.empty() || !path.HasParent())
		return;

	const CServerPath& parent = path.GetParent();
	const wxString& lastSegment = path.GetLastSegment();
	if (lastSegment.empty())
		return;

	wxDataObjectComposite object;

	CServer const* pServer = m_pState->GetServer();
	if (!pServer)
		return;
	CServer const server = *pServer;


	CRemoteDataObject *pRemoteDataObject = new CRemoteDataObject(*pServer, parent);
	pRemoteDataObject->AddFile(lastSegment, true, -1, false);

	pRemoteDataObject->Finalize();

	object.Add(pRemoteDataObject, true);

#if FZ3_USESHELLEXT
	std::unique_ptr<CShellExtensionInterface> ext = CShellExtensionInterface::CreateInitialized();
	if (ext) {
		const wxString& file = ext->GetDragDirectory();

		wxASSERT(!file.empty());

		wxFileDataObject *pFileDataObject = new wxFileDataObject;
		pFileDataObject->AddFile(file);

		object.Add(pFileDataObject);
	}
#endif

	CDragDropManager* pDragDropManager = CDragDropManager::Init();
	pDragDropManager->pDragSource = this;
	pDragDropManager->server = *pServer;
	pDragDropManager->remoteParent = parent;

	wxDropSource source(this);
	source.SetData(object);

	int res = source.DoDragDrop();

	pDragDropManager->Release();

	if (res != wxDragCopy) {
		return;
	}

#if FZ3_USESHELLEXT
	if (ext) {
		if (!pRemoteDataObject->DidSendData()) {
			pServer = m_pState->GetServer();
			if (!pServer || !m_pState->IsRemoteIdle() || *pServer != server) {
				wxBell();
				return;
			}

			CLocalPath target(ext->GetTarget());
			if (target.empty()) {
				ext.reset(); // Release extension before the modal message box
				wxMessageBoxEx(_("Could not determine the target of the Drag&Drop operation.\nEither the shell extension is not installed properly or you didn't drop the files into an Explorer window."));
				return;
			}

			m_pState->DownloadDroppedFiles(pRemoteDataObject, target);
		}
	}
#endif
}
Beispiel #28
0
bool CSiteManager::GetBookmarks(wxString sitePath, std::list<wxString> &bookmarks)
{
	wxChar c = sitePath[0];
	if (c != '0' && c != '1')
		return false;

	sitePath = sitePath.Mid(1);

	// We have to synchronize access to sitemanager.xml so that multiple processed don't write
	// to the same file or one is reading while the other one writes.
	CInterProcessMutex mutex(MUTEX_SITEMANAGER);

	CXmlFile file;
	TiXmlElement* pDocument = 0;

	if (c == '0')
		pDocument = file.Load(_T("sitemanager"));
	else
	{
		const wxString& defaultsDir = wxGetApp().GetDefaultsDir();
		if (defaultsDir == _T(""))
			return false;
		pDocument = file.Load(wxFileName(defaultsDir, _T("fzdefaults.xml")));
	}

	if (!pDocument)
	{
		wxMessageBox(file.GetError(), _("Error loading xml file"), wxICON_ERROR);

		return false;
	}

	TiXmlElement* pElement = pDocument->FirstChildElement("Servers");
	if (!pElement)
		return false;

	std::list<wxString> segments;
	if (!UnescapeSitePath(sitePath, segments))
	{
		wxMessageBox(_("Site path is malformed."), _("Invalid site path"));
		return 0;
	}

	TiXmlElement* pChild = GetElementByPath(pElement, segments);

	if (pChild && !strcmp(pChild->Value(), "Bookmark"))
		pChild = pChild->Parent()->ToElement();

	if (!pChild || strcmp(pChild->Value(), "Server"))
		return 0;

	// Bookmarks
	for (TiXmlElement* pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark"))
	{
		TiXmlHandle handle(pBookmark);

		wxString name = GetTextElement_Trimmed(pBookmark, "Name");
		if (name.empty())
			continue;

		wxString localPath;
		CServerPath remotePath;
		TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text();
		if (localDir)
			localPath = ConvLocal(localDir->Value());
		TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text();
		if (remoteDir)
			remotePath.SetSafePath(ConvLocal(remoteDir->Value()));

		if (localPath.empty() && remotePath.IsEmpty())
			continue;

		bookmarks.push_back(name);
	}

	return true;
}
Beispiel #29
0
bool CSiteManager::AddBookmark(wxString sitePath, const wxString& name, const wxString &local_dir, const CServerPath &remote_dir, bool sync)
{
	if (local_dir.empty() && remote_dir.IsEmpty())
		return false;

	if (sitePath[0] != '0')
		return false;

	sitePath = sitePath.Mid(1);

	// We have to synchronize access to sitemanager.xml so that multiple processed don't write
	// to the same file or one is reading while the other one writes.
	CInterProcessMutex mutex(MUTEX_SITEMANAGER);

	CXmlFile file;
	TiXmlElement* pDocument = file.Load(_T("sitemanager"));

	if (!pDocument)
	{
		wxString msg = file.GetError() + _T("\n") + _("The bookmark could not be added.");
		wxMessageBox(msg, _("Error loading xml file"), wxICON_ERROR);

		return false;
	}

	TiXmlElement* pElement = pDocument->FirstChildElement("Servers");
	if (!pElement)
		return false;

	std::list<wxString> segments;
	if (!UnescapeSitePath(sitePath, segments))
	{
		wxMessageBox(_("Site path is malformed."), _("Invalid site path"));
		return 0;
	}

	TiXmlElement* pChild = GetElementByPath(pElement, segments);
	if (!pChild || strcmp(pChild->Value(), "Server"))
	{
		wxMessageBox(_("Site does not exist."), _("Invalid site path"));
		return 0;
	}

	// Bookmarks
	TiXmlElement *pInsertBefore = 0;
	TiXmlElement* pBookmark;
	for (pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark"))
	{
		TiXmlHandle handle(pBookmark);

		wxString old_name = GetTextElement_Trimmed(pBookmark, "Name");
		if (old_name.empty())
			continue;

		if (name == old_name)
		{
			wxMessageBox(_("Name of bookmark already exists."), _("New bookmark"), wxICON_EXCLAMATION);
			return false;
		}
		if (name < old_name && !pInsertBefore)
			pInsertBefore = pBookmark;
	}

	if (pInsertBefore)
		pBookmark = pChild->InsertBeforeChild(pInsertBefore, TiXmlElement("Bookmark"))->ToElement();
	else
		pBookmark = pChild->LinkEndChild(new TiXmlElement("Bookmark"))->ToElement();
	AddTextElement(pBookmark, "Name", name);
	if (!local_dir.empty())
		AddTextElement(pBookmark, "LocalDir", local_dir);
	if (!remote_dir.IsEmpty())
		AddTextElement(pBookmark, "RemoteDir", remote_dir.GetSafePath());
	if (sync)
		AddTextElementRaw(pBookmark, "SyncBrowsing", "1");

	wxString error;
	if (!file.Save(&error))
	{
		if (COptions::Get()->GetOptionVal(OPTION_DEFAULT_KIOSKMODE) == 2)
			return true;

		wxString msg = wxString::Format(_("Could not write \"%s\", the selected sites could not be exported: %s"), file.GetFileName().GetFullPath().c_str(), error.c_str());
		wxMessageBox(msg, _("Error writing xml file"), wxICON_ERROR);
	}

	return true;
}
Beispiel #30
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;
	}