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); } } } }
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(); }
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; } } }
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); }
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); } } } }
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); }
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; } } }
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; }
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); }
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; }
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); }
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); }