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